I am creating an app with a service, and I would like other apps to be able to interact with and extend it. I can think of two scenarios:
another app wants to interact with the service
someone develops a better version of the service that they would
like my app to use instead of my built-in service
Most of the things that I have read about actions say that you should name your action something like com.mycompany.appname.CUSTOM_ACTION. However, I do not think I should put the actions in my own namespace since other developers might want their apps to be able to receive them. Instead, I think they should give them a more public name, like intent.action.CUSTOM_ACTION.
Is there a convention for naming public actions? Is it ok that I name my actions like intent.action.CUSTOM_ACTION, or is that a no-no?
It's bad idea to give it generic names. It comes with your app and therefore you should stick to com.mycompany.appname.CUSTOM_ACTION namespace
openintents.org is a website that appears to allow developers to register intents that they want other applications to use.
Related
Everyone knows Tasker.
The optimal way to use Tasker would be to create a Plugin. But then you can't use other automation Apps like Llama (except you also build a plugin for them of course).
I saw a clever workaround for this. since nearly all automatisation Apps are able to start Intends, some Apps like the one for Franco.Kernel or ElementalX have classes which can be startet from such Apps to do Stuff. For ElementalX it looks like this: flar2.elementalxkernel.powersaver.DISABLE_POWERSAVE.
I like this idea and want to implement this to!
but I have some questions...
Are these just normal classes like every other Activity and Class in my Project?
How do I get my Context in those Classes?
Can those classes access all other functions and SharedPrefs in my App?
Is it possible to hand over parameters like Ints or Strings?
What else do I need to keep in mind?
The example you gave is an intent from the application ElementalX Kernel (now replaced by EX Kernel Manager)
The intent is made public by adding android:exported=“true” to the app's manifest. This means other apps like Tasker can use it.
Within the ElementalX Kernel app, there is a broadcast receiver that listens for this intent. When the intent is used, it triggers further actions. In your example, when the intent flar2.elementalxkernel.powersaver.DISABLE_POWERSAVE is broadcast, the app will receive the broadcast and call the methods that disable powersave mode.
I'm developing a custom home screen launcher. As part of its functionality I would like to be able to show unread notification badges.
Instead of implementing my own API for this, I would like to hook onto existing standards. The most widely used is the one for Samsung's TouchWiz launcher.
It works through a ContentProvider with the authority com.sec.badge. Now, on Samsung devices, I can easily use a ContentObserver to observe changes to Samsung's ContentProvider and it works perfectly. However, on devices without an existing ContentProvider (i.e. non-Samsung devices) I would like to provide my own ContentProvider for this purpose. This also works perfectly to capture inserts from other apps.
However, when I roll my own ContentProvider I naturally get an INSTALL_FAILED_CONFLICTING_PROVIDER error when trying to install on Samsung devices.
I fully understand why this is happening since Android wants to avoid having conflicts in the providers.
What I would want help with is a workaround. Is it possible to somehow register my ContentProvider dynamically instead of declaring it in AndroidManifest.xml? That way, I could first check if the authority is already taken, and if so go with an Observer. Otherwise, register my own ContentProvider and go with that.
I realize that this might be bad practice but I don't really see any other way. Some apps (such as Facebook) also implement Sony's badge API that works through Broadcasts which avoids conflict, but not nearly as many existing apps use this process.
I've tried this:
ContentProvider test = new SamsungContentProviderSpoof();
ProviderInfo providerInfo = new ProviderInfo();
providerInfo.authority = "com.sec.badge";
providerInfo.enabled = true;
providerInfo.exported = true;
test.attachInfo(this, providerInfo);
but that obviously fails. I guess I need to somehow access some system ContentResolver and register myself there, but I don't know how.
I would like to hook onto existing standards
There are no existing standards. A few vendors have done their own thing, and that's it.
The most widely used is the one for Samsung's TouchWiz launcher.
Note that this mechanism is undocumented (AFAICT) and unsupported (outside of select Samsung partners).
Is it possible to somehow register my ContentProvider dynamically instead of declaring it in AndroidManifest.xml? That way, I could first check if the authority is already taken, and if so go with an Observer. Otherwise, register my own ContentProvider and go with that.
You are welcome to say that it is disabled (android:enabled="false") in the manifest, then conditionally enable it later using PackageManager and setComponentEnabledSetting(). You would know that you needed to do this by either trying to communicate with the existing provider (e.g., registering your observer) and getting an expected error, or by interrogating PackageManager to see if the provider exists.
However, not only will you need to claim that you are Samsung in terms of the provider, but also in terms of the custom permissions. That will break on the "L" Developer Preview, and probably going forward, for much the same reason that you ran into with the conflicting provider. At the present time, there is no workaround for this that I am aware of.
Android's intent documentation states that :
action must be in a namespace because Intents are used globally in the system
Does this namespace concept just imply that if I don't use, for e.g., my app's package name as a prefix for a custom action name, then it may conflict with the action name for a different app, so when some app is using intent, it may start the wrong component because of my name conflict. Is there any more detail that needs to be worried about when it comes to namespace in intents ?
Does this namespace concept just imply that if I don't use, for e.g., my app's package name as a prefix for a custom action name, then it may conflict with the action name for a different app, so when some app is using intent, it may start the wrong component because of my name conflict.
More or less.
Is there any more detail that needs to be worried about when it comes to namespace in intents ?
It is unlikely that creating a custom action is the right solution for whatever problem that you are solve. One use case for it is if you are going to try to convince third-party developers to specifically invoke one of your activities, perhaps as part of an SDK that you are creating for such developers. This is well within reason, just unlikely. Another use case would be if you have a suite of apps that you were trying to inter-link at specific spots. This is somewhat more probable, but it becomes a bit of a problem to do well -- by default, any app in the system will be able to start that activity if they so chose, and securing that can get tricky.
Note that you neither want nor need an action string of any sort for activities that are private to your app. That's because you neither want nor need an <intent-filter> for activities that are private to your app. Just use explicit Intents to invoke such activities.
I know that public (named) intents that are registered with the system and can be called from any application and private (anonymous) intents that are used within a single
application. please can anyone give me an example for better understanding.
Thanks in advance
Sorry no time to write a full answer, but you can create custom permissions in order to sign your Intents & BroadcastReceivers.
When you use these custom permissions, only apps that have been signed with the same signing key, and include that custom permission, can see these Intents.
This question might help you:
How to use custom permissions in Android?
#Commonsware explains the issue really well in a recent blog post:
Don't have an Accidental API - The CommonsBlog
The Android documentation does probably the best job of explaining it, here is a relevant snippet:
There are two primary forms of intents you will use.
Explicit Intents have specified a component (via
setComponent(ComponentName) or setClass(Context, Class)), which
provides the exact class to be run. Often these will not include any
other information, simply being a way for an application to launch
various internal activities it has as the user interacts with the
application.
Implicit Intents have not specified a component; instead,
they must include enough information for the system to determine which
of the available components is best to run for that intent. When using
implicit intents, given such an arbitrary intent we need to know what
to do with it.
This is handled by the process of Intent resolution,
which maps an Intent to an Activity, BroadcastReceiver, or Service (or
sometimes two or more activities/receivers) that can handle it.
Explicit intents you use in your activity to start internal activities.
While implicit intents are used often used to launch other activities like when you want to share a link or email something, you send out an implicit intent and let the user decide the email client to use to send the email or to share the link.
There are some instances where you might want to use an implicit intent to run an internal component of your app, because it seems to be more stable.
I've built an app called xLancer (https://market.android.com/details?id=kz.jay.xlancer.activity) that retrieves job listings from Elance. Now i want to implement a feature that would remind me to bid on a project at a later time. Instead of reinventing the wheel i want to launch any external TODO/Task manager app. But now i am stuck, i don't know which URI or action should be specified, so far i've only used intents to call my internal activities by specifying class name explicitly.
So the question is: how can i know which URI/action should be specified?
Look here, I didn't see any Todo/Task intents there though....