By default, an application which in stopped state (not yet run even once) could not receive broadcasts. There is a way to receive it if we add the flag FLAG_INCLUDE_STOPPED_PACKAGES to the broadcast intent.
My problem is that I need to receive system intent android.intent.action.MEDIA_MOUNTED (and I don't want to add that flag to it).
How can I receive it even in stopped application?
It seems to me that for sure it's possible because for example com.android.shell application is able to receive such intents even if it's force stopped. How it does it?
EDIT:
Just to clarify, because it appeared that this is not obvious:
Everything here is from the point of view of Android Open Source Project developer. I'm modifying the operating system source code and the application which I want to receive the broadcast could be preinstalled, signed with platform certificate, it can use hidden API, etc. Everything is permitted, even modifications of the system.
Declaring your application as a system app should allow you to receive regular broadcasts even if your app is in "stopped state".
Add the following to your manifest and make sure your application is signed by the platform key:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
...
android:sharedUserId="android.uid.system">
If you are not referring to Force Stopped applications, but rather to closed applications that are in the stopped state, then look at these two links to find out how to implement a BroadcastReceiver that can be activated after the app is closed. Otherwise a custom ROM and or sys app is the way to go probably.
BroadcastReceiver 1
BroadcastReceiver 2
If you are on a rooted device you can use Xposed to modify android.content.Intent#isExcludingStopped, as such:
public class DontExcludeStoppedPackagesFromIntents implements IXposedHookLoadPackage {
#Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals("android")) {
XposedBridge.log("In package: " + lpparam.packageName);
findAndHookMethod("android.content.Intent", lpparam.classLoader, "isExcludingStopped", new XC_MethodReplacement() {
#Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return false;
}
});
}
}
}
Don't forget to put the class name in xposed_init.
Of course this has some security implications, effectively taking you back to Android 3.0-, though this shouldn't be much of an issue because noone expects to exploit a vulnerability that is not present on nearly all existing Android devices that do no have this patch applied.
I tried the above and it works!
Related
I'm looking to expand my app to handle Guest Mode, introduced in Android L. I found that if I create a service with android:singleUser in AndroidManifest, with permission INTERACT_ACROSS_USERS, and I'm a system app by installing it in /system/priv-app, then my service is running even as I switch user. But my app needs to interact with the user, by being able to launch an activity, show a toast or notification. All of those things seems to not be possible. Is there a particular flag I need to set when I call startActivity so that it will launch a new activity from my service?
I found a way to do it. Basically have a singleton Service, which is a service with the android:singleUser="true" and with INTERACT_ACROSS_USERS and have the APK installed in /system/priv-app. Then have it broadcastAsUser to all users. You'll need to use reflection to access methods in UserManager. Then have a receiver instance which will receive the broadcast in the guest user's space, and then have the receiver startActivity.
There are several internal apis (comments as #hide) like Context.startActivityAsUser, NotificationManager.notifyAsUser to support it, but it needs build from source also with platform signature.
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.
I'm developing android application for CAR usage and I need that in phone or tablet the driver can only run and use this application: No calling or running other app. Is that possible? If it is not, is there any way to restrict the user for example uninstallaing other apps and disabling the installation system and disabling the calling system?
Thanks in Advance,
I have done a similar app like this, which is in fact an in-cab entertainment system. I have also written a blog post about it, you can check it out here: http://arnab.ch/blog/2012/01/android-auto-updating-homescreen-application/.
This is a complex application and let me list out the relevant items for you:
Your app should be a HomeScreen application (search google for how to create HomeScreen app for Android)
It seems clear that you would have some control over the device, so you can ensure that no additional applications are installed.
The homescreen can be dynamically enabled/disabled, check out KytePhone app to see what I meant. In short you would need some password to exit your HomeScreen app.
If you want to silently uninstall/install any application, then you'd need root access, or you'd have to have a custom Android build where your app will have System privilege (might not be what you're looking for).
I hope I am able to give you some direction, if anything is not clear then let me know.
You can use Accessibility service to solve this issue and you need to check granted application packages inside onAccessibilityEvent method.
import android.accessibilityservice.AccessibilityService;
public class MyAccessibilityService extends AccessibilityService {
...
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
#Override
public void onInterrupt() {
}
...
}
please follow the link: https://developer.android.com/training/accessibility/service.html
This code will run an app automatically after booting the system, but the app will close after pressing the back button.
If the app is run normally by clicking it's icon. It will continuously run even after pressing the back button or running other apps.
public class AutoBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
My question is, how to make this auto run code to continuously run even after pressing the back button or running other apps?
You can probably start a Service here if you want your Application to run in Background. This is what Service in Android are used for - running in background and doing longtime operations.
UDPATE
You can use START_STICKY to make your Service running continuously.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleCommand(intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
As apps run in the background anyway, I'm assuming what your really asking is how do you make apps do stuff in the background. The solution below will make your app do stuff in the background after opening the app and after the system has rebooted.
Below, I've added a link to a fully working example (in the form of an Android Studio Project).
This subject seems to be out of the scope of the Android docs, and there doesn't seem to be any one comprehensive doc on this. The information is spread across a few docs.
The following docs tell you indirectly how to do this:
https://developer.android.com/reference/android/app/Service.html
https://developer.android.com/reference/android/content/BroadcastReceiver.html
https://developer.android.com/guide/components/bound-services.html
In the interests of getting your usage requirements correct, the important part of this above doc to read carefully is: #Binder, #Messenger and the components link below:
https://developer.android.com/guide/components/aidl.html
Here is the link to a fully working example (in Android Studio format):
https://developersfound.com/BackgroundServiceDemo.zip
This project will start an Activity which binds to a service; implementing the AIDL.
This project is also useful to re-factor for the purpose of IPC across different apps.
This project is also developed to start automatically when Android restarts (provided the app has been run at least one after installation and app is not installed on SD card).
When this app/project runs after reboot, it dynamically uses a transparent view to make it look like no app has started but the service of the associated app starts cleanly.
This code is written in such a way that it's very easy to tweak to simulate a scheduled service.
This project is developed in accordance to the above docs, and is subsequently a clean solution.
There is, however, a part of this project which is not clean: I have not found a way to start a service on reboot without using an Activity. If anyone reading this post has a clean way to do this, please post a comment.
Starting an Activity is not the right approach for this behavior. Instead have your BroadcastReceiver use an intent to start a Service which can continue to run as long as possible. (See http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle)
See also Persistent service
Is it possible to force a reboot of the device after my apk is installed?
I want to force this because I want to ensure that my service is started.
Most probably the answer is no, your are not allowed to do such things from your app. This is the sole privilege of the user holding the phone (and of maybe the core system services).
You can however ensure you service is started when the user starts you main activity, which would be a very normal thing to do right after the user have installed your application.
For additional information see the question How to start android service on installation, which is in fact what you should be trying to do.
It's not possible in any way to get your application to do anything as soon as it's installed, before the user first launches it from the home screen. There's no broadcast action you can listen for explicitly. However, you can listen for something generic that gets called a lot, such as:
android.intent.action.USER_PRESENT,
android.intent.action.SCREEN_OFF, or
android.intent.action.SCREEN_ON
In any case you should NOT reboot the device. Your users will hunt you down and kill you with stones. Joke aside, Google might actually pull your app from the Market for this. Just listen for one of the actions mentioned above, check if the app has just been installed (using a one-time boolean preference, for example) and start the service.
Note: if you do end up listening for one of the above actions, please disable your receiver the first time it receives an intent. You can do this like so (in your receiver):
public class FirstTimeReceiver extends BroadcastReceiver {
public void onReceive (Context context, Intent intent) {
// start your service (which does stuff asynchronously, of course, and then:
final ComponentName mySelf = new ComponentName(context, FirstTimeReceiver.class);
context.getPackageManager().setComponentEnabledSetting(mySelf, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}
However, you should only do this if somehow this service is absolutely critical for the user (there are few proper scenarios for this), and not for you / your app. As bjarkef mentioned, you should only start it after the user starts your app from the home screen (better yet, ask for permission from the user to run the service).