ServiceからActivityへ情報を渡す
実際には、直接叩く(アクセス)するのではなくて、カスタムしたレシーバーを使って行う方法について書きます。以下のコードを試すときは、ServiceクラスをManifestファイルに追記することをお忘れなく…。
動作確認したコードをコピペしたので、問題なく動作するはずです。
ポイントとしては…
- DO_ACTION、の文字列は、独自レシーバーの判別に使うものです。オリジナルで構いません。
- カスタムしたレシーバー(以下ではUpdateReceiver)は、別ファイルでも構いません。
- message、という文字列に紐付けて、文字列を渡すサンプルになっています。文字列に限らず、booleanやintなども渡せますが、その例は省きます。
- 本サンプルは、ボタンを押すと「こんにちは」をToastするだけですから、これ自体は単純にServiceに実装しても表面上は同じ動きをします。このサンプルのミソは、Service側でいろんな処理をしていて、ある条件+タイミングでActivity側にトリガーをかけたいときの手段の1つとして考えてもらえればいいと思います。
- 自分で書いているコードでは、Service側の動作状態をテキストファイルに書き込んでいるのですが、書き込んだらActivityに通知を出して(本サンプルの構造を利用)ListView内部のTextViewを更新する、ということをやっています。
Activity
Activity
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
Button btn = new Button(this);
btn.setText("start");
ll.addView(btn);
setContentView(ll);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent service = new Intent(getApplicationContext(), TestService.class);
startService(service);
}
});
// receiver
UpdateReceiver receiver = new UpdateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("DO_ACTION");
registerReceiver(receiver, filter);
}
protected class UpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
Bundle extras = intent.getExtras();
String msg = extras.getString("message");
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
}
}
Service
Service
NullableはAndroidStudioが自動で入れたものなので、気にしないでください。
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
public class TestService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
public int onStartCommand(Intent intent, int flags, int startId){
sendMessage("こんにちは");
stopSelf();
return START_NOT_STICKY;
}
protected void sendMessage(String msg){
Intent broadcast = new Intent();
broadcast.putExtra("message", msg);
broadcast.setAction("DO_ACTION");
getBaseContext().sendBroadcast(broadcast);
}
}