26

My application that is not on Play Store verify on the web If there are a new version and download and start it. After the installation I would like to restart the application and I would use a BroadcastRecevier with ACTION_PACKAGE_REPLACED. This is the code :

Broadcast:

public void onReceive(Context context, Intent intent) {
  if(intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)){
    ApplicationInfo app = new ApplicationInfo();
    if(app.packageName.equals("it.android.downloadapk")){
      Intent LaunchIntent = context.getPackageManager().getLaunchIntentForPackage(app.packageName);
      context.startActivity(LaunchIntent);                    
    }
  }
}

Manifest:

<receiver android:name="it.android.downloadapk.Broadcast">
  <intent-filter>
    <action android:name="android.intent.action.ACTION_PACKAGE_REPLACED"></action>
    <data android:scheme="package" android:path="it.android.downloadapk" /> 
  </intent-filter>
</receiver>

The problem is that when I install new apk, the Broadcast appears not to start, why ?

Sami Eltamawy
  • 9,874
  • 8
  • 48
  • 66
MisterX_Dev
  • 429
  • 2
  • 7
  • 16

5 Answers5

30

see this:

How to know my Android application has been upgraded in order to reset an alarm?

correct fix is that you use the wrong string in the manifest: http://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_REPLACED

it should be "android.intent.action.PACKAGE_REPLACED" instead.


ok , i see that what i've written is still not enough to try it out, so i will make an exception and publish a whole project just to show that it works: app code is in a package called "com.broadcast_receiver_test" . don't forget to run it before testing , or else it won't work on some android versions (i think API 11+) .

manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.broadcast_receiver_test" android:versionCode="1"
  android:versionName="1.0">
  <uses-sdk android:minSdkVersion="3" />

  <application android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">

    <activity android:name=".BroadcastReceiverTestActivity"
      android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

    <receiver android:name=".MyBroadcastReceiver">
      <intent-filter>
        <action android:name="android.intent.action.PACKAGE_REPLACED"/>
        <data android:scheme="package"  />
      </intent-filter>

      <intent-filter>
        <action android:name="android.intent.action.PACKAGE_REMOVED"/>
        <data android:scheme="package"  />
      </intent-filter>

      <intent-filter>
        <action android:name="android.intent.action.PACKAGE_ADDED"/>
        <data android:scheme="package"  />
      </intent-filter>
    </receiver>

  </application>
</manifest>

MyBroadcastReceiver.java:

public class MyBroadcastReceiver extends BroadcastReceiver
  {
  @Override
  public void onReceive(final Context context,final Intent intent)
    {
    final String msg="intent:"+intent+" action:"+intent.getAction();
    Log.d("DEBUG",msg);
    Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
    }
  }

please just run it and see that it works perfectly .


EDIT: if your app is for API12 and above, and only wish to handle the case of updating of your app, you can use this intent alone:

http://developer.android.com/reference/android/content/Intent.html#ACTION_MY_PACKAGE_REPLACED

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • did you try to check if it works even with manual installation of a newer version ? also, maybe it only works if the build number is larger than the current one? frankly , i never used it , so it's just my guess. – android developer May 23 '12 at 23:27
  • did you also try to listen to this event when another app is being updated? – android developer May 24 '12 at 05:53
  • btw, how did you overcome the need to make the confirmation of installing an apk? is it still appearing to the user for each time it needs to update? – android developer May 24 '12 at 06:01
  • I start the APK this code: Intent intenti = Intent new (Intent.ACTION_VIEW); intent.setDataAndType (Uri.fromFile (new File (Environment.getExternalStorageDirectory () + "/ download /" + "apkname.apk")), " application / vnd.android.package-archive "); startActivity (intent); – MisterX_Dev May 24 '12 at 07:14
  • but it will ask the user to install it like any apk , no? if not , how come? – android developer May 24 '12 at 08:24
  • Yes. I have try to insert into my Broadcast also the action BOOT_COMPLETED and it work...then is the action ACTION_PACKAGE_REPLACED that is not detected from receiver ! I have also try with action ACTION_PACKAGE_INSTALL, ACTION_PACKAGE_ADD but it not work....but the code seems right or not ? – MisterX_Dev May 24 '12 at 08:43
  • the code seems ok ,but try to also put there a log in order to see that it reaches the "onReceive" method . also check that it works when another app is being updated. – android developer May 24 '12 at 09:14
  • But how can I do for the log ? it don't enter into onReceive method ! :( – MisterX_Dev May 24 '12 at 11:07
  • i don't understand . put the Log.d("TAG","TEST"); into the onReceive() method on the beginning of the method, before all "if" conditions . i suspect that if you do reach it , you are doing the checking wrong since you create an empty new instance instead of checking the intent itself. – android developer May 24 '12 at 15:58
  • The problem is that the application don't call onReceive() method, I have try with ACTION_BOOT_COMPLETED and it call onReceive()..there is same problem with ACTION_PACKAGE_REPLACED,INTALL,etc ut the code I think is correct... – MisterX_Dev May 25 '12 at 07:40
  • i've found it : you wrote the wrong test in the manifest. you wrote "android.intent.action.ACTION_PACKAGE_REPLACED" instead of "android.intent.action.PACKAGE_REPLACED" . see this : http://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_REPLACED . read it carefully or you will make the same mistake again . – android developer May 25 '12 at 08:30
  • I have changed with android.intent.action.ACTION_PACKAGE_REPLACED and into onReceive() if(intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)){ .. but not work :( I have try to update same application from the market...onReceive() method is never called !! – MisterX_Dev May 25 '12 at 09:23
  • added code so that you could see that it works fine . please , for the next time , just try things out in the most basic way and then go further. – android developer May 25 '12 at 09:41
  • still not working , even using my code ? are you sure you've installed&run it , and then installed/removed/updated an app and nothing occurred? here's a link to the whole project: http://speedy.sh/v6eFB/BroadcastReceiverTest.7z . maybe now it will work for you . for me it works perfectly on nexus one , android 2.3.7 . – android developer May 25 '12 at 10:15
  • Ok, the problem was that this code only work when I install or update or remove other application but not the application BroadcatReceiverTest....I wanted to use for the same application!! – MisterX_Dev May 26 '12 at 22:08
  • seems logical , though the API doesn't say it for some of the cases . hope you've finally found the answer , kindly tick this answer ... – android developer May 26 '12 at 23:05
  • but it is not possible to check if the applicazion update itself ?? – MisterX_Dev May 27 '12 at 02:13
  • well you can save the current version code and check upon each application creation if it's different , and if it is , it means that the user has updated the app. – android developer May 27 '12 at 07:32
  • @android developer: does it make any difference if I write each action in separate tag? Or write all actions in same tag? – AndroidDev Sep 30 '13 at 14:26
  • @256 according to the XML "rules" if you add the same attribute again and again, the last attribute will hold, right? so yes, you have to separate them. – android developer Sep 30 '13 at 18:18
  • @android developer: Thanks for your reply. I want to ask another question, do we get android.intent.action.PACKAGE_REMOVED when my package is uninstalled ? Well I dont think so its fired in the case when we replace our existing project with new version. Because I have never got this broadcast. – AndroidDev Oct 01 '13 at 06:22
  • @android developer: And yes I have checked, android.intent.action.PACKAGE_ADDED is never fired !!! – AndroidDev Oct 01 '13 at 06:30
  • @256 about PACKAGE_REMOVED the answer is : no you don't get notified of your current app. however, some apps like Dolphin web browser somehow do get notified on the removal of itself, but i have no idea how they did it. i've made a post about it here: http://stackoverflow.com/questions/18440293/how-does-dolpin-web-browser-get-notified-when-its-being-uninstalled . if you do find out how it works or a workaround for checking if the current app was uninstalled, please let me know. – android developer Oct 01 '13 at 06:32
  • @256 i don't understand the part of the "PACKAGE_ADDED is never fired" ... wasn't i right about it that you shouldn't put all of the info on the same tag? maybe the part of the "latest is the one that will work" isn't correct, but it doesn't make sense to put all inside where each has the same attribute name. – android developer Oct 01 '13 at 06:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/38390/discussion-between-256-and-android-developer) – AndroidDev Oct 01 '13 at 06:44
  • i can't chat right now. i work and when i have some short time, i answer to questions. – android developer Oct 01 '13 at 06:45
  • I also need this feature to be implemented in my app. I tried the steps above and it only triggered if its another app and not the same app which has the receiver registered.. The receiver wont be registered since the app is terminated during the installation/update.. So anyone found a way ? – Thilek Nov 19 '13 at 13:46
  • @Thilek can you please explain what did you test exactly ? did you try to install&run your app with build number X and then install it with build number X+1 ? – android developer Nov 19 '13 at 14:20
  • @androiddeveloper Yup exactly.. When my detects if there is a new version available in our server, the apk file is downloaded to the sd card and the installation is triggered using the installation intent. But upon installation complete i would like the app to restart. So i used the following example given above but the Receiver only detects the changes/updates done to other apps but not the which been listening and updated. – Thilek Dec 16 '13 at 09:24
  • @Thilek i cannot confirm, as my own app does get the intent when installing (it gets PACKAGE_REMOVED and then gets ACTION_PACKAGE_REPLACED). i've tested it with both eclipse and using a simple apk file. also tried increasing the version code. in all cases, it worked fine. i've now cleaned the manifest code of this answer. please try it out. would you also please make a sample app having the bare minimal code so that i could check it out? – android developer Dec 16 '13 at 23:04
  • Actually my widget stops working when memeory is cleaned by task manager.how can I get broadcast for `"android.intent.action.PACKAGE_DATA_CLEARED"` and `"android:name="android.intent.action.PACKAGE_RESTARTED"` doc say's `restarted/Cleared package does not receive this broadcast` then how can I know that my package is cleared and I have to call OnUpdate of widget to reinitilize my view of widget again – Shakeeb Ayaz Dec 18 '13 at 04:08
  • @ShakeebAyaz you won't be able to run anything when your app is cleared from data, since it also mean it's in a "stopped" state, the same state your app is when the end user only installs your app. you will just have to handle updating the appWidget so that if it doesn't have any configurations stored, initialize it again as if now the user has created and put it again on the "desktop". – android developer Dec 18 '13 at 06:25
  • but how to do that I dont know when my application is being cleaned – Shakeeb Ayaz Dec 18 '13 at 06:27
  • 1
    @ShakeebAyaz you don't get notified inside your app when it gets cleared, since it also means your app will be stopped (at least that's what i noticed). anyway, if you wish to handle upgrading of your app, i've found another solution, but it requires API12 : http://developer.android.com/reference/android/content/Intent.html#ACTION_MY_PACKAGE_REPLACED – android developer Dec 21 '13 at 22:11
  • Is there a way that app receives the MY_ACTION_REPLACED intent while in stopped state (before launch) ? – Singed Jul 28 '15 at 09:10
  • @Singed You mean a custom intent? Have you tried firing it via another app? – android developer Jul 28 '15 at 10:12
9

I put the following receiver in the AndroidManifest.xml

<receiver android:name=".StartupReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
    </intent-filter>
</receiver>

So my app can be launched on update as well as device reboot. Ofcourse as everyone has mentioned that you need API 12+ for MY_PACKAGE_REPLACED.

Sileria
  • 15,223
  • 4
  • 49
  • 28
1

After hours and hours of searching how to restart your app after it was updated, I finally find why it won't restart.

The app must NOT be launched by Android Studio or other IDE. If I manually install app with its apk and launch it from the current Android device, the app can recognize if there was an update of my application and it restarts correctly.

My user case is a custom launcher that can update by itself launching a PackageInstaller.Session without going to Google Play Store

Here it's the code

Manifest:

<receiver android:name="UpdateReceiver" >
     <intent-filter>
         <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
     </intent-filter>
</receiver>

UpdateReceiver (Kotlin code):

class UpdateReceiver: BroadcastReceiver() {

    companion object {
        private val TAG = UpdateReceiver::class.java.simpleName
    }

    override fun onReceive(context: Context?, intent: Intent?) {
        Log.d(TAG, "onReceive ${intent?.action ?: "unknown action"}")
        if (intent?.action == Intent.ACTION_MY_PACKAGE_REPLACED) {
          
            //MainActivity = Your first activity
            val yourIntent = Intent(context, MainActivity::class.java)
            yourIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            context?.startActivity(yourIntent)
        }

    }
}
0

After two days of struggle and experimentation, I found out the reason. It turned out I need to carefully read the official documentation.

As said here: https://developer.android.com/reference/android/content/Intent#ACTION_MY_PACKAGE_REPLACED

It turned out the key phrase is: It does not contain any additional data

those. if you changed the manifest, then the application will not restart after updating

you are welcome

0

For anyone trying all the other answers without success, I recommend you restarting the app.

I noticed the app was successfully updated, but it wasn't being launched even though I tried starting the activity in many ways.

I used https://github.com/JakeWharton/ProcessPhoenix in the BroadcastReceiver, so basically in the update you're downloading, add ProcessPhoenix.triggerRebirth(context); in your BroadcastReceiver, or restart the app somehow in there.

Computer's Guy
  • 5,122
  • 8
  • 54
  • 74