Il existe un service qui écoute une voix. Si la voix correspond à une chaîne, une certaine méthode est invoquée dans l'objet de service.
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");
}
//...
}
Voici comment je démarre le service dans mon activité:
Intent i = SpeechActivationService.makeStartServiceIntent(this);
startService(i);
À partir de cette méthode de service, comment puis-je appeler une méthode qui réside dans l'objet d'activité? Je ne veux pas l'accès de l'activité au service, mais du service à l'activité. J'ai déjà lu des informations sur les gestionnaires et les diffuseurs, mais je n'ai pu trouver/comprendre aucun exemple. Des idées?
Je voudrais enregistrer un BroadcastReceiver dans l'activité et lui envoyer une intention à partir du service. Voir ce tutoriel: http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html Cela peut sembler un peu long mais vous voudrez quand même apprendre à les utiliser;)
En supposant que votre service et votre activité sont dans le même package (c'est-à-dire la même application), vous pouvez utiliser LocalBroadcastManager comme suit:
À votre service:
// 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);
}
Dans votre activité:
@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 section 7.3 du lien @ Ascorbin: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager
Il existe de nombreuses façons d'y parvenir. L'un d'eux pour utiliser les classes Handler
et Messanger
. L'idée de la méthode est de passer l'objet Handler
de Activity
à Service
. Chaque fois que Service
veut appeler une méthode de Activity
, il envoie simplement un Message
et Activity
le gère d'une manière ou d'une autre.
Activité:
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();
}
}
Un service:
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;
}
}
Après quelques recherches, j'ai trouvé les horaires suivants dans mon cas pour l'envoi et la réception de l'émission. J'ai un service dans le même processus.
sendBroadcast (Non recommandé si les deux composants sont dans le même processus) 34 sec
LocalBroadcastManager.getInstance (this) .sendBroadcast (intention); près de 30 sec
Implémentation en utilisant AIDL et RemoteCallbackList fonctionnera pour le même processus ou un processus différent
A votre service
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);
}
Lorsque vous avez besoin de méthodes d'appel dans Application/Acitvity from service
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();
}
Dans votre classe, étendre l'application ou l'activité.
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);
}
Appeler de cette façon est presque instantané de la diffusion et de la réception du même processus