Best way to monitor for new photos in gallery? - android

I have checked other similar question and answers but not yet satisfied. I have a need where my app need to be notify whenever new photos arrive in the gallery so that it can process that new photo. I know apps like ES file explorer are using service for constantly monitoring the change in files and I am also doing the same.
What I am doing : Using intent service and AlarmManager to check every 30 minutes by querying MediaStore and send broadcast if any new photo is found since last scan.
What is required : Instead of firing intentService every 30 minutes I need to find a way where I can listen to new photos and send broadcast as soon as new photo is detected in device. I am not allowed to overburden device battery and give support all the way back from api level 11.
Can you suggest any way to achieve this ?

Related

Why do we need a UserHandle in many API declarations

In Android Open Source Project, a lot of core API declarations have an integer parameter userId in the end. I traced back and figured out the integer comes from a class called "UserHandle.java". There is a simple comments saying this class represents a user on the device. It still confuses me. Why do we need such a class? What's the difference between different values of the class, such as "USER_OWNER", "USER_CURRENT", "USER_CURRENT_OR_SELF"?
Thanks in advance!!!
Ever since Jelly Bean, Android platform has supported multiple users. This means that multiple users may be able to use one device, yet not be able to access other user's files or communicate with another user's app.
The first user on the device is user 0. The rest start their numbering from 10,11,... (In JB the numbering was 1,2...).
USER_OWNER is user 0.
He has some extra privileges over the other users (mostly access certain settings that others can't or uninstall an app for all users).
Multiple users on one device requires that only one user can be active in a specific point in time, this user is referred to as USER_CURRENT (since Kitkat().
In general one user's application can't send a broadcast message or an Intent to other user's apps.
Only apps with system permissions can do that (for example when the battery is running low, an intent will be sent to all).
Whenever you send an Intent from your app, the system service verifies whether this is a valid Intent i.e. if its supposed to reach all users then it's not.
This means that even if you were to use a certain api with the wrong userId (for example you force userId=0 even though this is user 10), then your call will receive a SecurityException.
To avoid such exceptions, there is also the option to send an Intent with USER_CURRENT_OR_SELF.
This means you're trying to send to the current user, but if he's not allowed to receive the Intent, let the same user who sent the Intent receive it.

Can you manually fire ACTION_BATTERY_LOW?

I'm relatively new to android programming but I'm told most applications have a receiver that will cut down on battery expensive activities when android fires ACTION_BATTERY_LOW.
Android developing page says:
public static final String ACTION_BATTERY_LOW
Added in API level 1
Broadcast Action: Indicates low battery condition on the device. This broadcast corresponds to the "Low battery warning" system dialog.
This is a protected intent that can only be sent by the system.
Constant Value: "android.intent.action.BATTERY_LOW"
I was wondering if there was a way to send this intent manually, at any desired battery level. I have a rooted device if that makes a difference.
No. It's not possible. Check this post. Look into the answer given by Mark(commonsware).
Sure there is a way to change the level - just download the terabytes of complete source code and spend a week or two building your own custom ROM, and trying to flash it without bricking your phone. It will only work on your device.
But no, you cannot change it in an app, nor on anyone else's device, and you cannot fire it yourself - did you read the part you quoted, "This is a protected intent that can only be sent by the system."?

Adding Image To System Content Provider From Camera Intent

At the moment my app has a service running which is fired every hour. This pulls any photos thats have been taken since last time it was open and uploads then to the server. This is done using the system content provider
Now what I want to do is send an intent to open the camera app, I am doing this like so...
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
What I would like to happen is when the focus comes back to my app (after the user has taken a picture), I can open the service and that takes care of the photo.
However it seems like the photo is never added to the content provider. The service opens it and the cursos has a count of 0. Is there anything i can do so the system adds the photo to the content provider or do I need to handle this myself?
Edit
So I figure there no intents I can use to get it to save to the system. So it would seem my options are either
contentResolver.insert()
or
MediaStore.Images.Mediea.insertImage()
What is the difference between these 2 methods?
Edit
So I am starting to think google are clueless with there implementation of this feature. Take this link
http://developer.android.com/guide/topics/media/camera.html#intent-receive
You pass in the Uri and when it returns to your app it gives you the uri you gave it. If you did not specify a uri it doesn't return one. What is the point in that? Why would I want data I already have? Surely it would make sense the other way around. Or even just giving you basic data you need such as name, path, mimetype. Would that be too difficult?
Notify MediaScanner, when the scan is complete your photo will be added to the system database.

Listen to photo taken event

Just want to register to video/photo taken events.
Hopefully, but not a must, the event will be triggered when the operation have finished, so I won't process half photos or half taken videos.
Already tried:
fileObserver = new FileObserver(dcimDir, FileObserver.ALL_EVENTS)
I see the events when traversing using a file manager app but not when a picture is taken nor when copying.
Ideas?
Found a way by registering to all sub directories of dcim (except the ones that start with a period):
new FileObserver(dcimDir.toString(), FileObserver.CLOSE_WRITE)
The reason I need to register to all of them is because different phones put picutes and videos in different folders - at least they are all under DCIM.
The reason the event is 'CLOSE_WRITE' is because I want to trigger after the photo/video is complete, so I won't process only half of the photo/video.
There is another way:
ContentProvider
See another SE thread for more info: Android -- How does Google+ instant upload work?

BroadcastReceiver Priority issue

I am implementing SMSListener in my app and I have set it's possibly highest priority as android:priority="2147483647" so that I should get the call on new incoming sms.
In my second sample app I have set the same priority as above for SMSListener but when I get call for new incoming SMS I am using abortBroadcast();.
When I ran both these app and I found that 1 is getting the call before 2. Now I am seeking this behaviour will remain as it is or it is not constant and 2 can get call before 1.
I want to make sure that my app get's the call whenever sms comes even if there exists some other app which has the highest priority and it is aborting the sms.
I hope I have put my point and looking for some convincing answer.
Thanks for devoting your time to my problem.
The abortBroadcast only works when they get it first, usually based on installation order, but not always.) System level apps will execute, then Android will try to sort out non-system apps. If you look at the source code, the order of execution is based on priority level, but the calls to select the order of apps is not consistent for apps over 999 or for apps with the same priority level. It might be in order of installation, but system changes can result in other orders of execution (which I have seen many times with testing this).
Another thing, from what I understand, the priority for applications must be between -1000 and 1000, inclusive.
http://developer.android.com/reference/android/content/IntentFilter.html#setPriority%28int%29
http://developer.android.com/reference/android/content/IntentFilter.html#SYSTEM_HIGH_PRIORITY

Categories

Resources