web-dev-qa-db-fra.com

ACTION_MY_PACKAGE_REPLACED non reçu

J'utilise ACTION_MY_PACKAGE_REPLACED pour recevoir lorsque mon application est mise à jour ou réinstallée . Mon problème est que l'événement n'est jamais déclenché (j'ai essayé Eclipse et un périphérique réel) . C'est ce que je fais:

Manifeste:

<receiver Android:name=".MyEventReceiver" >
    <intent-filter Android:priority="1000" >
        <action Android:name="Android.intent.action.ACTION_MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>

Code:

public class MyEventReceiver extends BroadcastReceiver
{  
   @Override public void onReceive(Context context, Intent intent)
   {  
      if ("Android.intent.action.ACTION_MY_PACKAGE_REPLACED".equals(intent.getAction())) 
      {  //Restart services
      }
   }      
}

Ce code est simple, en réalité, j’ai utilisé d’autres événements comme BOOT_COMPLETED et d’autres, et ils fonctionnent, mais ACTION_MY_PACKAGE_REPLACED . Merci.

21
Ton

En obtenant des informations de tous les utilisateurs, je pouvais résoudre ma situation de la manière suivante… Tous avaient raison, avec quelques points à noter:

En manifeste:

    <receiver Android:name=".MyEventReceiver" >
        <intent-filter Android:priority="1000" >
            <!--other actions I need-->
            <action Android:name="Android.intent.action.PACKAGE_REPLACED" />
            <data Android:scheme="package"/>
        </intent-filter>
    </receiver>

Et code:

public class MyEventReceiver extends BroadcastReceiver
{     
    @Override public void onReceive(Context context, Intent intent)
    {  
       if(Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) 
       {   if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName()))
           {  //Restart services.
           }
       }
    }      
}

Dans ma version Android (2.3 Gingerbread), je ne pouvais pas utiliser MY_PACKAGE_REPLACED, mais nous avons résolu le problème en utilisant PACKAGE_REPLACED (nous aviserons de toute application remplacée), mais nous demanderons si c'est la nôtre avec:

 if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName()))
 {
 }

Merci à tous

8
Ton

pour une raison quelconque, un développeur Google (nommé "Dianne Hackborn") pense qu'il est possible de s'enregistrer à l'intention PACKAGE_REPLACED de l'application actuelle uniquement (lien ici ).

cependant, je ne trouve aucun moyen de le faire correctement. J'ai donc fait un compromis: il utilisera la plus récente API, le cas échéant.

Malheureusement, je ne peux pas savoir pourquoi il ne peut pas être débogué, mais cela fonctionne (vous pouvez écrire dans le journal si vous le souhaitez).

voici le code:

manifeste:

    <receiver
        Android:name=".OnUpgradeBroadcastReceiver"
        Android:enabled="@bool/is_at_most_api_11" >
        <intent-filter>
            <action Android:name="Android.intent.action.PACKAGE_REPLACED" />
            <data Android:scheme="package" />
        </intent-filter>
    </receiver>
    <receiver
        Android:name=".OnUpgradeBroadcastReceiver"
        Android:enabled="@bool/is_at_least_api_12" >
        <intent-filter>
            <action Android:name="Android.intent.action.MY_PACKAGE_REPLACED" />
        </intent-filter>
    </receiver>

res/values ​​/ version_checks.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <item name="is_at_least_api_12" type="bool">false</item>
    <item name="is_at_most_api_11" type="bool">true</item>

</resources>

res/values-v12/version_checks.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <item name="is_at_least_api_12" type="bool">true</item>
    <item name="is_at_most_api_11" type="bool">false</item>

</resources>

OnUpgradeBroadcastReceiver.Java

public class OnUpgradeBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        if (VERSION.SDK_INT <= VERSION_CODES.HONEYCOMB
                && !context.getPackageName().equals(intent.getData().getSchemeSpecificPart())) {
            Android.util.Log.d("AppLog", "other apps were upgraded");
            return;
        }
        Android.util.Log.d("AppLog", "current app was upgraded");
22
android developer

La réponse acceptée ne fonctionne plus avec Android Studio 1.0+ en raison de problèmes de fusion manifeste, comme on le voit ici . Totalement basé sur réponse du développeur Android , j'ai résolu le problème avec l'implémentation suivante:

AndroidManifest.xml:

<receiver Android:name=".UpdateReceiver$LegacyUpdateReceiver" Android:enabled="@bool/shouldUseActionPackageReplaced" >
    <intent-filter>
        <action Android:name="Android.intent.action.PACKAGE_REPLACED" />
        <data Android:scheme="package" />
    </intent-filter>
</receiver>
<receiver Android:name=".UpdateReceiver" Android:enabled="@bool/shouldUseActionMyPackageReplaced" >
    <intent-filter>
        <action Android:name="Android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>

/res/values/resources.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="shouldUseActionPackageReplaced">true</bool>
    <bool name="shouldUseActionMyPackageReplaced">false</bool>
</resources>

/res/values-v12/resources.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="shouldUseActionPackageReplaced">false</bool>
    <bool name="shouldUseActionMyPackageReplaced">true</bool>
</resources>

UpdateReceiver.Java:

import Android.content.BroadcastReceiver;
import Android.content.Context;
import Android.content.Intent;
import Android.util.Log;

public class UpdateReceiver extends BroadcastReceiver
{
    public static class LegacyUpdateReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            if (intent != null && intent.getData() != null && context.getPackageName().equals(intent.getData().getSchemeSpecificPart()))
            {
                onUpdate(context);
            }
        }
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        onUpdate(context);
    }

    public static void onUpdate(Context context)
    {
        Log.d("LOG", "Current app updated");
    }
}
13
cprcrack

Je veux juste ajouter mes deux pence de valeur ici, car j’ai eu du mal à le faire fonctionner et à le déboguer. J'utilise un périphérique Lollipop:

C'est le code que j'ai utilisé:

    <receiver Android:name=".services.OnUpdateReceiver">
        <intent-filter>
            <action Android:name="Android.intent.action.MY_PACKAGE_REPLACED" />
        </intent-filter>
    </receiver>    

Pour le déboguer, vous devez vous assurer que vous avez installé la mise à jour sur votre téléphone, simplement via le débogage Eclipse, et que vous avez ouvert l'application au moins une fois. Vous pouvez simplement modifier votre configuration de débogage:

Eclipse > run > debug configurations > launch action (do nothing) > then F11 like normal

J'ai confirmé que cela fonctionnait en écrivant un petit fichier sur la carte SD

7
Steven Elliott

Manifeste simple fonctionnant dans toutes les versions:

    <receiver
        Android:name=".Receiver"
        Android:enabled="true"
        Android:exported="true" >
        <intent-filter>
            <action Android:name="Android.intent.action.PACKAGE_REPLACED" />
            <data Android:scheme="package"/>
        </intent-filter>
        <intent-filter>
            <action Android:name="Android.intent.action.MY_PACKAGE_REPLACED" />
        </intent-filter>
    </receiver>
2
Bouchehboun Saad

L'essayez-vous sur une API> = 12 périphérique/émulateur? Cette émission ne sera pas envoyée sur les cas précédents, car il s'agit de l'API 12. Si vous avez besoin que votre application le reçoive pour Pre-ICS et les anciens appareils à rayon de miel,

essayer:

if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
  if (!intent.getData().getSchemeSpecificPart()
       .equals(context.getPackageName())) {
    return;
  }
}
2
Edison

En fait, votre application démarrera deux fois lorsque vous installerez votre apk . Une fois pour chaque récepteur défini.

Lorsque vous écoutez Android.intent.action.PACKAGE_REPLACED, vous devez rechercher le nom du paquet dans la fonction intent.getData().

Notez que intent.getData() sera Null s'il provient de Android.intent.action.MY_PACKAGE_REPLACED

Je pense que l'utilisation de l'un d'eux suffit.

0
Omid Mehdizadeh