I have a series of Android apps, and I need to coordinate their execution. On any given device, there can be any one of those apps installed, or any two of them installed, or any three of them, or any four, and so on. All of those apps can do one specific thing, and they all will try to do that thing from time to time. Now here's the problem: at any instant, at most one of those apps should be allowed to do that thing. If any one app is doing that thing, none of the other apps should be doing it; they should either wait for their turn, or simply pass. In other words, I need a global mutex or critical section mechanism on Android. In addition, I want to avoid NDK, if possible. What should I do?
You might have to give a bit more detail to get a more specific answer. But from what I understand it sounds like you could use BroadcastReceiver in each application that listens for an action to get broadcast and takes it as sign that it needs to either wait, or cancel it's action. Then inside each application whenever you are going to start your action you broadcast an intent with the action string something like `com.your.packagename.ACTION_STARTING_THE_THING. All of the other apps that are installed (if any) will receive this intent and can act upon it accordingly.
Related
Note: I haven't coded anything but looking for a structure/keywords or ideas how it can be achieved.
Use Case:
I have an activity which basically shows some display/data/or does some operation etc when opened manually from button click, notification click etc. Now I want to display the same stuff when a particular condition is satisfied [like my geo location matches that I force to be my home or user home].
1. without user clicking any notification,
2. without opening the activity,
3. without clicking buttons, and
4. without opening the app.
So in short, I want my app to be launched when I am home or reach a geo fence, is it achievable?
I am aware of Pending Intents, but seems they need the activity to be opened once and register the intent, let me know if this is the only way to go.
Kindly help!
when a particular condition is satisfied
This is not possible in general. For example, Android has nothing built-in with the ability to do something automatically based upon when your neighbor's cousin's daughter posts something on Stack Overflow. Even though that is a particular condition that could be satisfied, Android does not know your neighbor, nor your neighbor's relatives, nor the neighbor's cousin's children, nor the online actions of your neighbor's cousin's daughter.
There are specific things that Android can handle that offer the ability to give you control for related conditions, such as AlarmManager for getting control at certain points in time, or JobScheduler for getting control periodically when the environment is proper (e.g., we have connectivity and are on a charger).
Your question uses a geofence as an example. The Play Services SDK offers geofence APIs that you can use, that can give you control when the user enters a particular region.
I want my app to be launched when I am home or reach a geo fence, is it achievable?
You are welcome to call those geofence APIs, providing a PendingIntent that points to a WakefulBroadcastReceiver, which in turn points to an IntentService, where you can go do something.
If by "my app is launched", you mean bring up one of your activities, while that is technically possible using an activity PendingIntent, you may make your users very unhappy for interrupting what they are doing (e.g., collecting Pokémon). Please consider using a Notification instead.
I am aware of Pending Intents, but seems they need the activity to be opened once and register the intent
Nothing of your app will ever run until the user manually runs your app (e.g., taps on your home screen launcher icon) or until something else uses an explicit Intent to start one of your components. At that point, you can call the geofence APIs, assuming that you somehow know where the user's home is.
Most likely, you need the user to spend time in the activity simply to collect the data from the user about where they want the geofences to be established.
I've got a unique situation where I have to query the phone to determine which app will be handling incoming phone calls. I realize that in 95% of cases com.android.phone is doing this work, however, I can't only be right 95% of the time, I need to know 100% of the time what app it'll be (user could have installed a custom phone app afterall to handle calls).
Being familiar with intents, I figured I could simply ask PackageManager to identify all apps that could handle these actions: Intent.ACTION_ANSWER and or Intent.ACTION_CALL (the only two Intent actions relevant to phone calls), after all, this approach works for virtually all other phone functions I've tried.
Unfortunately, whenever one tries to query PackageManager, say either using .resolveActivity() or .queryIntentActivities(), the result is always 'null', even when default applications exist for these intents. To further compound my frustration, there's absolutely zero documentation on why these intent actions can't be utilized. The documentation reads as if I am doing everything exactly right to reach my objective.
So, the question is two-fold: is there any reasonable method whatsoever to determine the phone app (hopefully the default app) AND why the heck can't intent actions created for this exact purpose be utilized?
TL;DR There's two intent actions that relate to phone calls, except, you can't use these to query PackageManager to find the underlying apps that facilitate these intent actions. Why not?
Background: I have an app which needs to use an intent from an other app. If this other app is not installed when its intent is needed, I would like to offer it for download and install.
Question: If the downloaded app is opened (by the user) immediately after installing it, I would need it to open the specific intent the first app needs instead of opening it as normal. See image below.
What options do I have available, is there a common pattern for this? Thanks in advance.
If the downloaded app is opened (by the user) immediately after installing it, I would need it to open the specific intent the first app needs instead of opening it as normal.
That is not possible, strictly speaking. There is nothing stopping the user from pressing Open, and that will behave as normal -- you cannot change this.
If you are the author of the, um, "Monkey Trampoline" app, you could work out various hacks to recognize that it is being opened after an install from, um, "Animal Olympics", so it can route its logic accordingly (use a custom sticky broadcast, have the second app use some IPC to ask the first app "yo, am I supposed to do something special?", etc.).
It is also conceivable that ACTION_PACKAGE_ADDED will be broadcast before the user clicks either Done or Open (or HOME or BACK or whatever). In that case, you could listen for that broadcast, determine that, indeed, the app just installed does involve simian somersaults, and call startActivity(). This will be a bit jarring for the user, insofar as all of a sudden they'd be transported from the install process into this new app. And, since the precise timing of ACTION_PACKAGE_ADDED is undocumented, your mileage may vary (e.g., the user could still get a chance to tap Open before the broadcast winds its way to your app).
Basically I'm trying to get the "notifications" present in the notification bar somewhere else, or something similar in effect.*
Mind the ": I'm not really interested in catching and possibly messing with the original notification, I just want to know that it is there. There seems to be more questions around this topic, but mostly the quality is "I WANT THIS" with an expected "YOU CAN'T" answer. Maybe you (we) can come up with another option?
Things I have come up with, but that seem problematic are:
1:
Catching all send notification's. I don't think you can extend/override/change the current notificationManager. People seem to think this is not needed for non-evil apps. I disagree. But nevertheless I don't know any method that can accomplish this. Another option would mean to ask the manager for the current 'live' notification, but there is no such method I believe. Also the conclusion of these threads:
Global intents that are fired for all Android notifications
Receive Android NotificationManager Notifications from Non-System Apps
Is it possible for an app to replace the NotificationManager? (google groups)
2: Catching Broadcasts. This seems more doable, although not everything has a broadcast available. Apart from that last point: This would mean I would have to find out what broadcasts are available, and act on each one hard-coded. How feasable would it be to let users add their own broadcasts? And how would they know if (and what) their favorite program sends out? (I mean: add their own the app should listen to, not add a broadcast itself obviously)
This might involve something like an activity that catches everything for a certain period of time, and then you make sure you let your program send a notification, hoping it also sends something like a broadcast? Once a broadcast is identified, you want to act on that, but I don't know if you can change your behavior this dynamically.
3: Something completely different that will let me send as many different types of information (user choosable in the end) to an 'outside' place.
* I'm trying to send all notifications to a secondary location (a watch in this case). I can make something for all sorts of different situations (SMS, phone, mail, twitter etc), but this means double bandwith and cpu (battery), and everytime I (or a user) wants to add another type of message, I need to code more.
But nevertheless I don't know any method that can accomplish this.
Correct, short of modifying firmware.
Another option would mean to ask the manager for the current 'live' notification, but there is no such method I believe
Also correct, short of modifying firmware.
And how would they know if (and what) their favorite program sends out?
They wouldn't.
You are certainly welcome to:
Define your own broadcast Intent structure for a broadcast saying "hey, if anyone out there has some sort of extended notification thingy, here's one!"
Create one or more end-user applications that consume such events (e.g., routing to your watch)
Document and evangelize your Intent structure, convincing developers to take advantage of it, either to broadcast such events or consume such broadcasts
I want my application to start when someone modifies a content provider. A setting to be specific. The settings framework calls "notify" when a value is set.
If my app was started I would use registerContentObserver() I guess, but is is not started.
Can define some intent-filter in my manifest that wakes up my application. A back up plan would be to have a service running all the time that has registered a listener, but that seems like a wast or resources.
Thanks, Ola
This isn't directly supported by the Android device because starting an app every time a ContentProvider's data changes is a path to really killing your battery. To do the query, you'd need to do it in a service, which as you said is understandably undesirable.
Secondly, starting an intent is a user action. Android really doesn't support allowing an application to start all on its own without user request... Doing so would be impolite! What if your user was doing something important and then your app pops up on top? Remember the user is in control, not you. Instead of starting an application, consider placing a Status Bar Notification so the user can deal with it when it's convenient for them.