I'm aware of the fact that the app is uninstalled and re-installed during the course of an app update from the play store.
I have a very crucial service which needs to be running ALWAYS in the background. And this service gets killed during the update process. Is there any way to restart this service without having the user to go manually to the app (without going to the activity)?
I've implemented the following code. But somehow this doesn't work either. (Probably because the app gets uninstalled anyway)
public class AppUpdateReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent)
{
if ("android.intent.action.PACKAGE_REPLACED".equals(intent.getAction()))
// Start service here
}
}
MANIFEST:
<receiver android:name="com.company.services.AppUpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Other info : minSDK = 14, Target SDK = 20
I'm aware of the fact that the app is uninstalled and re-installed during the course of an app update from the play store
No, it is not. Your process is terminated, though.
I have a very crucial service which needs to be running ALWAYS in the background
A user can stop your service whenever the user wants to, above and beyond the OS terminating your process whenever the OS feels that it is appropriate.
But somehow this doesn't work either
Try to use ACTION_MY_PACKAGE_REPLACED instead and see if that helps.
Related
I am making a system app. In that I have a requirement is to run a service after boot load WITHOUT A SINGLE TIME LUNCHING THE APP.
this question is bit similar to this
System App auto starting
But it does not have any appropriate solution.
Also read that BOOT_COMPLETE_RECEIVER works only when app launched at once.
Use Broadcast Receiver for getting action after that start service from that broad cast receiver and use START_STICKY service so that if it is killed because of some priority than it's recreate and if you want to continuously run this service in background than WAKE_Lock that service and using Alarm Manager check it is runnig or not.
Set this in manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name="AutoStart"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
AutoStart class
public class AutoStart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
// Start your service here..
}
}
}
Thanks all for your effort, I finally got answer.
Solution:
As I stated my app is system app, System work even they not opened at once. Because they are not in stopped state i.e enforce after android 3.1.
Secondly If a user app wants this then Its manifest don't have any "android.intent.category.LAUNCHER" category in activity.
Also by adb you can enable your app by using this command
adb shell am broadcast -a com.example.demo.action.LAUNCH --include-stopped-packages (This is not tested)
Some good link to this:
http://droidyue.com/blog/2014/01/04/package-stop-state-since-android-3-dot-1/
Static BroadcastReceiver not Working after Installation from ADB
I am working on app which needs to executes a web-service at app install and only once.
Currently i used Shared Preferences for this, But if user clear app data then it lost Shared Preferences value and my code detracts that app is newly created and my code executes web-service further.
So i need solution which broadcast event of my own app install.
I also create broadcast for that but broadcasts only when other app install.
This code i used...
For Check Status
private void checkAppStatus() {
boolean isOpen = AppMethod.getBooleanPreference(MainActivity.this, AppConstant.PREF_IS_OPEN);
if (!isOpen) {
executeWS();
}
}
Broadcast
public class AppInfoReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("My App", "Install");
}
}
Manifest
<receiver android:name=".receiver.AppInfoReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
If you have a server, you can save status in your server and get the status before execute task
You have following options:
You can create a file in hidden directory on external memory with
needed information.
You can create and use your web service for those needs.
Your code doesn't work because your application not installed at that time when broadcast created and because in android your application can receive broadcasts only if it was launched at least one time by user.
As I understood, first option doesn't fit your needs too, cause there is some probability that external memory would be erased or replaced. Android devices doesn't provide any kind of memory that 100% would be persistent in time, and if you really need information about installation of your application you should run your server that receives android device id and sends back to your application information about rather it is first installation or re installation. However I suppose that you should assume clearing app data as application reinstall and run your web service one more time. Simplest solution: just pass to your service android device id and do your things if it is new id or not if it is already done.
I have implemented an app that is basically a custom app store for updating and launching a family of related apps. It also needs to update itself, which works, but the app is killed without warning during the install process. I want to automatically restart the app in this case so that the user can continue to use it immediately after an update.
So I made a separate application including only a single Broadcast Receiver that listens for package events for the first app's package name and starts a new activity. That receiver is never called:
<application android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<receiver android:name=".AppUpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package" />
</intent-filter>
</receiver>
In searching for similar implementations I have seen directly contradictory information on whether an application with only a receiver will ever execute, and whether a receiver will be called if its app is not already running. I've even come across example code of an application containing only a receiver, with a manifest very similar to my own. So what do I need in this application to ensure that the receiver is called whenever another package is installed?
If there is a better solution, I'd be happy to hear it.
Depending on the version of Android, you might need to start an application component in order for the BroadcastReceiver to be registered. By this I mean there will need to be a launcher Activity which must be started manually by the user.
From Honeycomb (I think) onwards it isn't possible to have application components 'active' unless the app has been manually started in some way. The reasoning behind this is the potential for insecure code executing without the end-users' knowledge.
I suspect this is what you're experiencing. To test it, add a simple "Hello World" Activity to the app that has the BroadcastReceiver in it. Launch the Activity and then check to see if the BroadcastReceiver then gets called after your other package is updated.
I have a very simple IntentReceiver to receive event when time changes. Here's the code:
public class IntentRec extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("IntentRec", intent.getAction());
}
}
<application android:label="#string/app_name" android:icon="#drawable/ic_launcher">
<receiver android:name=".IntentRec">
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>
<activity android:name="MyActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
However, I receive the intent while the application is running. But if I shutdown (using Force Close) the app, onReceive is not called. So my question is, do I receive intents only when listener app is running? I thought that intents was designed to run target listener class when the app was not running.
Thanks
The solution is simple: stop clicking Force Close.
On Android 3.1+, Force Close will prevent anything in your app from running again, until the user runs an activity of yours manually, or something else (e.g., third-party app) starts up your app.
UPDATE
I suspect that you are being confused by multiple meanings of the word "stopped". Let's walk through the process, avoiding the word "stopped", to see if it helps.
When your app is first installed on an Android device, is in a state known to some as "snicklefritzed". While the app is in this "snicklefritzed" state, no manifest-registered BroadcastReceiver will work. To move an app out of the "snicklefritzed" state, some third-party app (like the home screen launcher) must explicitly request to run something in your app (like an activity). So, the normal course of events is that the user downloads your app, clicks on the launcher icon for it, and your app is moved into the "normal" state and away from the "snickelfritzed" state. While in the "normal" state, your BroadcastReceiver will work fine.
Let's suppose that your BroadcastReceiver is for the ACTION_BOOT_COMPLETED broadcast. The "snicklefritzed" state has nothing to do with whether your app is presently running or not -- it is dependent only upon if your app has ever run or not. Hence, if the user installs your app, but reboots their phone before doing anything with your app, your ACTION_BOOT_COMPLETED receiver will not get control at boot time. If, however, the user runs something in your app, then reboots the phone, your receiver will receive the ACTION_BOOT_COMPLETED broadcast as normal.
Normally, apps move out of the "snicklefritzed" state and never return to that state. One thing that will cause an app to be "snicklefritzed" again is if the user clicks on Force Close for this app in Settings. Here, the user is expressly telling Android that your app is misbehaving and should not run again until the user says otherwise. If, of course, the user launches your activity again, you move back to "normal" state.
You have to add android:process=":remote" in order for the BroadcastReceiver to receive independent of your Activity.
<receiver android:name=".IntentRec"
android:process=":remote"> //We declare that this is in a remote process
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>
Cheers,
Zed
OK, so not entirely sure this is possible...
But trying to write an application so that I can run some code before any of the following activities are performed.
1) APK is downloaded from web and market launches installer
2) Install button is pressed on android market
Is it possible to intercept and prompt on these events, or has Google locked that stuff down quite tightly?
This isn't an answer per se, but I can't find any commenting tool here. Sorry.
I'm having this issue as well. I would like to be able to detect new application installs. I know it is possible - for example, the app Apps to SD posts a notification when you install a new app that when clicked opens a dialog to move that new app to the sd card.
So far, all I've been able to figure is like this:
manifest.xml:
...
<receiver android:name=".IntentReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
...
IntentReciever.java:
public class IntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, YourService.class));
}
}
YourService is then created and calls onCreate() then onStartCommand(). However, I haven't been able to debug this or successfully display any notifications from the service class, so I'm not entirely sure this works. I have gotten this to work for other Receivers like android.intent.action.BOOT_COMPLETED.
Using a BroadcastReceiver you can filter the android.intent.action.PACKAGE_ADDED intent. However this will only be after the two actions you describe, not before. And it will not stop or interrupt the installation.
AFAIK there is no way to do anything before or to interrupt the Market. And then we're even talking about another app than the one that's being installed ofcourse.