Wednesday, June 29, 2011

Recommended Android Market screenshot format

In the Android Developer Console you can upload the screenshots of your app (max 8 currently) in several sizes, like 320x480, 480x800, 480x854 and 1280x800.

But it turns out that sometimes (always?) if you upload in the higher resolutions (like 480x800), the images get cropped in a weird way in the market on your phone (at least the Nexus One). The images will look fine in the online Android market, but not on a physical device. Actually, when you look closely, the dev-console gives a thumbnail of the screenshots and there you can already see that the images are cropped strangely sometimes; like the left 20-50 pixels just cut off. And that's actually how they also appear in the market on devices!
After some experimenting, it turns out this does not happen when you upload in 320x480 format.
Thus the recommended resolution to upload screenshots seems to be 320x480! Doesn't matter if you use a device (like the Galaxy S2) or emulator to take the screenshots.

Note I didnt check if the browser market image quality decreased when going from 480x800 to 320x480. Though clicking on an image in the webmarket shows the 320x480 uploaded image quite fine.

Android Bluetooth bugs on Galaxy S2

Just a quick post regarding Bluetooth on the Samsung Galaxy S II.

Recently I've been creating an app that uses Bluetooth for sending data between devices (not FTP just strings). A pretty good introduction can be found here, though some things are missing from it. Like an example how you can register a BroadcastReceiver for the ACTION_SCAN_MODE_CHANGE. Just in case you are looking for it, here it is:



// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy

...

// Creates a BroadcastReceiver for ACTION_SCAN_MODE_CHANGED for BT discovery
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {
if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,
BluetoothAdapter.ERROR);
String strMode = "";
switch(mode){
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
strMode = "mode changed: SCAN_MODE_CONNECTABLE_DISCOVERABLE";
break;
case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
break;
case BluetoothAdapter.SCAN_MODE_NONE:
strMode = "mode changed: SCAN_MODE_NONE";
break;
default:
strMode = "mode changed: unknown mode " + mode;
break;
}
Log.d(TAG, strMode);

}


Basically a device can be made discoverable by others, or a device can be set to find other devices (discover). Being discoverable is configurable up to 300 seconds max, finding other devices is not configurable and about 12 seconds.

Making a device discoverable entails the following code:


Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
startActivityForResult(discoverableIntent, REQUEST_MAKE_BT_DISCOVERABLE);


That should enable Bluetooth if it isn't already and make the device discoverable for 120 seconds, and the result of the intent comes in at onActivityResult(). For receiving Bluetooth state changes you can register a BroadcastReceiver. This all works fine on a Nexus One.
But not on all devices, their Bluetooth stack contains bugs and behaves differently:

Samsung Galaxy S II
  • When you make the device discoverable, its state should become SCAN_MODE_CONNECTABLE_DISCOVERABLE, i.e value 23, meaning this device is both discoverable and connectable from remote Bluetooth devices.
    On the Nexus One I see the device.getScanMode() always return 23, as it should be. But on the Galaxy S2 it sometimes just changes to scanmode SCAN_MODE_CONNECTABLE (21), making it not discoverable anymore! And indeed, other devices don't see it anymore when discovering. In the S2 phone's settings I also see in that case that the discoverable checkbox is not checked.
    Workaround: the only workaround that always works seems to be to always first turn on the Bluetooth, and after that send the above discoverableIntent. Thus first do a


    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableIntent, REQUEST_ENABLE_BT);


    then the


    Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
    startActivityForResult(discoverableIntent, REQUEST_MAKE_BT_DISCOVERABLE);



  • When you start the discoverable intent with any number different from 120, say 300, the popup that asks for user confirmation always shows 120, instead of the different number, say 300. The discoverability actually stays on for the specified amount (300 seconds), so functionally it works (phew), but the display is just incorrect and you can't change it. Confusing for the user.



Other bugs
I also found a few other more generic bugs reported by others and found by myself. Maybe they were SDK or device related (my app runs on Android 2.0+, tested on N1, Wildfire and Galaxy S2):