
Introduction
When I first heard about Google Plus and their Instant Upload feature, my initial thought was “how does this work?”. I did a quick search on Google to see if there were any other people who were curious about how they do it. I found only one useful result, this stack overflow post (stack overflow has been invaluable this summer), and it got me thinking about how cool it would be to try to do the same thing. The words ContentProvider and ContentObserver was gibberish to me but I dedicated one night to see if I can figure this thing out. Turned out, it was actually quite easy and not that hard to understand.
This is probably not the exact way that Google+ used to implement Instant Uploads, but it provides the same functionality, with a bonus that Google+ does not have – that it’ll work with any camera app, not just the native camera app. My hope is that this tutorial will help others that may be curious about how to do something similar.
Content Providers are the only way to share data across different applications. They can store and read data, and Android has a bunch of content providers already provided for you for common data types, such as video, audio, images and contacts.
Content Observers are just that. It’s an abstract class that has a method that gets called when it observes a change in a content provider.
Hopefully you figured out now that what we simply have to do is register a content observer to the images content provider.
InstantUploadActivity
Let’s create a simple and useless Android project that will detect when a picture is taken and display the most recent picture’s file name in a TextView. The content provider that we want to observe is the one that Android provides for images, and the URI for that is MediaStore.Images.Media.EXTERNAL_CONTENT_URI
.
We start with the onCreate
method in the Activity:
public class InstantuploadActivity extends Activity { private PhotosObserver instUploadObserver = new PhotosObserver(); private String saved; private TextView tv; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv = (TextView)findViewById(R.id.textview); this.getApplicationContext() .getContentResolver() .registerContentObserver( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, instUploadObserver); Log.d("INSTANT", "registered content observer"); }
Upon creation of this Activity, we register our custom PhotosObserver (which extends ContentObserver) to the images content provider.
Recall that the goal for this project is to simply take the most recent picture’s file name and display it in our Activity’s TextView, tv
. To get alerted when a new picture is taken, we have to create a class that extends ContentObserver and implement the onChange
method:
private class PhotosObserver extends ContentObserver { public PhotosObserver() { super(null); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Media media = readFromMediaStore(getApplicationContext(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI); saved = "I detected " + media.file.getName(); Log.d("INSTANT", "detected picture"); } } private Media readFromMediaStore(Context context, Uri uri) { Cursor cursor = context.getContentResolver().query(uri, null, null, null, "date_added DESC"); Media media = null; if (cursor.moveToNext()) { int dataColumn = cursor.getColumnIndexOrThrow(MediaColumns.DATA); String filePath = cursor.getString(dataColumn); int mimeTypeColumn = cursor .getColumnIndexOrThrow(MediaColumns.MIME_TYPE); String mimeType = cursor.getString(mimeTypeColumn); media = new Media(new File(filePath), mimeType); } cursor.close(); return media; } private class Media { private File file; @SuppressWarnings("unused") private String type; public Media(File file, String type) { this.file = file; this.type = type; } public String getType() { return type; } public File getFile() { return file; } }
In the onChange
method we call readFromMediaStore
, which will retrieve data about the most recent picture (the one that was just taken). readFromMediaStore
initializes a Cursor on the same Images URI that we’ve been observing. We then grab the filepath and the filetype from the first result (note: the cursor was sorted by “date_added DESC”) and create a new Media
to return. Keep in mind that this can be done when our Activity is not running in the foreground. You can launch InstantUploadActivity, press “Home” to back out, then go to Camera and take a picture – and the onChange
method will still get called.
From here, we simply set the String variable saved
to display the filename such that when you go back to the Activity, the filename of the picture you have just taken is displayed in the TextView via the onResume
method:
@Override public void onResume() { super.onResume(); if (saved != null) { tv.setText(saved); } }
Lastly, don’t forget to unregister the content observer if onDestroy
is called:
@Override public void onDestroy() { super.onDestroy(); this.getApplicationContext().getContentResolver() .unregisterContentObserver(instUploadObserver); Log.d("INSTANT", "unregistered content observer"); }
You can do much better than just setting text on a TextView. You can take that image and resize it, and then upload it somewhere, or you can automatically apply an image filter on each picture or do both! There are many cool things you can do with this.
Check out the full source code on github here.
Conclusion
This was my second hackathon project at Facebook, and I was able to implement this functionality into the Android Facebook app successfully such that whenever you took a picture from any camera app, it would get uploaded to your Mobile Uploads album. Instead of storing the filepath of the most recent picture like in the example above, I grabbed the URI of the picture that was just taken and sent it to an upload service in the Facebook app that took care of uploading the picture to your album. I also built some preferences so that you can enable or disable it depending on if you’re connected to wifi, roaming, or charging your phone.
Unfortunately, my hackathon project is not going to be implemented but it was a fun learning experience. It is also hard to describe the utter excitement when seeing this work for the first time at 5am, having a picture taken from your camera and onto Facebook in a matter of seconds. Stay tuned for another tutorial on another hackathon project!
EDIT: And here it is: How to NFC on Android
Tags: android, facebook, google, google plus, hackathon, instant upload, internship, stack overflow
dude awesome post, will try this later.
Comment by Dmitry Kislyuk — August 18, 2011 @ 5:29 PM
whoa whoa whoa curiousity satisfied
Comment by Nelson Hoang — August 20, 2011 @ 1:09 AM
Nice article. The hackathon you did for Facebook is exactly the idea that led me to your post. I found another app doing this via a Service, since the broadcast action for android.intent.action.CAMERA_BUTTON isn’t always implemented by device manufacturers (so say some people).
Thanks for the info!
Comment by Todd — November 28, 2011 @ 7:44 PM
Very nice post.
Can you post, QR/BAR code reader app? It would be great help for many people looking for it.Because nobody is explaining about QR/BAR code reader the way you post.
Thanks in advance.
Comment by Geet — March 29, 2012 @ 2:43 AM
Why not just use a CursorLoader instead? Either way, queries to the MediaStore should be performed on a separate worker thread.
Comment by Alex Lockwood — August 20, 2012 @ 5:01 PM
hello,
how can we upload an image on google plus application through android
please give me methods or sample code
thank you
regards
nitin gupta
Comment by nitin gupta — August 24, 2012 @ 2:55 AM
how can we upload an image on google plus through android code
please give me sample code ..
thanks
regards
nitin gupta
Comment by nitin gupta — August 24, 2012 @ 2:58 AM
[…] Thanks to Femi’s answer in this post, I was able to take what he said and figure out how to emulate Google+’s Instant Upload feature. I wrote a tutorial about it here:http://www.jessechen.net/blog/how-does-google-plus-instant-upload-work/………………………………… […]
Pingback by Android — How does Google+ instant upload work? | Android Development tutorial | Android Development tutorial — September 1, 2012 @ 8:43 PM
Everyone loves it when people come together and share views.
Great blog, continue the good work!
Comment by refencement google — December 25, 2012 @ 7:27 AM
If some one wishes expert view regarding blogging and site-building then i suggest him/her to pay
a visit this webpage, Keep up the pleasant job.
Comment by cold cal — February 17, 2013 @ 1:09 PM
I read this paragraph fully about the comparison of most recent and earlier technologies, it’s amazing article.
Comment by www.gamezebo.com — April 13, 2014 @ 10:47 PM
awesome post
Comment by مركز Ø±ÙØ¹ صور — May 31, 2017 @ 5:40 AM