rokkonet

PC・Androidソフトウェア・アプリの開発・使い方に関するメモ

ForegroundServiceによるService実行 android開発

2020 Jul. 24.
2020 Jul. 03.
2020 Jun. 28.


参考元
https://androidmonks.com/foreground-service-in-android/
https://qiita.com/naoi/items/03e76d10948fe0d45597
http://www.gigas-jp.com/appnews/archives/6228
https://akira-watson.com/android/service.html

概要

・ActivityからServiceを呼び出す
・ServiceのonStrartCommand(){ }に下記を記述
  ・PendingIntentを生成
  ・PendingIntentを組み込んだNotificatoionを生成
  ・startForeground(ID, notification) // IDは1以上の整数
  ・サービスとして実行するコード
     コードの終了ポイントで
     stopForeground(true) もしくは stopSelf() でサービスを終了させる
  ・return START_NOT_STICKY / START_STICKY / START_REDELIVER_INTENT で
   onStrartCommand()を終える

アンドロイドバージョン対応

minSdkVersionが26(Version 8)未満の場合
Servicee呼び出しは startService(ServiceIntent)

minSdkVersionが26(Version 8)以上の場合
Servicee呼び出しは startForegroundService(serviceIntent)

ターゲットを28(Version 9)以上にする場合
AndroidManifest.xmlパーミッションを記述する

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>


ServiceのonStartCommand( )

ロック画面のノーティフィケーションをタップした時にIntentを発行するPendingIntentを生成する

val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent
        .getActivity(this, 0, notificationIntent, 0)

Notificationを生成する

val notification: Notification = NotificationCompat
        .Builder(this, "ChannelID")
        .setContentTitle(getText(R.string.notification_title))
        .setContentText(getText(R.string.notification_message))
        .setSmallIcon(R.mipmap.icon_fg36)
        .setContentIntent(pendingIntent)
        .setTicker(getText(R.string.ticker_text))
        .build()


サービスを別スレッドとする場合

Thread( Runnable {
    DO-YOUR-JOB
    stopForeground(true)
} ).start()


サンプル
// MainActivity.kt

package YOUR.PACKAGE.PROJECT

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        buttonServiceStart.setOnClickListener {
            val serviceIntent = Intent(this, MyForegroundService::class.java)
            startService(serviceIntent)
        }
    }
}
// MyForegroundService.kt

package YOUR.PACKAGE.PROJECT

import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.widget.Toast
import androidx.core.app.NotificationCompat


class MyForegroundService : Service() {

    override fun onBind(intent: Intent): IBinder {
        throw UnsupportedOperationException("Not yet implemented")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Toast.makeText(this,"Creating Notification",Toast.LENGTH_SHORT).show()

        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent
                .getActivity(this, 0, notificationIntent, 0)


        val notification: Notification = NotificationCompat
            .Builder(this, "ChannelID")
            .setContentTitle(getText(R.string.notification_title))
            .setContentText(getText(R.string.notification_message))
            .setSmallIcon(R.mipmap.icon_fg36)
            .setContentIntent(pendingIntent)
            .setTicker(getText(R.string.ticker_text))
            .build()

        startForeground(1, notification)

        Thread(
                Runnable {
                    (0..30).map {
                        Thread.sleep(1000)

                    }

                    stopForeground(true)
                    // もしくは
                    // stopSelf()

                }).start()

        return START_STICKY
    }
}