android

androidアプリ作成時のメモです。

1138 views

フォアグラウンドサービスのサンプルプログラムを記す。

作るプログラムの動作

AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.konishisoft.servicesample">
  4. <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  5. <application
  6. android:allowBackup="true"
  7. android:icon="@mipmap/ic_launcher"
  8. android:label="@string/app_name"
  9. android:roundIcon="@mipmap/ic_launcher_round"
  10. android:supportsRtl="true"
  11. android:theme="@style/Theme.ServiceSample">
  12. <activity android:name=".MainActivity">
  13. <intent-filter>
  14. <action android:name="android.intent.action.MAIN" />
  15. <category android:name="android.intent.category.LAUNCHER" />
  16. </intent-filter>
  17. </activity>
  18. <service android:name=".MyForegroundService" />
  19. </application>
  20. </manifest>

重要なのは、4行目の<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
19行目の<service android:name=".MyForegroundService" />である。

activity_main.xml

画面にボタンを二つ定義しているだけ。startボタンを押せばサービスが起動し、stopボタンを押せばサービスが停止するようにする。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <Button
  9. android:id="@+id/startbutton"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:text="start"
  13. app:layout_constraintBottom_toBottomOf="parent"
  14. app:layout_constraintHorizontal_bias="0.498"
  15. app:layout_constraintLeft_toLeftOf="parent"
  16. app:layout_constraintRight_toRightOf="parent"
  17. app:layout_constraintTop_toTopOf="parent"
  18. app:layout_constraintVertical_bias="0.273" />
  19. <Button
  20. android:id="@+id/stopbutton"
  21. android:layout_width="wrap_content"
  22. android:layout_height="wrap_content"
  23. android:text="stop"
  24. app:layout_constraintBottom_toBottomOf="parent"
  25. app:layout_constraintHorizontal_bias="0.498"
  26. app:layout_constraintLeft_toLeftOf="parent"
  27. app:layout_constraintRight_toRightOf="parent"
  28. app:layout_constraintTop_toTopOf="parent"
  29. app:layout_constraintVertical_bias="0.644" />
  30. </androidx.constraintlayout.widget.ConstraintLayout>

MyForegroundService.kt

サービスプログラムのクラスである。

  1. package com.konishisoft.servicesample
  2. import android.app.PendingIntent
  3. import android.app.Service
  4. import android.content.Intent
  5. import android.os.IBinder
  6. import android.util.Log
  7. import androidx.core.app.NotificationCompat
  8. class MyForegroundService: Service() {
  9. override fun onBind(intent: Intent?): IBinder? {
  10. return null
  11. }
  12. override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
  13. /* val notification = NotificationCompat.Builder(this).apply {
  14. mContentTitle = "通知のタイトル"
  15. mContentText = "通知の内容"
  16. setSmallIcon(R.mipmap.ic_launcher)
  17. }.build()*/
  18. val openIntent = Intent(this, MainActivity::class.java).let {
  19. PendingIntent.getActivity(this, 0, it, 0)
  20. }
  21. var notification = NotificationCompat.Builder(this, 1234.toString())
  22. .setSmallIcon(R.mipmap.ic_launcher)
  23. .setContentTitle("これはタイトルです")
  24. .setContentText("これは内容です")
  25. .setContentIntent(openIntent)
  26. .setPriority(NotificationCompat.PRIORITY_DEFAULT)
  27. .build()
  28. Thread(
  29. Runnable {
  30. while(true){
  31. Log.d("konishi", "test")
  32. Thread.sleep(1000)
  33. }
  34. }).start()
  35. startForeground(1, notification)
  36. return START_STICKY
  37. }
  38. override fun stopService(name: Intent?): Boolean {
  39. return super.stopService(name)
  40. }
  41. }

基本的に32行目~36行目に追加したい処理を追加すればよい。
ちょっと最初に躓くのは、23行目~29行目のNofiticationCompatの扱い。
これは、サービスが起動したときに、通知を行う処理。
これがないと、うまく動かない。

何故こんな仕様になっているかというと、従来のアプリでサービスを利用すると、ユーザが気づかない状態で動いていることがある。
だから、悪意のあるサービスプログラムを仕掛けられていても、ユーザは気づきにくい。
つまり、サービスが稼働していますよ、というのをユーザに知らせることを強制する仕様になった、ということ。
恐らく、中国で勝手にデータを送信するプログラムがあるというのがたびたび問題になっていたので、それがトリガーとなってこのような仕様になったのではないかと勝手に理解している。

MainActivity.kt

  1. package com.konishisoft.servicesample
  2. import android.app.NotificationChannel
  3. import android.app.NotificationManager
  4. import android.content.Context
  5. import android.content.Intent
  6. import android.os.Build
  7. import androidx.appcompat.app.AppCompatActivity
  8. import android.os.Bundle
  9. import android.util.Log
  10. import android.widget.Button
  11. class MainActivity : AppCompatActivity() {
  12. override fun onCreate(savedInstanceState: Bundle?) {
  13. super.onCreate(savedInstanceState)
  14. Log.d("konishi", "start")
  15. setContentView(R.layout.activity_main)
  16. createNotificationChannel()
  17. val startbutton = findViewById<Button>(R.id.startbutton)
  18. startbutton.setOnClickListener {
  19. val intent = Intent(this, MyForegroundService::class.java)
  20. startForegroundService(intent)
  21. }
  22. val stopbutton = findViewById<Button>(R.id.stopbutton)
  23. stopbutton.setOnClickListener {
  24. val intent = Intent(this, MyForegroundService::class.java)
  25. stopService(intent)
  26. }
  27. }
  28. private fun createNotificationChannel() {
  29. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  30. val channel = NotificationChannel(
  31. 1234.toString(),
  32. "お知らせ",
  33. NotificationManager.IMPORTANCE_DEFAULT).apply {
  34. description = "お知らせを通知します。"
  35. }
  36. val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
  37. notificationManager.createNotificationChannel(channel)
  38. }
  39. }
  40. }

19行目~23行目がstartボタンを押したときにサービスプログラムが起動する処理。
24行目~29行目がstopボタンを押したときにサービスプログラムが停止する処理。

18行目は、通知のチャンネルを開く処理。関数自体は31行目以降に定義している。

Page 9 of 19.

前のページ 次のページ



[添付ファイル]


お問い合わせ

プロフィール

すぺぺぺ

自己紹介

本サイトの作成者。
プログラムは趣味と勉強を兼ねて、のんびり本サイトを作っています。
フレームワークはdjango。
ChatGPTで自動プログラム作成に取り組み中。

サイト/ブログ

https://www.osumoi-stdio.com/novel/

ツイッター

@darkimpact0626