Androidアプリ開発

非推奨のgetRunningservicesの対応

この記事は約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での開発を始めたい方へ

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

未経験者からシステムエンジニアを目指すのに最適かと、
まずは無料相談から♪

未経験者からプログラマーを目指すのに最適かと、
まずは無料カウンセリングから♪

カリキュラムとサポートがしっかりしています、
お得なキャンペーンとかいろいろやっています♪

ゲーム系に強いスクール、UnityやUnrealEngineを習得するのに最適かと、
まずは無料オンライン相談から♪

参考になったら、💛をポッチとしてね♪