たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 1419
お一人様インスタンス作ってみたい(タイトル全然関係なくてあれ)
Context#startForegroundService()
に制限が追加された模様。
ので検証してみる
なまえ | あたい |
---|---|
Android | 12 DP 1 |
スマホ | Pixel 3 XL |
アプリがバックグラウンドな状態の時にContext#startForegroundService()
が呼べなくなった模様。
どの状態のことを言っているのかというとここに書いてある→ https://developer.android.com/guide/background#definition
Android 12 を対象にします
app/build.gradle
android {
compileSdkVersion "android-S"
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "io.github.takusan23.backgroundstartforegroundservice"
minSdkVersion "S"
targetSdkVersion "S"
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
フォアグラウンドサービス利用権限が必要です(インターネット権限並に書き忘れるやつ)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.takusan23.backgroundstartforegroundservice">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BackgroundStartForegroundService">
<service android:name=".ExampleService" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
サービスを起動するコードだけ。バックグラウンドに行ったことを検知するためonStop()
に書く
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
/** バッググラウンド判定 */
override fun onStop() {
super.onStop()
Toast.makeText(this, "onStop", Toast.LENGTH_SHORT).show()
Timer().schedule(5000) {
runOnUiThread {
Toast.makeText(this@MainActivity, "Start service", Toast.LENGTH_SHORT).show()
startForegroundService(Intent(this@MainActivity, ExampleService::class.java))
}
}
}
}
特に何もしませんが
class ExampleService : Service() {
/** 通知チャンネル追加で使う */
private val notificationManager by lazy { getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
postNotification()
return START_NOT_STICKY
}
override fun onBind(p0: Intent?): IBinder? {
return null
}
/** フォアグラウンド開始 */
private fun postNotification() {
val notificationChannelId = "test_notification"
if (notificationManager.getNotificationChannel(notificationChannelId) == null) {
// 通知チャンネル登録
val channel = NotificationChannel(notificationChannelId, "通知テスト", NotificationManager.IMPORTANCE_LOW)
notificationManager.createNotificationChannel(channel)
}
val notification = Notification.Builder(this, notificationChannelId).apply {
setContentTitle("サービス起動中")
setContentText("サービス起動テスト")
setSmallIcon(R.drawable.ic_outline_textsms_24)
}.build()
startForeground(1, notification)
}
}
起動する→アプリから離れる→5秒待つと?
java.lang.IllegalStateException: startForegroundService() not allowed due to mAllowStartForeground false: service io.github.takusan23.backgroundstartforegroundservice/.ExampleService
起動しない。あと通知も飛んでくる
Context#startForeground()
を呼んでも10秒間は通知を出さずにサービスを起動しておけるらしい。
ただし、以下の条件に一個でも当てはまるとすぐに通知が出るようになる。
val notification = Notification.Builder(this, notificationChannelId).apply {
setContentTitle("サービス起動中")
setContentText("サービス起動テスト")
setSmallIcon(R.drawable.ic_outline_textsms_24)
addAction(Notification.Action.Builder(Icon.createWithResource(this@ExampleService, R.drawable.ic_outline_textsms_24), "ボタン", null).build())
}.build()
foregroundServiceType
がconnectedDevice
、mediaPlayback
、mediaProjection
、phoneCall
のとき<service android:name=".ExampleService" android:foregroundServiceType="mediaProjection" />
setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
を指定したval notification = Notification.Builder(this, notificationChannelId).apply {
setContentTitle("サービス起動中")
setContentText("サービス起動テスト")
setSmallIcon(R.drawable.ic_outline_textsms_24)
setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE) // これ
}.build()
これに当てはまらなければService#startForeground()
を呼んだ後10秒間は通知が表示されずにサービスを実行できます
間違ってたらすいません
startActivity()
の制限の次はstartForegroundService()
がやられるのか