android - servicios - receive_boot_completed
BOOT_COMPLETED de Android no se recibió cuando la aplicación está cerrada (8)
Soy consciente de que esta pregunta se ha planteado mucho en el sitio, sin embargo, no puedo encontrar una solución. No se llama a mi receptor BOOT_COMPLETED cuando la aplicación no se está ejecutando.
Manifiesto:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.startuptest"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.startuptest.MainActivity"
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="com.example.startuptest.StartUpBootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
StartUpBootReceiver:
public class StartUpBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("startuptest", "StartUpBootReceiver " + intent.getAction());
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
}
}
}
Si la aplicación se está ejecutando y simulo una llamada con
adb shell
am broadcast -a android.intent.action.BOOT_COMPLETED
El evento se recibe correctamente, sin embargo, si la aplicación se cierra, el evento no se recibe, ni se recibe al inicio.
He instalado la aplicación y luego la inicié un par de veces para asegurarme de que esté registrada. Estoy bastante perdido en este caso por lo que cualquier consejo sería muy apreciado.
Edición: Puedo ver en los registros que todas las demás aplicaciones cerradas (Youtube, FileObserver, etc.) reciben el evento boot_completed, pero no el mío.
Si desea saber el motivo real por el que BOOT_COMPLETE no funciona o no está recibiendo. Te sugeriré que vayas al sitio oficial de desarrollo de Android. Han explicado con la solución exacta.
A partir de Android 3.1, todas las aplicaciones, luego de la instalación, se colocan en un estado " detenido " (este es el mismo estado en el que la aplicación termina después de que el usuario detiene la aplicación desde la aplicación Configuración).
Mientras se encuentre en el estado "detenido", la aplicación no se ejecutará por ningún motivo , excepto mediante el inicio manual de una actividad. ( ACTION_PACKAGE_INSTALLED
significa que no se ACTION_PACKAGE_INSTALLED
BroadcastReceviers
( ACTION_PACKAGE_INSTALLED
, ACTION_PACKAGE_INSTALLED
, etc.), independientemente del evento para el que se hayan registrado, hasta que el usuario ejecute la aplicación manualmente .)
Este es un movimiento anti-malware de Google. Google ha recomendado que los usuarios inicien una actividad desde el iniciador primero, antes de que la aplicación pueda hacer mucho. Evitar que BOOT_COMPLETED
se entregue hasta que se inicie la actividad es una consecuencia lógica de ese argumento.
Más detalles sobre esto:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
http://commonsware.com/blog/2011/07/05/boot-completed-regression.html
http://devmaze.wordpress.com/2011/12/05/activating-applications/
Básicamente necesitas las banderas de android: enabled = "true" android: export = = true "en el manifiesto para recibir la transmisión.
<receiver android:name=".bootReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
Cada respuesta aquí agrega una pequeña parte de información, así que aquí está el resumen de todo:
Para asegurarse de que recibirá el BOOT_COMPLETED, asegúrese de hacer lo siguiente:
Añade tu receptor al manifiesto (no olvides las flags ):
<receiver android:name="com.yourpacakge.BootReceiver" android:exported="true" android:enabled="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </receiver>
Añadir permiso:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Después de instalar su aplicación, debe ser almorzada al menos una vez, manualmente por el usuario, para recibir el evento Boot complete ( Más detalles )
Comienzo mi aplicación cuando BOOT_COMPLETED, así que sé que está funcionando. Agrego Log.d
no se mostrará. Añado Toast
lo que muestro. Diferentes pequeños en Manifest.xml
<receiver android:name="com.example.startuptest.StartUpBootReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Heres una versión de C # si ustedes lo quieren. Mis pruebas muestran que funciona bastante bien y la puesta en marcha es bastante rápida. Aunque tenga en cuenta que agregarlo tanto en C # como en AndroidManifest.xml lo rompe (al menos para mí).
También he agregado algunos ejemplos agradables y útiles que deseé haber descubierto de alguien en lugar de aprenderlo yo mismo al leer los documentales y demás.
[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true, Name = "com.nevaran.startup.StartUpBootReceiver")]
[IntentFilter(new string[] {
Intent.ActionBootCompleted
, Intent.ActionLockedBootCompleted
, Intent.ActionMyPackageReplaced
, Intent.ActionUserInitialize
, "android.intent.action.QUICKBOOT_POWERON"
, "com.htc.intent.action.QUICKBOOT_POWERON"
})]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if( intent.Action.Equals(Intent.ActionBootCompleted)
|| intent.Action.Equals(Intent.ActionLockedBootCompleted)
|| intent.Action.Equals(Intent.ActionUserInitialize)
|| intent.Action.Equals("android.intent.action.QUICKBOOT_POWERON")
|| intent.Action.Equals("com.htc.intent.action.QUICKBOOT_POWERON")
)
{
//run code here only if its started by the chosen actions
}
//some code that doesnt care about which action is triggered by
}
}
Para resolver este problema, puede usar firebaseJobDispatcher para invocar automáticamente, firebaseJobDispatcher tendrá un código para reactivar sus servicios, sí, después de un cierto tiempo, el sistema operativo puede detener los servicios, pero su firebaseJobDispatcher volverá a reactivarlos. FirebaseJobDispatcher tiene muchas propiedades desde donde puede definir el alcance de esto;
cómo funciona, para más detalles https://github.com/firebase/firebase-jobdispatcher-android
estaba luchando con el mismo problema, la razón es que está utilizando Log.d para rastrear su aplicación en logcat, desafortunadamente cuando reinicia su teléfono la aplicación está recibiendo BOOT_Complete pero no puede verla porque no está logueando en logcat.
intente hacer un Toast
con algún texto en lugar de Log.d
para asegurarse de que BOOT_COMPLETED se reciba o no.
espero que esto ayude.