ACTION_MY_PACKAGE_REPLACED no recibido
Estoy utilizando ACTION_MY_PACKAGE_REPLACED para recibir cuando mi aplicación se actualiza o resina. Mi problema es que el evento nunca se desencadena (probé Eclipse y dispositivo real). Esto es lo que hago:
Manifiesto:
- Descartar la notificación de Android en curso mediante el botón de acción sin abrir la aplicación
- Detectar la desconexión desde un punto de acceso WiFi
- BroadcastReceiver no funciona cuando mato mi aplicación
- Crear notificación con BroadcastReceiver
- Error del receptor no registrado cuando se llama a la función onDestroy
<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 realidad utilicé otros eventos como BOOT_COMPLETED y otros, y funcionan pero ACTION_MY_PACKAGE_REPLACED. Gracias.
- Cómo determinar si una de mis actividades está en primer plano
- ¿Cuándo se transmite la intención ACTION_DEVICE_STORAGE_LOW?
- Por qué algunos receptores de radiodifusión sólo pueden registrarse a través de Code o AndroidManifest
- Android BootReceiver no funciona
- Utilizar el receptor de difusión para capturar la llamada entrante, onReceive no activado?
- ¿Cómo puedo interceptar pulsaciones de botón en el auricular en Android?
- La detección de cambios de estado de la red Android tarda tiempo
- Detener el receptor de difusión de un botón en acivity
Por alguna razón, un desarrollador de Google (llamado "Dianne Hackborn") cree que es posible registrarse en la intención PACKAGE_REPLACED de la aplicación actual solo (enlace aquí ).
Sin embargo, no puedo encontrar ninguna manera de hacerlo correctamente, por lo que he hecho un compromiso: se 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:
manifiesto:
<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");
La respuesta aceptada ya no funciona con Android Studio 1.0+ debido a problemas de combinación de manifiesto, como se ve aquí . Totalmente basado en la respuesta del desarrollador android , arreglé 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"); } }
Obtener información de todos los usuarios podría resolver mi situación de esta manera. Todos tenían razón, con pequeños puntos a notar:
En 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 para Android (2.3 Gingerbread) no pude usar MY_PACKAGE_REPLACED pero resolvimos usando PACKAGE_REPLACED (te aconsejaré que cualquier aplicación haya sido reemplazada) pero preguntando si es la nuestra con:
if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName())) { }
Gracias a todos
Sólo quiero añadir mi propio valor de dos peniques aquí, porque tuve problemas para conseguir esto para trabajar y depurarlo .. Estoy usando un dispositivo Lollipop:
Este es el código que usé:
<receiver android:name=".services.OnUpdateReceiver"> <intent-filter> <action android:name="android.intent.action.MY_PACKAGE_REPLACED" /> </intent-filter> </receiver>
Para depurarlo, debes asegurarte de haber instalado la actualización en tu teléfono, solo a través de Eclipse debug está bien, y abrió la aplicación al menos una vez, entonces simplemente puedes editar tu configuración de depuración:
eclipse > run > debug configurations > launch action (do nothing) > then F11 like normal
He confirmado que funcionó escribiendo un pequeño archivo en la tarjeta SD
¿Lo estás probando en una API> = 12 dispositivo / emulador? Esta transmisión no será enviada en casos anteriores, ya que es API 12. Si necesita que su aplicación reciba esta información para Pre-ICS y los viejos dispositivos de peine de miel,
tratar:
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) { if (!intent.getData().getSchemeSpecificPart() .equals(context.getPackageName())) { return; } }
Manifiesto sencillo trabajando 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>
Es necesario agregar un esquema de datos al filtro de intenciones 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>