2012-10-01 23 views
16

Estoy usando ACTION_MY_PACKAGE_REPLACED para recibir cuando mi aplicación se actualice o se vuelva a instalar. Mi problema es que el evento nunca se desencadena (probé Eclipse y el dispositivo real). Esto es lo que hago:ACTION_MY_PACKAGE_REPLACED no recibido

Manifiesto:

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

Código:

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 
     } 
    }  
} 

Este código es simple, en una verdadera utilicé otros eventos como BOOT_COMPLETED y otros, y que funcione, pero ACTION_MY_PACKAGE_REPLACED. Gracias.

+2

Usted tiene dos problemas. Tu nombre de acción es incorrecto; no debe incluir el prefijo 'ACTION_'. Además, 'MY_PACKAGE_REPLACED' es para API 12+. – Sam

Respuesta

8

Obtención de información de todos los usuarios que pude resolver mi situación de esta manera. Todos ellos tenían razón, con pequeños puntos a notar:

en el manifiesto:

<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> 

Y código:

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. 
      } 
     } 
    }  
} 

En mi versión de Android (Gingerbread 2.3) yo no era capaz de use MY_PACKAGE_REPLACED pero lo resolvimos usando PACKAGE_REPLACED (le avisaremos si alguna aplicación ha sido reemplazada) pero le preguntamos si es nuestra con:

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

Gracias a todos

2

¿Lo está intentando en un dispositivo API/API = = 12/emulador? Esta emisión no se enviará en los casos anteriores, ya que es API 12. Si necesita que su aplicación reciba esto para Pre-ICS y los antiguos dispositivos de panal de miel,

intento:

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

Gracias. Bueno, también probé ACTION_PACKAGE_REPLACED pero tampoco se activó nada. Y sí, Emulator y Device son GingerBread. ¿Alguna otra pista? – Ton

+0

¿Ha agregado el receptor? como y Utilizo esto para varias de mis aplicaciones y funcionan bien en todos los dispositivos Android> 1.5 – Edison

-3

Es necesario añadir esquema de datos para el filtro de la intención, como a continuación

<receiver android:name=".MyEventReceiver" > 
    <intent-filter android:priority="1000" > 
     <action android:name="android.intent.action.ACTION_MY_PACKAGE_REPLACED" /> 
     <data android:scheme="package"/> 
    </intent-filter> 
</receiver> 
+8

Según la [documentación] (http://developer.android.com/reference/android/content/Intent.html#ACTION_MY_PACKAGE_REPLACED), el valor de la constante 'ACTION_MY_PACKAGE_REPLACED' es' android.intent.action.MY_PACKAGE_REPLACED' sin la parte 'ACTION_'. – MaxChinni

+0

debes usar Intent.ACTION_MY_PACKAGE_REPLACED que equivale a "android.intent.action.MY_PACKAGE_REPLACED" – FabioC

19

por alguna razón, un desarrollador de Google (llamado "Dianne Hackborn") piensa que es posible registrar a la intención PACKAGE_REPLACED de la aplicación actual solo (enlace here).

Sin embargo, no puedo encontrar ninguna forma de hacerlo correctamente, así que hice un compromiso: utilizará la API más reciente cuando esté disponible.

Lamentablemente, no puedo averiguar por qué no se puede depurar, pero funciona (puede escribir en el registro si lo desea).

aquí está el código:

manifiestan:

<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/valores/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/valores-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"); 
+0

Debes agregar ** android: debuggable = "true" ** y ** android: exported = "true" ** a tu manifiesto declaración para poder depurar el receptor. p. '' –

+0

pero ya se puede depurar como lo ejecuté desde Eclipse ... también creo que se ha exportado ya que es cómo obtiene la intención del sistema ... ¿Seguro que lo arregla?si es así, eso es extraño –

+0

Nunca se supo sobre ' falso', siempre se usó el más corto ' falso' – cprcrack

0

trabajo Manifiesto Simple en todas las versiones:

<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> 
+0

pero esto hará que su aplicación se active cada vez que CUALQUIER otra aplicación se sustituya en dispositivos con API 12 o superior – Gavriel

4

sólo quiero añadir mis dos peniques vale aquí, porque tenía problemas haciendo que esto funcione y lo depure ... Estoy usando un dispositivo Lollipop:

Este es el código que utilicé:

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

para depurarlo, es necesario asegurarse de haber instalado la actualización en su teléfono, sólo a través de Eclipse de depuración está muy bien, y se abrió la aplicación por lo menos una vez, a continuación, simplemente puede editar la configuración de depuración:

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

me confirmó que trabajó escribiendo un pequeño archivo en la tarjeta SD

+5

¡esta respuesta es correcta! MY_PACKAGE_REPLACED no funcionaba antes para mí, pero yo _REMOVED_ que estaba allí después de probar PACKAGE_REPLACED antes de – Boy

12

el accepted answer no trabaja más con Android 1.0+ estudio debido a la fusión de manifiesto problemas, como s een here. Totalmente basado en android developer's answer, He arreglado el problema con la siguiente implementación:

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"); 
    } 
} 
+0

¿qué hay de diferente aquí exactamente que lo que he escrito? ¿Acaba de agregar "getApplicationContext"? Además, si ha encontrado un error en Android-Studio (o Android), debe publicarlo aquí: https://code.google.com/p/android/issues/list –

+2

No es un error, es solo que la nueva fusión de manifiesto no admite lo que estás haciendo. Y lo que es diferente, dices? No puedes usar la misma clase para dos receptores diferentes. Entonces, si miras mi código, utilicé una clase interna estática en uno de los receptores, cumpliendo así con la nueva fusión de manifiesto y al mismo tiempo evitando los archivos java para la misma tarea. Aparte de eso, todo es equivalente, por supuesto, y acabo de agregarlo porque las respuestas en StackOverflow deben ser autónomas. – cprcrack

+0

Además, siga los enlaces que proporcioné si está interesado en saber por qué su solución no funciona ahora en Android Studio. Del mismo modo, eche un vistazo al código o intente primero su código y luego mire en Android Studio 1.0+ si todavía no puede ver qué es diferente, porque soy consciente de que no puedo explicarlo con más detalle. – cprcrack

Cuestiones relacionadas