Android implement automatisation - android

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.

Related

Delegate text transformation to "plugin" Android apps, not known in advance

Context
Our app shows an HTML flashcard to the user.
We have added several layers of "filters" to satisfy different groups of users:
To satisfy chess enthusiasts, we convert any {FEN:rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2} block to an HTML table representing a chess board with pieces at the right position
To satisfy Chinese language learners, we convert 字 to <ruby>字<rt>zì</rt></ruby>
...
Original HTML → Chess transformation → Chinese transformation → ... → Final HTML to display
Problem
The number of filters is growing, leading to problems:
Slower rendition
Heavier download
Bigger source code to maintain
More bugs/crashes
Maintenance burden
Question
So, we would like to make these separately installable apps.
For instance, a chess+Chinese enthusiast would install 3 apps:
TheApp
TheApp Chess plugin
TheApp Chinese plugin
TheApp would automatically discover what plugins are installed, and call them in turn (order does not matter).
I was thinking of using an intent THEAPPTRANSFORM, but how can I receive the list of apps that have an <intent-filter> for THEAPPTRANSFORM, and call them all in turn?
Speed is a major requirement. I have read that Intents are 10+ times slower than direct calls... would Parcelable help here?
If impossible, is there any other solution?
To know apps which have a broadcast reciever with THEAPPTRANSFORM as filter, you can use below code
PackageManager pm = getPackageManager();
Intent intent = new Intent("THEAPPTRANSFORM");
List<ResolveInfo> info = pm.queryBroadcastReceivers(intent, 0);
for (ResolveInfo resolveInfo : info) {
Log.e("apps", "packages = " + resolveInfo.activityInfo.packageName);
}
You need a dynamically installed plugin which is not part of your application. I think you have a few options for this.
Solution 1: Scripting
Ship a scripting language interpreter with your app. (eg. ruby - http://ruboto.org/). Create an interface for executing these scripts. Make a central database of such scripts, or load them from external storage. Now, you can execute these scripts and get the required result.
Solution 2: AIDL
Use a remote service in the plugin apps. Provide an AIDL for third parties to develop apps with a remote service with that AIDL. Such services should also conform to an intent filter defined by you. Now you can use packagemanager to find such services, select one and connect to it. Now you can call all the AIDL methods. This will be inter process communication using binder, for your application this will be a synchronous call. (see this SO question for details - Access remote service in different application)
Downside to this approach is that all these services need to be running when your app is running, so you have to handle the starting/stopping of these services. It will also affect the power consumption if the services are running in the background.
Solution 3: Broadcast/receiver
Third party installed apps that have a broadcast receiver with an intent filter for custom intent defined by you. Also, your app needs to have a broadcast receiver with a custom intent that the plugins can call with the result. Now, say you want to call a third party plugin for some transformation, you have to do this:
Use packagemanager to find all the third party apps conforming to
your custom intent. Send a broadcast with extradata about
transformation. Handle the transformation in the broadcast receiver of
the plugin app. Once transformation is done, send a broadcast with
result to the original app.
This option is entirely asynchronous, and it may take any amount of time to execute with no guaranties.

Public Intents for Other Applications to Use

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.

creating android service like system service

I want to implement a service which should be running like standard system service on boot up, this service should not be kill-able and should be able to perform action on receiving notification from another process.
Can anyone help me which is the best methodology (AIDL) to create such service,if any example for reference ?
You can't do this unless you are creating your own system ROM.
If creating your own ROM, you can start by modifying the AndroidManifest of the apk containing your service. You need to add an attribute to your manifest node: android:sharedUserId="android.uid.system". That will cause your APK to hold the system ID (which requires the APK to be signed with your platform signing key -- this is why you need to be creating your own system ROM.
That will allow your application to be considered special by the system, and (at least on 4.x, I haven't tested on older Android versions) your application will be auto-started. The application being auto-started doesn't mean much on its own though; either you need to implement a BOOT_COMPLETED receiver as #febinkk suggests, or you can provide a custom Application override (by adding the attribute android:name="your.package.ApplicationSuperClass" to your application node in your AndroidManifest.xml). In your application super class, you can overload onCreate() and have it start your service or whatever else is required.
Additionally, as a system application, I believe (though have not fully tested) you will not be able to be killed through normal means.
You are not able to create non-killable, immune service without creating your own ROM
You could register a BroadcastReciever with filter for android.intent.action.BOOT_COMPLETED for your service and after starting call startForeground(). This may not be what exactly you were looking, but this is probably the only thing that comes near, if you don't want to create ROM.

android - is it possible to use private intents instead of global ones?

background:
i've noticed that for regular activities within, it is possible for any application to open the activities of my app .
question:
is it possible to allow only my own app (or apps , or package) to send and receive intents inside the same scope , so that other application won't be able to receive them or interfere with the flow of the app?
example:
suppose i have a broadcastReceiver that listens to some kind of intent , but this intent is only meant to be used by another service/activity that resides either inside my app , or inside another app that i've created , but i don't want others to be able to use this intent.
please help me.
setPackage()
Set an explicit application package name that limits the components this Intent will resolve to. If left to the default value of null, all components in all applications will considered. If non-null, the Intent can only match the components in the given application package.
or you can use setSelector() , but not both.
suppose i have a broadcastReceiver that listens to some kind of intent , but this intent is only meant to be used by another service/activity that resides either inside my app , or inside another app that i've created , but i don't want others to be able to use this intent.
In addition to Reno's fine answer, for your specific requirement quoted above, use LocalBroadcastManager. Not only do you get the security you seek, but it is more efficient. LocalBroadcastManager is available in the Android Support package and AFAIK should work going back to Android 1.6. Here is a sample project using LocalBroadcastManager.

How can i know supported intents of the 3rd party app

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....

Categories

Resources