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).
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.
Background
It might be useful for apps to allow to ask the user to answer why it was decided to uninstall them.
The problem
It seems that the Dolphin web browser app (and "everything me launcher") somehow managed to bypass it, and now it shows a webpage (on the default web browser) each time the app is being uninstalled.
This happens even if I uninstall using ADB.
As a user, I really hate it, but it's still interesting since as far as I know, apps can't get intents for the uninstallation of themselves.
Question
How could it be? How did they manage to overcome this?
Is this a hack?
Maybe the app has a background service which checks the foreground app when it's own onDestroy() callback is fired, and if the foreground app is the uninstalling activity of android Package installer, it launch a new intent for the webpage?
My guess is that they're using ACTION_PACKAGE_REMOVED.
http://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_REMOVED
Either that, or Robin Hood and Frei Tuck method, where each one listens to broadcasts events from the other.
Just a guess, but will look into it.
This might be an option: How can an app detect that it's going to be uninstalled?
Please try to get the top activity in the task via ActivityManager, and check if it is the uninstall activity.
Core code:
ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity;
String packageName = topActivity.getPackageName();
String className = topActivity.getClassName();
Log.v(TAG, "packageName" + packageName);
Log.v(TAG, "className" + className);
if ("com.android.packageinstaller".equals(packageName)
&& "com.android.packageinstaller.UninstallerActivity".equals(className)) {
//Do anything you want here
}
I am writing an Andoid app so that when battery life gets below a certain level, a dialog with options of how to save the battery appears. One of those options is to close all background apps/services (processes) using ActivityManager.killBackgroundProcesses(). The code is shown here:
public void TaskKiller( View view){
List<ApplicationInfo> packages;
PackageManager pm;
pm = getPackageManager();
packages = pm.getInstalledApplications(0);
ActivityManager mActivityManager = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
for (ApplicationInfo packageInfo : packages) {
mActivityManager.killBackgroundProcesses(packageInfo.packageName);
}
}
However, when I click the button that calls TaskKiller() and closes the background processes, some of the apps (Email, Google Maps) instantly begin he process of restarting. How can I alter my code so these apps stay closed until they are reopened? Also, is this approach sensible in regard to saving power or am I attacking this the wrong way?
I don't think that's the right way of handeling the problem.
These apps have broadcast receivers, which mean they'll restart the service whenever something happens (i.e. AC plugged in/WiFi turned on), and I don't think there's a way to stop that without root, and actually disabling the broadcast receiver.
You could make something that kills it every 5 minutes, but that wouldn't be very battery-friendly.
I don't think it's a good idea to force close the Maps app everytime, it's a bug in Android i think..
One of the answers is as following:
"
Actually, Maps always runs when you have "Backround Data" checkmarked in your General Sync Settings under Account Settings in your phone's Gmail app. Syncing backround data is necessary, unfortunately, in order for your phone service provider to provide calling and texting (although internet access will still work without this item checkmarked). Unchecking this box will remove Maps from Running applications (& any other app that needs it), improving battery time and speeding up your phone. But, if you want to make calls, text or use apps that require Backround sync, you have to have this ckeckmarked. If all you want to do is browse the net...uncheckmark it. There are currently no other legitimate solutions to the issue. Hope this is helpful...
"
See this issue (https://code.google.com/p/android/issues/detail?id=10251)
is it possible to run a broadcast receiver to detect, pause installing and alert when an application is installing.
onRecive
public class Receiver extends BroadcastReciver{
public void onReceive(Context context, Intent intent ){
if(intent.getAction().equals("android.intent.action.PACKAGE_INSTALL")){
//i want to pause the installing activity and prompt an alert box
}
}
}
Purpose would be, when an application is going to install, it ask are you really want to install this application.
After doing a lot of R & D I'm really stuck with a solution for this, if u please can help me out with this, thank you a lot.
This is possible according to this research paper. Look page 2 Figure 1.
You cannot pause it. There is no API for this. This is a system level function not meant to be handled by 3rd party applications.
This is a security measure. Image if every app could control the installation of all other apps! It would be a big security misstep! Hence it's not available.
You can, however detect the installation of a package. See this thread:
Receiving package install and uninstall events
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