studio programacion herramientas fundamentos con avanzado aplicaciones android android-intent android-service android-handler

programacion - manual de android en pdf



Cómo llamar a un método en actividad desde un servicio (4)

Asumiendo que su Servicio y Actividad están en el mismo paquete (es decir, la misma aplicación), puede usar LocalBroadcastManager de la siguiente manera:

En su Servicio:

// Send an Intent with an action named "my-event". private void sendMessage() { Intent intent = new Intent("my-event"); // add data intent.putExtra("message", "data"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); }

En tu actividad:

@Override public void onResume() { super.onResume(); // Register mMessageReceiver to receive messages. LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("my-event")); } // handler for received Intents for the "my-event" event private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Extract data included in the Intent String message = intent.getStringExtra("message"); Log.d("receiver", "Got message: " + message); } }; @Override protected void onPause() { // Unregister since the activity is not visible LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); super.onPause(); }

De la sección 7.3 del enlace de @ Ascorbin: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager

Hay un servicio que escucha algo de voz. Si la voz coincide con una cadena, se invoca un determinado método en el objeto de servicio.

public class SpeechActivationService extends Service { public static Intent makeStartServiceIntent(Context pContext){ return new Intent(pContext, SpeechActivationService.class); } //... public void onMatch(){ Log.d(TAG, "voice matches word"); } //... }

Así es como comienzo el servicio en mi actividad:

Intent i = SpeechActivationService.makeStartServiceIntent(this); startService(i);

A partir de este método de servicio, ¿cómo puedo invocar un método que reside en el objeto de actividad? No quiero acceso de actividad a servicio, sino de servicio a actividad. Ya leí sobre manejadores y locutores, pero no pude encontrar ni entender ningún ejemplo. ¿Algunas ideas?


Después de algunas investigaciones encontré los siguientes tiempos en mi caso para enviar y recibir la transmisión. Tengo servicio en el mismo proceso.

sendBroadcast (No recomendado si ambos componentes están en el mismo proceso) 34 sec

LocalBroadcastManager.getInstance (this) .sendBroadcast (intento); cerca de 30 segundos

La implementación usando AIDL y RemoteCallbackList funcionará para el mismo proceso o proceso diferente

En tu servicio

public final RemoteCallbackList<ICallBackAidl> mDMCallbacks = new RemoteCallbackList<ICallBackAidl>(); public void registerDMCallback(ICallBackAidl cb) { Logger.d(LOG_TAG, "registerDMCallback " + cb); if (cb != null) mDMCallbacks.register(cb); }

Cuando necesita métodos de llamada en Application / Acitvity desde el servicio

public void callMehodsInApplication() { final int N = mDMCallbacks.beginBroadcast(); for (int i = 0; i < N; i++) { try { mDMCallbacks.getBroadcastItem(i).method1(); } catch (RemoteException e) { e.printStackTrace(); } } mDMCallbacks.finishBroadcast(); }

En su clase se extiende la Aplicación o Actividad.

private ISyncmlServiceDMCallback mCallback = new ISyncmlServiceDMCallback.Stub() { // Implement callback methods here public void method1() { // Service can call this method } } public void onServiceConnected(ComponentName name, IBinder service) { svc.LocalBinder binder = (svc.LocalBinder) service; mSvc = binder.getService(); mSvc.registerDMCallback(mCallback); }

Llamar de esta manera es casi instantáneo desde la transmisión y recepción desde el mismo proceso


Hay muchas formas diferentes de lograr esto. Uno de ellos para usar las clases de Handler y Messanger . La idea del método es pasar el objeto Handler de Activity to Service . Cada vez que el Service quiere llamar a algún método de la Activity , simplemente envía un Message y la Activity maneja de alguna manera.

Actividad:

public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { showToast(msg.what); } }; final Intent intent = new Intent(this, MyService.class); final Messenger messenger = new Messenger(handler); intent.putExtra("messenger", messenger); startService(intent); } private void showToast(int messageId) { Toast.makeText(this, "Message " + messageId, Toast.LENGTH_SHORT).show(); } }

Servicio:

public class MyService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { final Messenger messenger = (Messenger) intent.getParcelableExtra("messenger"); final Message message = Message.obtain(null, 1234); try { messenger.send(message); } catch (RemoteException exception) { exception.printStackTrace(); } } return START_NOT_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } }