«

»

nov 14 2012

Android Services (2/4) – BroadcastReceiver

Buenas a todos, seguimos con esta tanda de tutoriales dedicados a Services. En este tutorial aprenderemos qué es un BroadcastReceiver en Android y su uso. Espero que os sirva :)

 

 

¿Qué es un BroadcastReceiver?

Un BroadcastReceiver es un componente Android que permite el registro de eventos del sistema.
Todos los Receivers registrados para un evento serán notificados por Android una vez que éstos ocurran.
Por ejemplo, Android permite que aplicaciones puedan registrarse al ACTION_BOOT_COMPLETED que es un evento que lanza el sistema una vez que ha completado el proceso de arranque.
 

Implementación

Un BroadcastReceiver extiende de la clase BroadcastReceiver y es registrado como un receptor en una aplicación a través del fichero AndroidManifest.xml

Alternativamente a este tipo de registro, podemos registrar un BroadcastReceiver dinámicamente a través del método Context.registerReceiver()
Si el evento para el que el BroadcastReceiver recibe BroadcastIntents desde el sistema Android entonces usamos el método onReceive()

 

Envío de Broadcast Intents

El método sendBroadcast() permite enviar BroadcastIntents. No se pueden desencadenar emisiones del sistema, el sistema Android evitará esto.
Pero sí podemos definir intent-filters para nuestras propias acciones y hacerlas funcionar desde el método sendBroadcast().
El siguiente ejemplo de AndroidManifest.xml muestra un BroadcastReceiver que es registrado para una acción customizada.
 

         <?xml version="1.0" encoding="utf-8"?>
         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
	     package="es.androcode.android.receiver.own"
	     android:versionCode="1"
	     android:versionName="1.0">
	     <uses-sdk android:minSdkVersion="15" />
	     <application
	        android:icon="@drawable/ic_launcher"
	        android:label="@string/app_name">
	        <activity
		   android:name=".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="MyReceiver">
		  <intent-filter>
			 <action android:name="es.androcode.android.mybroadcast"/>
		  </intent-filter>
	       </receiver>
             </application>
         </manifest>				
         

 

Podemos disparar el evento desde el método sendBroadcast()

 

          Intent intent = new Intent();
          intent.setAction("es.androcode.android.mybroadcast");
          sendBroadcast(intent);
        

 

Ejecución de largas operaciones

Después de que el método onReceive() del BroadcastReceiver ha acabado, el sistema Android puede reciclarlo.Por lo tanto no se puede realizar ninguna operación asíncrona con el método onReceive(). Si tenemos largas operaciones deberíamos lanzar un Service para eso.
 

Restricciones para definir BroadcastReceiver

A partir de la versión Android 3.1 el sistema Android por defecto excluye todo BroadcastReceiver de recibir Intent si la correspondiente aplicación nunca ha sido iniciada por el usuario o si el usuario explícitamente detuvo la aplicación desde el menu Android.
Esta es una característica de seguridad adicional ya que el usuario puede estar seguro de que sólo las aplicaciones que él empezó recibirá broadcast Intents.
 

Sticky Broadcast Intents

Un BroadcastIntent básico no está disponible nunca más después que fué enviado y procesado por el sistema. Si usamos el método sendStickyBroadcast(Intent), el Intent es sticky, que significa que el Intent que hemos enviado se mantiene después que que la emisión se ha completado.
Podemos recuperar los datos a través del valor de retorno de registerReceiver(BroadcastReceiver, IntentFilter). Esto trabaja también para un BroadcastReceiver nulo. En todos los demás aspectos, se comporta igual que sendBroadcast(Intent).
 

El sistema Android usa sticky broadcast para cierta información del sistema. Como para el estado de la batería que se envia un sticky Intent y puede recibirse en cualquier momento.

El siguiente ejemplo lo demuestra:
 

               //Registro para el evento del cambio en la bateria
               IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);

               //Intent es sticky, así que si usamos null como receiver funcionará bien
               //devuelve el valor que contiene el estado.
               Intent batteryStatus = this.registerReceiver(null, filter);

               //¿Está cargándose o está cargado?
               int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
               boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING 
	         || status == BatteryManager.BATTERY_STATUS_FULL;
               boolean isFull = status == BatteryManager.BATTERY_STATUS_FULL;

               //¿Cómo se está cargando?
               int chargePlug = batteryStatus.getIntentExtra(BatteryManager.EXTRA_PLUGGED, -1);
               boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
               boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 
              

 

System broadcasts

Varios eventos del sistema son definidos como campos final statics en la clase Intent. Otras clases del sistema Android también definen eventos como el TelephonyManager que define eventos para el cambio del estado del teléfono.
La siguiente tabla lista algunos eventos importantes del sistema.

 

Evento Descripción
Intent.ACTION_BOOT_COMPLETED Arranque completado. Requiere el permiso android.permission.RECEIVE_BOOT_COMPLETED.
Intent.ACTION_POWER_CONNECTED Cargador de energía conectado al dispositivo.
Intent.ACTION_POWER_DISCONNECTED Cargador de energía desconectado del dispositivo.
Intent.ACTION_BATTERY_LOW La batería se está agotando, normalmente se usa para reducir que las activities en la aplicación que consumen más batería.
Intent.ACTION_BATTERY_OKAY La batería está correcta de nuevo.

 

Pending Intent

Un PendingIntent es un token que damos a otra aplicación (Por ejemplo, Notification Manager, Alarm Manager u otra aplicación), que permite a esta otra aplicación usar los permisos de nuestra aplicación para ejecutar trozos de códigos predefinidos.
Para realizar una transmisión desde un PendingIntent y obtener un PendingIntent usamos PendingIntent.getBroadcast().
Para realizar una actividad desde un pending intent recibimos la actividad a través de PendingIntent.getActivity().
 

Definiremos un BroadcastReceiver que liste los cambios de estado del teléfono. Si el teléfono recibe una llamada, entonces nuestro receptor o receiver será notificado y anota un mensaje.

Creamos un nuevo proyecto es.androcode.android.receiver.phone. Creamos una Activity ficticia ya que esto es necesario para que el BroadcastReceiver también se active. Creamos el siguiente fichero AndroidManifest.xml

 

          <?xml version="1.0" encoding="utf-8" ?>
          <manifest xmlns:android="http://schemas.android.com/apk/res/android"
	   package="es.androcode.android.receiver.phone"
	   android:versionCode="1"
           android:versionName="1.0"

	   <uses-sdk android:minSdkVersion="15"/>
	   <uses-permission android:name="android.permission.READ_PHONE_STATE">
	   </uses-permission>
	
	   <application
	      android:icon="@drawable/icon"
	      android:label="@string/app_name"
		<activity
		     android:name=".MainActivity"
		     android:label="@string/title_activity_main">
		     <intent-filter>
			<action android:name="android.intent.action.MAIN" />
			<category android:name="android.intent.category.LAUNCHER"/>
		     </intent-filter>
		</activity>
		<receiver android:name="MyPhoneReceiver"
			<intent-filter>
				<action android:name="android.intent.action.PHONE_STATE">
				</action>
			</intent-filter>
		</receiver>
         </application>
      </manifest>
     

 

Creamos la clase MyPhoneReceiver
 

       package es.androcode.android.receiver.phone;

       import android.content.BroadcastReceiver; 
       import android.content.Context;
       import android.content.Intent;
       import android.os.Bundle;
       import android.telephony.TelephonyManager;
       import android.util.Log;

       public class MyPhoneReceiver extends BroadcastReceiver{

           public void onReceive(Context context,Intent intent){
	    Bundle extras = intent.getExtras();
	    if(extras != null){
		String state = extras.getString(TelephonyManager.EXTRA_STATE);
		Log.w("DEBUG", state);
		if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
		String phoneNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
		Log.w("DEBUG", phoneNumber);
	     }	
	   }	
       }
     }
    

 

Ahora instala tu aplicación y simula una llamada de teléfono desde la perspectiva DDMS de Eclipse. Nuestro receiver es llamado y se registra un mensaje en la consola. :)

 

System Services y BroadcastReceiver

Ahora vamos a programar un BroadcastReceiver desde un AlertManager. Una vez que se llame usaremos el VibratorManager y un Toast para notificar al usuario.

Creamos un nuevo proyecto, en este caso “es.androcode.android.alarm” con la Activity “AlarmActivity”. Creamos el siguiente layout

 

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	    android:layout_width="match_parent"
	    android:layout_height="match_parent"
	    android:orientation="vertical">
	    <EditText
	        android:id="@+id/time"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"	
	        android:hint="@string/Segundos"
	        android:inputType="numberDecimal">
	    </EditText>
	    <Button
	        android:id="@+id/ok"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:onClick="startAlert"
	        android:text="@startCounter">
	    </Button>
         </LinearLayout>
     

 

Ahora creamos la siguiente clase broadcast receiver. Esta clase obtendrá el servicio del vibrador del dispositivo.
 

        package es.androcode.android.alarm;

        import android.content.BroadcastReceiver;
        import android.content.Context; 
        import android.content.Intent;
        import android.os.Vibrator;
        import android.widget.Toast;

        public class MyBroadcastReceiver extends BroadcastReceiver{
	       public void onReceive(Context context, Intent intent){
		    Toast.makeText(context,R.string.timeup, Toast.LENGTH_LONG).show();
		    //El vibrador del dispositivo
		    Vibrator vibrator =(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
		    vibrator.vibrate(2000);	
	        }
         }
       

 

El AndroidManifest se nos quedaría como sigue:
 

       <?xml version="1.0" encoding="utf-8" ?>
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
	    package="es.androcode.android.alarm"
	    android:versionCode="1"
	    android:versionName="1.0">
	  <uses-sdk android:minSdkVersion="15"/>
	  <uses-permission android:name="android.permission.VIBRATE">
	  </uses-permission>

	  <application
		android:icon="@drawable/icon"
		android:label="@string/app_name"
		<activity
		    android:name=".AlarmActivity"
		    android:label="@string/app_name">
		    <intent-filter>
			<action android:name="android.intent.action.MAIN"/>
			<category android:name="android.intent.category".LAUNCHER />
		    </intent-filter>
		</activity>
	 </application>
      </manifest>	
      

 

Ahora cambiamos el código de nuestro AlarmActivity al siguiente. Esta Activity creará un Intent para el Broadcast receiver y obtiene el servicio AlarmManager
 

        package es.androcode.android.alarm;
        import android.app.Activity;
        import android.app.AlarmManager;
        import android.app.PendingIntent;
        import android.content.Intent;
        import android.os.Bundle;
        import android.view.View;
        import android.widget.EditText;
        import android.widget.Toast;

         public class AlarmActivity extends Activity{
	
        	public void onCreate(Bundle savedInstanceState){
		         super.onCreate(savedInstanceState);
		         setContentView(R.layout.main);	
	         }
	
	        public void startAlert(View view){
		        EditText text=(EditText)findViewById(R.id.time);
		        int i = Integer.parseInt(text.getText().toString());
		        Intent intent = new Intent(this,MyBroadcastReceiver.class);
		        PendingIntent pendingIntent =                                     
                             PendingIntent.getBroadcast(this.getApplicationContext(),234324243, intent, 0);
          		AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
	         	alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(i*1000),        
                                 pendingIntent);
	         	Toast.makeText(this,"Alarma puesta en "+i+" segundos", Toast.LENGTH_LONG).show();	
	         }
        }
     

 

Ahora ejecuta la aplicación en el dispositvo. Selecciona los segundos e inicia la hora. Tras la cuenta atrás, aparecerá un Toast para avisarnos.
Ten en cuenta que el vibrador del movil no funciona en el emulador.
 
En el siguiente post explicaremos cómo crear un propio Service con BroadcastReceiver.
Un saludo!

 
Fuente | http://www.vogella.com

 

Espero que os haya gustado y si es así no lo dudéis y ¡¡compartid lo aprendido!!

 

Acerca del autor

InmaculadaAlcon

Me entusiasma aprender y desarrollar software de calidad. Crear aplicaciones para Android es lo que más me gusta y por lo que me muevo cada día. Soy muy flamenca, enamorada de Sevilla y con el sueño de trabajar algún día en Silicon Valley. Me encanta el fútbol y soy del Betis manque pierda.

  • http://desandroid.com DesAndrOId

    Como ya te he dicho via Twitter, Good Job, las dos entradas son muy interesantes de verdad, las necesitaba.

    En esta segunda has hablado de los Broadcast de tipo Sticky, que sinceramente yo ni los conocía, pero me surgen algunas dudas al respecto.

    1º. – Únicamente te retornan el valor una vez, o están actualizando continuamente el Intent, de tal manera que podría tener un AlarmService mirando el Intent.

    2º.- Este proceso cuando para, no es necesario hacer un unregisterReciber???.

    Por otro lado, quiero hablarte del LocalBroadcastManager, que no se si estará presente en lo sucesivos post, pero es muy interesante.

    ENHORABUENA

    • http://www.linkedin.com/in/inmaculadaalcon InmaculadaAlcon

      Hola!! Gracias por leernos y porque te guste :)
      Los Broadcast sticky, retornan el valor cada vez que haces una llamada para saber el valor. Osea, que son permanentes.
      No existen según mis conocimientos ningún unregisterReceiver, pero si que existe removeStickyBroadcast(Intent i) que elimina los datos que enviamos previamente con el sendStickybroadcast, y esto hace como si la emisión del sticky nunca hubiese ocurrido.

      Por lo que 1. Puedes obtener el valor cuando lo necesites(son permanentes) y no hay unregister.(que yo sepa, si averiguas comentame :))

      LocalBroadcastManager, puede que lo veas pronto también :)

      Muchas gracias por el comentario y espero que sigas leyéndonos, que me ha dado mucha alegría ver el tweet esta mañana :)
      Un saludo!
      @inmaculadaalcon

      • http://desandroid.com DesAndrOId

        Muchas gracias por tu respuesta,

        Pero me siguen surgiendo algunas dudas, está claro que tendré que probarlo.

        XD

  • Santidoo

    Antes de nada, felicitarte por esos increible y utiles tutoriales sobre Services y Broadcast!!
    Te queria preguntar una “aclaracion” o dudilla que me surge. En el ejemplo para crear un BroadcastReceiver desde un AlertManager, no hace falta que declares el en el Manifest.xml para dicho broadcastReceiver?
    Lo he probado en Eclipse, y si no declaras dicho receiver, no se ejecutará el broadcastreceiver creado, es decir, mostrar un Toast y vibrar el movil. Me estoy perdiendo algo?
    Al añadir dicho receiver al Manifest funciona perfectamente
    Una vez, muchisimas gracias por estos tutos =D

    • http://www.linkedin.com/in/inmaculadaalcon InmaculadaAlcon

      Hola! Antes que nada Santidoo gracias por las felicitaciones, simplemente intento plasmar un poco de sapiencia android, que no es que tenga mucha pero aquí estamos para aprender a diario.
      A ver, tienes toda la razón del mundo, el manifest debe contener el receiver, sino no va. Vaya tela, esto de no hacer un copy paste, sino de escribir directamente es lo que tiene. Un errorcito, te paso a continuación como debería quedar el Manifest propiamente y disculpa las molestias.
      También podría decir que es un truco para que la gente lo intente y así sepa yo si lo intentais o no, pero no jajaja en este caso mea culpa, asi que nada, aquí te lo dejo:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
         <?xml version="1.0" encoding="utf-8" ?>
        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="es.androcode.android.alarm"
         android:versionCode="1"
         android:versionName="1.0">
       <uses-sdk android:minSdkVersion="15"/>
       <uses-permission android:name="android.permission.VIBRATE">
       </uses-permission>
       
       <application
         android:icon="@drawable/icon"
         android:label="@string/app_name"
         <activity
             android:name=".AlarmActivity"
             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="MyBroadcastReceiver" >
              </receiver>
      </application>
       </manifest>

      Espero que te haya servido y si surge otra dudita, no dudes en ponerte en contacto conmigo.
      Un saludo! :)

  • http://facilbusx.webnode.com.co/ Jackson

    hola…quiero decir que he comensado adesarrollar app en android y soy muy novato en el tema.. Pero este post sobre BroadcastReceiver realmente me resulta interesante. la pregunta es si al BroadcastReceiver tambien llegan los eventos lansados por RF Bluetooth?
    en especial cuando el Bluetooth rechasa un paquete porque noestaba dirigido a el. Y si de alguna manera se puede recuperar informacion sobre el paquete como remitente y el destinatario.

    • http://www.linkedin.com/in/inmaculadaalcon InmaculadaAlcon

      Hola Jackson,
      No es estrictamente necesario el uso de BroadcastReceiver para una conexión con Bluetooth,de hecho, yo no lo usaría, La API de Android nos provee de soporte de bluetooth, puedes ver más información justo aquí :

      Si no estaba dirigido el paquete hacia Bluetooth, ¿dónde lo quieres coger? Si el paquete se ha invalidado en el envío, el paquete se destruye, porque no llega a su lugar, de hecho, en comunicaciones un paquete ¿te refieres a una unidad de información mínima, o a un mensaje? Es diferente. Como ya te he dicho si el paquete no llega, un paquete como máximo lo envía un emisor 3 veces(me refiero a unidad mínima de información en comunicaciones) luego en el destino es cuando se juntan todos los paquetes y “lo ve” el receptor.
      No sé si te he ayudado, si tienes más dudas no dudes en ponerte en contacto con nosotros.
      Muchas gracias por seguirnos.
      Un saludo,
      InmaculadaAlcon

  • Jordi

    Hola y gracias por vuestro trabajo! ;-)

    Leyendo el artículo, el apartado de restricciones a partir de la version 3.1, me asalta la duda de ¿como se puede resolver esto a partir de esa versión? mi problema es que tengo dos proyectos, donde el principal abria el secundario (tareas en segundo plano) mediante un Broadcast Receiver, pero el secundario no es abierto nunca por el usuario y siempre debe de estar activo. El secundario simplemente se instala y tiene dos Broadcast Receiver, uno que lo activa cuando se inicia el sistema, y el otro desde la app principal.

    No se si me he explicado bien… :-P

  • http://gravatar.com/kiquetal kiquetal

    Gracias por los ejemplos!!, no sabrias cual es la forma correcta de enviar un broadcast, junto al action PHONE_STATE, para por ejemplo que el sistema de encargue las notificaciones, una vez que haya insertado en el call log?

  • http://www.networksolution.cl/ Christopher

    estimados :

    existe una forma de poder iniciar un servicio luego de detenido por ejemplo tengo mi app que lanza un servicio y que luego si yo detengo desde configuraciones del equipo este deberia autoiniciar nuevamente dejando este servicio permanentemente corriendo (ya tengo y funciona el tema que cuando apaga y enciende el teléfono este servicio se inicie)

  • Cristina Navarro

    Hola, tengo una app que utiliza un PendenIntent y el Broadcast , lo que hace esta app es programar alarmas para los días que se indican en un calendario, por ejemplo programo 4 alarmas para días y horas diferentes, y los dos primeros días, saltan el día que les correspoden y a la hora que tiene programada, pero cuando le toca saltar a la alarma del día 3 esta no salta
    Tengo lo siguiente :

    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    //Intent notificationIntent= new Intent(AlarmClock.ACTION_SET_ALARM);
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DAY_OF_MONTH, dia);
    cal.set(Calendar.MONTH, mes);
    cal.set(Calendar.YEAR, anno);

    cal.set(Calendar.HOUR_OF_DAY, hora);
    cal.set(Calendar.MINUTE, minuto);

    Intent notificationIntent = new Intent(MainActivity.this,Temporizador.class);
    notificationIntent.putExtra(“fechayhoramilsec”, cal.getTimeInMillis());
    notificationIntent.putExtra(“dia”, dia);
    notificationIntent.putExtra(“mes”, mes);
    notificationIntent.putExtra(“anno”, anno);
    notificationIntent.putExtra(“hora”, hora);
    notificationIntent.putExtra(“minuto”, minuto);
    notificationIntent.putExtra(“cantidad”, cantidad);
    PendingIntent pIntent=PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    int alarmType = AlarmManager.RTC_WAKEUP;
    long horaEnMilSec=cal.getTimeInMillis();
    alarmManager.set(alarmType, cal.getTimeInMillis(), pIntent );

    /////////////////////////////////////////////
    y el BroadcastReceiver:
    ////////////////////////////////////////////////
    int dia = (Integer) intent.getExtras().get(“dia”);
    int mes = (Integer) intent.getExtras().get(“mes”);
    int anno = (Integer) intent.getExtras().get(“anno”);
    int hora = (Integer) intent.getExtras().get(“hora”);
    int minuto = (Integer) intent.getExtras().get(“minuto”);
    String cantidad = (String) intent.getExtras().get(“cantidad”);

    int minutoAlarm = minuto;
    int horaAlarm = hora;

    if(minuto<57){
    minutoAlarm=minuto+3;

    }else{
    horaAlarm=hora++;
    minutoAlarm=0;

    }

    AlarmClock alarma;
    Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);

    i.putExtra(AlarmClock.EXTRA_MESSAGE, "El dia :" + dia + "/" + mes + "/"
    + anno + "a las " + hora + ":" + minuto + " tienes que tomar "
    + cantidad + " de sintron");
    i.putExtra(AlarmClock.ACTION_SET_ALARM, true);
    i.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    i.putExtra(AlarmClock.EXTRA_HOUR, horaAlarm);
    i.putExtra(AlarmClock.EXTRA_MINUTES, minutoAlarm);

    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    context.startActivity(i);
    ….
    …..

    HE PUESTO EL RETARDO DE 3 MIN. porque me di cuenta que sino la programa para la siguiente hora am/pm

    • Franki

      Hola cristinq navarro estoy haciendo una alarma una pequeña aplicacion sera q me puedas ayudar te lo agradeceria mucho soy muy nuevo en android

  • Ivan renato

    Saludos Inmaculada, encontre tus tutoriales buscando por ahi
    me parecen geniales y bien explicados. Bueno te molesto pues estoy desarrollando una app y tengo un pequeño problema con android 3.1 en adelante:

    te explico brevemente lo que deseo lograr.

    Mi aplicación funciona muy bien en android 1.5 hasta la versión 3.0.
    mi aplicación se inicia automáticamente cuando el sistema es reiniciado y inicia un BroadcastReceiver mediante los intents:

    Todo Bien hasta ahí el problema es que también deseo ocultar el laucher Icon y lo hago deshabilitando el paquete de la aplicación mediante una funcion que cree:

    private void hideLauncherIcon() {
    getPackageManager().setComponentEnabledSetting(LAUNCHER_COMPONENT_NAME,
    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
    PackageManager.DONT_KILL_APP);
    Log.e(“ocultar estado”, “Oculto”);
    }
    Todo bien hasta ahi, el icono se oculta al iniciar la app, el tema es que si reinicio la aplicación o la instalo nuevamente, la consola me manda el siguiente error:

    New package not yet registered with the system. Waiting 3 seconds before next attempt.
    ActivityManager: Error: Activity class {org.com.test/org.com.test.Launcher} does not exist.

    Lo cual indica que como el paquete fue deshabilitado, la aplicacion no puede iniciarse y se produce el fallo.

    Mi pregunta es ¿Como hago para ocultar el icono sin deshabilitar el paquete? o tal vez ¿como puedo indicar en el manifest que el al reiniciar el paquete se habilite nuevamente?

    porfavor ruego me ayudes con este problema llevo meses sin lograr un resultado satisfactorio.

    encontre una solución la cual implemente otro BroadcastReceiver el cual al detectar el instalado de la app habilita el paquete nuevamente y permite la reinstalacion pero no me funciona

    aquí el código:

    Add a broadcast receiver with intent filter action android.intent.action.PACKAGE_ADDED. In the onReceived method you must activate your disabled component :

    ComponentName componentToEnable = new ComponentName(context, Your_disabled_class.class);
    PackageManager pm = context.getPackageManager();
    pm.setComponentEnabledSetting(componentToEnable, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

    Espero tu respuesta si necesitas una compensación monetaria por la ayuda no hay problema pero hazmelo saber y muchas gracias por compartir tu conocimiento con la comunidad.

    Saludos

  • Rafael

    Hola buenas tardes mira yo quisiera recibir un correo y reenviarlo en forma de texto.Entonces lo que hago es un sistema de alertas detecta cuando una maquina esta conectada.Mi pregunta es es mejor usar un broadcast reciver?Ya que piodrìa yo usar llamadas al sistema para enviarle un boradcast al telefono y enviarlo por sms o me conviene mandar un correo y yo recibirlo desde el telefono y enviarlo?

  • alicia beltran

    Hola, gracias por el tutorial. Tengo una pregunta. Tengo que programar unas alarmas, que activen un servicio (consumo de web service), y posterior al consumo cree una notificación. Ya tengo la alarma q lanza el servicio, pero cada vez q abro la notificacion que “estoy creando” desde el servicio se re lanza cada vez que abro la notificacion. Quiero q la notificacion me envie a la actividad especifica q le he dicho, sin q me consuma de nuevo el servicio ni me cree una notificacion cada vez q abro la notificacion.

    Por lo visto tengo acoplado en el servicio la notificacion.

    Como programao las notificaciones y las alarmas sin que el se cree ese ciclo? Otro reciever.

    Gracias.

  • Daniel Contreras

    no me funciono el de mensajes ni me salio el toast de que alemenos recivio esta vibrando

  • Erick Sianquiz Flores

    Buenas una consulta yo uso un alarmanager + intent + reciever , pero porque a veces funciona la alarma y otras no.

  • charlene00