Androidアプリ開発

非推奨のgetRunningservicesの対応

Androidアプリ開発
この記事は約12分で読めます。

こんにちは、まっさん(@Tera_Msaki)です。

この記事はAndroidスマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Javaでの開発経験、XML構文規則、Androidのアプリ開発経験がある方を対象としています。
Androidのアプリ開発でお役にたててれば、嬉しいです。
(これからAndroidのアプリ開発やJavaでの開発を始めたい方への案内は、記事の最後で紹介します)

◎テーマ
アプリから起動したサービスが動作しているか確認にしたい

◎ポイント

Android Oreo(API 26)以降では、getRunningservices(ActivityManager)が使用できなくなったため、アプリから起動したサービスが動作しているかどうか確認するには、アプリで確認する仕組みを実装する必要があります。

◎対応前(getRunningservicesを使用した実装)

	:
    ActivityManager activitymanager = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
    List<RunningServiceInfo> listServiceInfo = activitymanager.getRunningServices(Integer.MAX_VALUE);
    Boolean execure = false;
    for (RunningServiceInfo runningServiceInfo : listServiceInfo) {
        if (runningServiceInfo .service.getClassName().equals(LoggingService.class.getName())) {
		           //アプリから起動したサービスが動作している
		           :
		           execute = true;
		           break;
      }
    }
	:

getRunningservices(ActivityManager)を使用して、起動してるサービス一覧を取得する
取得したサービス一覧にアプリから起動したサービス名が存在するか確認する。

◎対応後 サービス側(LoggingService.java)

    private LocalBroadcastManager   localBroadcastManager;
	:

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
	:

        //サービス通信用レシーバーセット
        localBroadcastManager = LocalBroadcastManager.getInstance(context);
    }
	:
        handler = new Handler(Looper.getMainLooper());
        runnable = new Runnable() {
            @Override
            public void run() {
	:

                    //通知
                    intent = new Intent();
                    intent.setAction("SEND_MESSAGE");
                    intent.putExtra("MEASURE_SWITCH", String.valueOf(true));
                    localBroadcastManager.sendBroadcast(intent);
                }
                //ロギング取得間隔(ミリ秒)
                handler.postDelayed(this, INTERVAL);
            }
        };
        handler.post(runnable);
    }
	:

サービス側はLocalBroadcastManagerを作成する。
intentに通知メッセージセットし、LocalBroadcastManagerを使用して起動したアプリに通知用メッセージを送信(sendBroadcast)する。
intentには通知メッセージを識別するアクション(SEND_MESSAGE)をセットする。
intentを定期的に送信することで、アプリ側はサービスが動作していることが確認できるようになる。

また、intentにアプリ側に連携するデータを追加することで、サービス→アプリ間でデータの引き渡しが可能となる。

◎対応後 サービス側(LoggingService.java)

    private BroadcastReceiver           broadcastReceiver;
    private LocalBroadcastManager       localBroadcastManager;
	:
    @Override
    protected void onResume() {
        super.onResume();
        context = getApplicationContext();
        //ボタン( REC <-> STOP )
        recording = findViewById(R.id.recording);
        recording.setVisibility(View.VISIBLE);
        recording.setOnClickListener(v -> {
            recording.setVisibility(View.INVISIBLE);
            Intent intent = new Intent(getApplication(), LoggingService.class);
            if (recording.getText().equals(context.getString(R.string.recording))) {
                startForegroundService(intent);
	:
            } else {
                stopSrvice(intent);
	:
            }
        });
	:
        //サービス通信用レシーバ設定
        if (broadcastReceiver == null) {
            broadcastReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (recording.getText().equals(context.getString(R.string.recording))) {
                        //LoggingService起動中のため、stopボタンに変更
                        recording.setText(R.string.stop);
                        recording.setVisibility(View.VISIBLE);
                    }
                    boolean measure_switch = Boolean.parseBoolean(intent.getStringExtra("MEASURE_SWITCH"));
		:
                }
            };
        }
        localBroadcastManager = LocalBroadcastManager.getInstance(context);
        final IntentFilter filter = new IntentFilter();
        filter.addAction("SEND_MESSAGE");
        localBroadcastManager.registerReceiver(broadcastReceiver, filter);
	:
   @Override
    protected void onDestroy() {
        //サービス通信用レシーバ解除
        localBroadcastManager.unregisterReceiver(broadcastReceiver);
	:
        super.onDestroy();
    }

画面上のRECボタンをクリックすることでサービスを起動(startForegroundService)する。
サービス起動中は、ボタンを非表示にすることで重複起動を禁止する。
アプリ側もLocalBroadcastManagerを作成。
通知メッセージを識別するためのIntentFilterをセットし、サービス通信用レシーバ(BroadcastReceiver)を登録(registerReceiver)する。
サービスからの通知メッセージは、サービス通信用レシーバ経由で受信する。
起動したサービスが動作しているかは、サービスからの通知メッセージの有無で判断し、通知メッセージが受信できたら、サービス起動時に非表示にしたボタンを表示する(STOPボタンに変更)
アプリ終了時にはサービス通信用レシーバを解除(unregisterReceiver)する。

ブログランキング・にほんブログ村へにほんブログ村

◎これからAndroidのアプリ開発やJavaでの開発を始めたい方へ

初めてのAndroidのアプリ開発では、アプリケーション開発経験がない方や、
アプリケーション開発経験がある方でも、JavaやC#などのオブジェクト指向言語が初めての方は、
書籍などによる独学ではアプリ開発できるようになるには、
かなりの時間がかかりますので、オンラインスクールでの習得をおススメします。

コメント

タイトルとURLをコピーしました