Pages

Sunday, December 12, 2010

ChristmasOnes - send best wishes to your loved ones - on Android market

Dear friends!

ChristmasOnes is available for download on Android Market.
Dress up a Christmas Tree with beautiful toys, decorations and lights, attach your wishes and send to your loved ones.

ChristmasOnes app is a Christmas wallpaper editor and catchy e-greetings. Use it to make virtual postcard with Christmas tree or setup authentic holiday wallpaper. It's completely FREE with EXTRA features:
- Auto mode
- Dozens of templates
- One-click export to social networks
- Falling snow effect

Merry Christmas and Happy New Year!



Thursday, November 4, 2010

Marketing insights from Intexsoft

Huge, enormously growing market of Android applications and games is a challenge for Intexsoft marketing specialists. How do they manage to find a way through debris of competitors to their customers mobile hearts?

Please follow us on applications blogs:
my7wonderslite.blogspot.com
semchudesbelarusi.blogspot.com
hallomonster.blogspot.com
christmasones.blogspot.com

"My Seven Wonders" project

Project dedicated to analisys of issues arised during development of Android application "My Seven Wonders" in Intexsoft company
Source code of the examples referenced in this post is available at http://code.google.com/p/intexsoft/

http://intexsoft.googlecode.com/files/IntexsoftExamples.apk



Article 1. Give me more memory, please (avoiding OutOfMemory errors)

Article 2. Where in the world is… (working with maps)

Article 3. Say “cheese”, please (working with camera)

Article 4. Where am I? (working with GPS)

Where am I? (working with GPS)

Source code of the examples referenced in this post is available at http://code.google.com/p/intexsoft/

In “My Seven Wonders” application it was important to know where we are located now in order to correctly calculate bearings of compass targets. Android API makes the interaction with geographical location services an easy task. In this article we will introduce the usage of that API along with some hints we discovered during development.
Android device features two possibilities to obtain current location: from GPS (more accurate) or from Network (less accurate).



The availability of these possibilities is controlled by a user in the Locations menu of a device:



Our example application will:
* retrieve our current location latitude and longitude using GPS or Network Location provider, depending on the current settings
* automatically switch from GPS to Network location provider, if GPS signal is not available.
* display the readable name of the current location using asynchronous call to Geocoder.
* notify the user, if required Location Providers are disabled and automatically display Locations menu so the user be able to enable one.

Firstly in our application activity we will get the android.location.LocationManager service, which will provide us with all the required geographical data.
Now we will check, which of the providers are enabled. This is accomplished using isProviderEnabled method of LocationManager. We try with LocationManager.GPS_PROVIDER and if it is not enabled we try with LocationManager.NETWORK_PROVIDER. If both are disabled, we will display a Locations menu by constructing a new Intent with android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS as a parameter.



As soon as we found an enabled provider we will subscribe to receive updates from it using requestLocationUpdates from LocationManager. The updates will be handled by our custom implementation of android.location.LocationListener which we pass to requestLocationUpdates as a parameter.

Finally we will display received latitude and longitude in onLocationChanged method of our LocationListener.



Currently our application is able get the coordinates from GPS or Network (it depends on which of them are enabled). This is cool. But assume now, user has both providers enabled, but he is located indoors where GPS signal is not available. In that case our application will continuously wait for data from GPS, which actually is impossible to retrieve.

So it would be nice to make our application be smart enough to switch from GPS to Network automatically, when GPS signal is not available. The problem is that GPS signal availability could not be retrieved from Android API, so our aim is to find a workaround for this.

The simple way is to set a predefined delay after which, when no data is received from GPS, we give up. But this may be very inaccurate since the delay, after which the data may be received, may vary depending on different factors, like the time of the day or weather conditions. Sometimes the data could be returned in 2 seconds, but sometimes in 25.

The good thing is Android API can tell us the number of satellites discovered by the GPS receiver of our Android device. The idea is to track the value of available satellites and based on this information predict can we receive GPS data, or we should give up.

Unfortunately there is no predefined value of available satellites after which the coordinates could be potentially received. Depending on the circumstances we can receive coordinates with 3 satellites available, but can receive nothing with 5.

Though the value of available satellites can’t tell us much, the way this value changes over time may become quite handy. If the number of available satellites is increasing, that means we are on the way to signal receiving.



We will introduce a number of wait intervals and a number of satellites, which anyway should become available in these intervals. For example, if during first 5 seconds we will not get at least one satellite available, that surely means, we will not be able to receive the signal later. The same way we can experimentally find other intervals and SATs values (like 3 SATs at 10 seconds, 5 SATs at 18 etc.).

Based on this information we can make an appropriate check by registering our custom GpsStatus.Listener and handle the GpsStatus.GPS_EVENT_SATELLITE_STATUS event. If the minimal required number of satellites will not be available at the predefined time interval we will immediately switch to Network provider.



If GPS signal is not available, but Network provider is disabled we will display Locations menu:



Our application displays the latitude and longitude of the current location in numerical form. To make it more user friendly, we will use these numerical values to get the geographical name of the location associated with these coordinates. To achieve that an android.location.Geocoder.Geocoder class will be used. The data returned by Geocoder will be retrieved from Internet, so there could be some visible delay during that procedure. To avoid our application to stop responding during data retrieval we will call the Geocoder from the android.os.AsyncTask. As a result our application will be able to respond to other actions, while the data is being retrieved asynchronously.



Finally we have a nice application, which automatically chooses available location provider whether we are indoors or outdoors, and displays our current location.

Tuesday, October 12, 2010

Say “cheese”, please (working with camera)

Source code of the examples referenced in this post is available at http://code.google.com/p/intexsoft/

Working with camera on Android could be easy and straightforward – we may start a new activity with MediaStore.ACTION_IMAGE_CAPTURE intent and just wait for the result to be returned. But sometimes there may be a need to go inside that process: for example in our “My Seven Wonders” application we had a necessity to create a custom camera preview screen. Here we will share some details learned during development of that custom screen.



To start with a camera activity we used a sample available in the Android SDK. Since we planned to handle the orientation of the phone we firstly set our camera activity screen orientation to be “landscape” in AndroidManifest.xml. The landscape orientation will be our starting point of further image rotation operations.

To know the exact orientation of the phone we added OrientationEventListener. This listener is notified on all 360 range of values, but since we are interested only in discrete values (0,90,180,270) we made a ImageCaptureCallback.getRotationAngle() method, which filters the values sent to the listener. For each of the four orientations we created 4 separate images of binocular view, which are pre-rotated appropriately. In the camera_view.xml, which describes our camera activity layout, we added the camera surface itself (where the camera preview will be shown) and an image view (where a binocular image will be displayed). When the orientation of the phone is changed we just change the source of the ImageView to the appropriate binocular image.

Our custom capture button is also added in the camera_view.xml, which, when clicked, invokes the CameraActivity.takePicture() method. The snapshot storing procedure is performed in ImageCaptureCallback class.

Taking a snapshot and processing a picture should be performed with care, because currently available Android phones feature high resolution cameras, which produce high resolution images. When processing these images we may easily get an OutOfMemory error. To avoid this problem we will set medium camera parameters in the CameraActivity.surfaceChanged method.

First we will configure the camera picture size (this is the size in which we will receive the taken snapshot in ImageCaptureCallback.onPictureTaken method). We will get all picture sizes supported by camera, and find the one with width nearest to 480 (which is optimal width for medium resolution Android resources).

Also we will configure the camera preview size (this is the size in which the actual output from camera will be shown on camera surface). We will get all the supported preview formats from the camera and will try to find the one, which width is nearest to the width dedicated to our camera surface activity.

Now in the ImageCaptureCallback.onPictureTaken we can finally rotate the received snapshot according to our current orientation and overlay appropriate binocular image over the snapshot using Android Canvas API.

After we made all of the above there was one annoying bug left. Sometimes, when testing on a real device, after clicking on a capture button the activity was freezing and after that the hardware camera was not responding. The only thing to work around this was to restart the phone. We were not able to debug this problem because it was a rare case and it was not understandable under which circumstances this bug arises.

In resolving of the above problem the Monkey utility have helped us a lot. By the way this is a great tool which may economy debugging time spent on investigating the “miracle” bugs (http://developer.android.com/guide/developing/tools/monkey.html). When we ran the Monkey to do a stress test of our application, each time the Monkey visited the Camera Activity the hardware camera was crashing! It was really cool because it became very easy to understand what the problem was. The Monkey makes random clicks on the screen and it does this very fast. And this was the actual problem. Multiple simultaneous calls to the camera.takePicture method made the hardware camera to fail. This was a rare case during manual testing, but with a Monkey this problem became clearly visible. What we just needed to do is to disable the snapshot button right after it was clicked once.

Finally we have a nice little application which draws customized camera preview screen, obeys the phone orientation and produces cool snapshots. Happy filming!