Wednesday, December 21, 2011

'Tis the season for sharing (via your Android code)

Come Facebook, come Twitter, come Tumblr and Flickr!

No app is an island, we often want to be able to share the cool things we create with our apps with the world, whether it's the latest social network to on-sell our personal details, or just plain old email to your gran.

.. And here's how.

Lets say we have an image file located here:
String fileLocation = "/mnt/sdcard/SomeMediaFiles/aMediaFile10.jpg"

We can share this easily by passing the reference to our file location into the below method:
    public void shareFile(String newFilePath) {
      {Intent share = new Intent(Intent.ACTION_SEND);
//declare the MIME type of the file. .. What you pass into share.setType determines what apps appears in your Sharing list.

      Uri imageUri = Uri.fromFile(new File(newImagePath));
      share.putExtra(Intent.EXTRA_STREAM, imageUri);
      startActivity(Intent.createChooser(share, "Share"));
And this is basically what is the result (actual apps listed will depend on what is installed on your users device):

... Easy.

Saturday, December 10, 2011

OutOfMemory errors when populating a Gallery

I've just spent the last couple of hours wrestling with OutOfMemory errors when populating a Gallery widget with photos, and as fun as it's been, I think I've sorted it out and thought I'd share my solution with you.

For starters, the reason we're getting OutOfMemory errors in the first place is that the heap size on Android devices is limited to something like 16 MB on a G1 and 24 MB on a Nexus one.

As soon as you start to work with media files you quickly start to learn that you need to work to manage your memory usage with Android as a result of this limitation.

I would also like to thank direct to device debugging, I couldn't have done this without utilizing it, I would go as far as saying that it is essential in situations like this.

Here is the full code of one of my imageAdapters,  I'm using this to provide the images to my Gallery widget like this:

galleryTop.setAdapter(new ImageAdapterTop(this));

The Adapter class :

public class ImageAdapterTop extends BaseAdapter {
   int mGalleryItemBackground;
   private Context mContext;

    File[] allTopSlices = Utils.getAllTopSlices();  
    String[] fullPathAllTopSlices = new String[allTopSlices.length];
    Uri[] uriAllTopSlices = new Uri[fullPathAllTopSlices.length];

   public ImageAdapterTop(Context c) {
       mContext = c;
       TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery);
       mGalleryItemBackground = a.getResourceId(
               R.styleable.HelloGallery_android_galleryItemBackground, 0);

   public int getCount() {
       return uriAllTopSlices.length;

   public Object getItem(int position) {
       return position;

   public long getItemId(int position) {
       return position;

   public View getView(int position, View convertView, ViewGroup parent) {
    int screenHeightPx = Utils.GetScreenHeight(getWindowManager().getDefaultDisplay());
    for(int i = 0; i < allTopSlices.length; i++){
    fullPathAllTopSlices[i] = allTopSlices[i].getAbsolutePath();
    for(int j=0; j < fullPathAllTopSlices.length; j++){
    uriAllTopSlices[j] = Uri.parse(fullPathAllTopSlices[j]);
       ImageView i = new ImageView(mContext);

       i.setLayoutParams(new Gallery.LayoutParams(400, (screenHeightPx-50) /3));

       return i;

and the referenced recycleDrawable :

private void recycleDrawable(ImageView i) {
BitmapDrawable currentBitmapDrawable = (BitmapDrawable)i.getDrawable();

if(currentBitmapDrawable != null){

and readBitmap methods:

public static Bitmap readBitmap(String selectedImage) {
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;

try {
bm = BitmapFactory.decodeFile(selectedImage, options);
catch (OutOfMemoryError e) {

return bm;

Probably worth mentioning that the 'options.inSampleSize' reference, which is downsizing the image is pretty much essential when working with large files with the memory constraints associated with current Android devices.

Hope that helps someone out there.