2011-04-11 16 views
40

trato de activar y desactivar un receptor de radiodifusión mediante el uso de este método PackageManager:Activar y desactivar un receptor de radiodifusión

setComponentEnabledSetting(componentName, 
     PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 
     PackageManager.DONT_KILL_APP); 

El receptor de radiodifusión se ha registrado en el manifiesto. El receptor funciona bien, pero cuando intento desactivarlo, todavía recibe los mensajes de difusión. Cuando desactivo el receptor en el manifiesto por "android: enabled =" false "", el receptor no recibe nada pero no puedo habilitarlo.

Llamo al método desde dentro de un servicio.

PackageManager pm = getApplicationContext().getPackageManager(); 
    ComponentName componentName = new ComponentName("com.app", 
      ".broadcast_receivers.OnNetworkChangedReceiver"); 
    pm.setComponentEnabledSetting(componentName, 
      PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 
      PackageManager.DONT_KILL_APP); 

manifiesto de Android:

<receiver android:name=".broadcast_receivers.OnNetworkChangedReceiver" 
       android:enabled="true"> 
      <intent-filter> 
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> 
      </intent-filter> 
    </receiver> 

El receptor

public class OnNetworkChangedReceiver extends BroadcastReceiver { 
private static final String TAG = "OnNetworkChangedReceiver"; 

@Override 
public void onReceive(Context context, Intent intent) { 
    Log.d(TAG, "in OnNetworkChanged"); 
    } 
} 

I también conocido como método del interior de una Actividad de ayer. Pensé que funcionaba, pero hoy ya nada funciona. ¿Podría ser que a veces hay una gran demora en la intención (android.net.conn.CONNECTIVITY_CHANGE) que malinterpreté ayer como desactivando el receptor?

¿El enfoque con el PackageManager es la dirección correcta o hay un error básico en la idea?

Muchas gracias, Sven

+0

Por cierto @Sven, su error inicial fue muy común. Su ComponentName necesario ("com.app", "com.app.broadcast_receivers.OnNetworkChangedReceiver"); Me doy cuenta de que esta solución se ve extraña, porque el nombre del paquete parece estar en la lista dos veces. Y desde el 'Nuevo Asistente de Android ...'Puede que solo le pida un solo nombre de paquete cuando crea un proyecto, es fácil pensar que solo hay uno, pero bajo las coberturas realmente toma esa cadena que le da y le asigna dos nombres diferentes de paquete, tanto el paquete de Aplicación nombre y también el nombre del paquete de actividad. –

+0

Usar '0' en lugar de' PackageManager.DONT_KILL_APP' también podría ayudarlo a deshacerse de la actividad, si estoy leyendo los documentos correctamente: http://developer.android.com/reference/android/content/pm/PackageManager .html en la sección 'SetComponentEnabledSetting'. –

Respuesta

71

Bueno, lo que tienes básicamente parece estar bien. Tengo el siguiente código en one of my projects:

boolean enabled=prefs.getBoolean(key, false); 
int flag=(enabled ? 
      PackageManager.COMPONENT_ENABLED_STATE_ENABLED : 
      PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 
ComponentName component=new ComponentName(EditPreferences.this, OnBootReceiver.class); 

getPackageManager() 
    .setComponentEnabledSetting(component, flag, 
           PackageManager.DONT_KILL_APP); 

que utilizarlo para desactivar un receptor BOOT_COMPLETED cuando no tengo las alarmas activas que necesitan ser programado.

Supongo que su ComponentName no está configurado correctamente (por ejemplo, su . principal). Pruebe el constructor que estoy usando, que toma un Context y un Class como parámetros.

+1

Muchas gracias por la respuesta rápida. Usé el constructor que usaste y ahora funciona. – Sven

+0

Digamos que tengo un Receptor de arranque: ¿valdría la pena deshabilitarlo justo antes de que regrese su 'onReceive'? ¿Se ejecutaría el próximo reinicio? –

+1

@Mr_and_Mrs_D: si está deshabilitado cuando el dispositivo se reinicia, no se invocará. – CommonsWare

4

Creo utilizando el PackageManager es sobre-pensar su situación. Usted tiene un BroadcastReceiver que a veces necesita ignorar las transmisiones que está escuchando. Puedo pensar en dos formas sencillas de hacerlo:

1) Establezca un indicador que su receptor pueda verificar para ignorar o aceptar transmisiones, y no se preocupe por habilitarlo o deshabilitarlo en absoluto.

2) Cree el BroadcastReceiver programáticamente (puede ser solo una clase interna, par), y regístrelo y anótelo como lo necesite en determinadas partes de su aplicación.

En general, he encontrado que la definición de mis BroadcastReceivers en código en lugar de XML me ha proporcionado mucha más flexibilidad y, en general, me resulta más fácil de administrar.

+9

Hay algunos tipos de emisiones (por ejemplo, 'BOOT_COMPLETED') que no se pueden registrar efectivamente a través de' registerReceiver() '. Además, la dependencia excesiva en 'registerReceiver()' te lleva a servicios eternos (servicios para mantener un receptor), lo que es malo. Deshabilitar el componente es una buena idea para la eficiencia, particularmente con las transmisiones populares del sistema, como 'BOOT_COMPLETED'. – CommonsWare

+1

Muy buenos puntos. Programmatic BroadcastReceivers requieren un registro/anulación del registro responsable para evitar servicios eternos. Como siempre, depende de la situación. – LeffelMania

Cuestiones relacionadas