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;
}
}
Registraría un BroadcastReceiver en la Actividad y le enviaría un Intento desde el servicio. Vea este tutorial: http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html Puede parecer un poco largo, pero querrá aprender a usarlos de todos modos;)