una studio segundo programacion plano notificación notificaciones móviles mensajes maneja desarrollo curso app aplicaciones android android-service android-pendingintent

studio - notificaciones push android firebase



¿Cómo usar PendingIntent para comunicarse desde un servicio a un cliente/actividad? (3)

He estado leyendo el siguiente texto en el sitio de desarrolladores de Android, específicamente en los temas del marco -> Servicios -> Iniciar un servicio .

Allí dice lo siguiente:

Si el servicio no proporciona también enlace, la intención entregada con startService () es el único modo de comunicación entre el componente de la aplicación y el servicio. Sin embargo, si desea que el servicio devuelva un resultado, entonces el cliente que inicia el servicio puede crear un PendingIntent para una transmisión (con getBroadcast ()) y entregarlo al servicio en la Intención que inicia el servicio. El servicio puede usar la transmisión para entregar un resultado.

Tengo un par de preguntas sobre esto:

  1. ¿Este texto se aplica a los Service e IntentService ?
  2. ¿Cómo (en forma de código) se debe lograr esto dentro del Service ? El servicio puede usar la transmisión para entregar un resultado. y también, ¿dónde la transmisión mencionada entregaría el resultado al cliente / actividad original? ¿Hay algún método que deba sobrescribirse (como onActivityResult() ) o algo así?

Como esta escrito here

La comunicación entre el servicio y la Actividad se puede hacer usando PendingIntent. Para que podamos usar createPendingResult () .createPendingResult () crea un nuevo objeto PendingIntent que puede entregar al servicio para usar y enviar datos de resultados a su actividad en onActivityResult (int, int, Intent) devolución de llamada. Dado que un PendingIntent es Parcelable y, por lo tanto, se puede poner en un Intent extra, su actividad puede pasar este PendingIntent al servicio. El servicio, a su vez, puede llamar al método send () en el PendingIntent para notificar al Actividad a través de onActivityResult de un evento.

Actividad

public class PendingIntentActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PendingIntent pendingResult = createPendingResult( 100, new Intent(), 0); Intent intent = new Intent(getApplicationContext(), PendingIntentService.class); intent.putExtra("pendingIntent", pendingResult); startService(intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 100 && resultCode==200) { Toast.makeText(this,data.getStringExtra("name"),Toast.LENGTH_LONG).show(); } super.onActivityResult(requestCode, resultCode, data); } }

Servicio

public class PendingIntentService extends Service { private static final String[] items= { "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus" }; private PendingIntent data; @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { data = intent.getParcelableExtra("pendingIntent"); new LoadWordsThread().start(); return START_NOT_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); } class LoadWordsThread extends Thread { @Override public void run() { for (String item : items) { if (!isInterrupted()) { Intent result = new Intent(); result.putExtra("name", item); try { data.send(PendingIntentService.this,200,result); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } SystemClock.sleep(400); } } } } }




La pregunta se hizo hace unos meses, pero en caso de que alguien todavía esté buscando una respuesta, espero poder ayudar.

En el siguiente ejemplo tenemos servicio local, responsable de realizar algunas operaciones que requieren mucho tiempo. La actividad realiza las solicitudes al servicio, pero no se enlaza con él, solo envía el intento con la solicitud. Además, Actividad incluye la información de BroadcastReceiver que debe devolverse cuando se realiza el servicio con la tarea solicitada. La información es pasada por PendingIntent. El servicio maneja la tarea en un subproceso en segundo plano y cuando la tarea finaliza, el servicio transmite BroadcastReceiver con una respuesta.

1. Crear la subclase BroadcastReceiver:

public class DataBroadcastReceiver extends BroadcastReceiver { static Logger log = LoggerFactory.getLogger(DataRequestService.class); @Override public void onReceive(Context context, Intent intent) { log.info(" onReceive"); } }

Este receptor de difusión será notificado desde el servicio, cuando la tarea se realiza.

2. Crear servicio

public class DataRequestService extends Service { private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { log.info("handleMessage"); //... performing some time-consuming operation Bundle bundle = msg.getData(); PendingIntent receiver = bundle.getParcelable("receiver"); // Perform the operation associated with PendingIntent try { //you can attach data from the operation in the intent. Intent intent = new Intent(); Bundle b = new Bundle(); //b.putString("key", value); intent.putExtras(b); receiver.send(getApplicationContext(), status, intent); } catch (CanceledException e) { e.printStackTrace(); } } } @Override public void onStart(Intent intent, int startId) { Bundle bundle = intent.getExtras(); msg.setData(bundle); mServiceHandler.sendMessage(msg); }

Bueno, la parte más importante está en el método handleMessage (). El servicio simplemente hace la operación de transmisión para entregar resultados a Broadcast Receiver.

3. También debe registrar su receptor y servicio de difusión en Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ramps.servicetest" android:versionCode="1" android:versionName="1.0" > .... <service android:name=".service.DataRequestService" android:exported="false"/> <receiver android:name=".service.DataBroadcastReceiver"></receiver> </application> </manifest><br>

4. Y por último, realizar solicitud a su servicio de Actividad:

Intent serviceIntent = new Intent(context, DataRequestService.class); @Override public void onClick(View v) { //this is the intent that will be broadcasted by service. Intent broadcastReceiverIntent = new Intent(context, DataBroadcastReceiver.class); //create pending intent for broadcasting the DataBroadcastReceiver PendingIntent pi = PendingIntent.getBroadcast(context, 0, broadcastReceiverIntent, 0); Bundle bundle = new Bundle(); bundle.putParcelable("receiver", pi); //we want to start our service (for handling our time-consuming operation) Intent serviceIntent = new Intent(context, DataRequestService.class); serviceIntent.putExtras(bundle); context.startService(serviceIntent); }



5. Dar respuesta al cliente / actividad original .

Puede tener actividad abstracta desde la cual se extenderán todas sus actividades. Esta actividad abstracta puede registrarse / anularse automáticamente como oyente de respuesta en el receptor de difusión. No hay muchas opciones aquí en realidad, pero es importante que si mantiene referencias estáticas a su actividad, debe eliminar la referencia cuando se destruya la actividad.

Saludos,
Rampas