0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AndroidStudio: Service の使い方

Posted at

こちらと同じことを行いました。
[Android & Kotlin] Service でバックグラウンド処理

ツリー構造

image.png

環境

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Service05"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:taskAffinity=""
            android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".TestService" />
    </application>

</manifest>
values/strings.xml
<resources>
    <string name="app_name">service05</string>
    <string name="start">Start Service</string>
    <string name="stop">Stop Service</string>
</resources>

プログラム

MainActivity.kt
package com.example.service05

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

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

        val intent = Intent(application, TestService::class.java)

        val buttonStart = findViewById<Button>(R.id.button_start)
        buttonStart.setOnClickListener {
            intent.putExtra("REQUEST_CODE", 1)

            // Serviceの開始
            startService(intent)
        }

        val buttonStop: Button = findViewById(R.id.button_stop)
        buttonStop.setOnClickListener {
            // Serviceの停止
            stopService(intent)
        }
    }
}
TestService.kt
package com.example.service05

import android.app.*
import android.content.Intent
import android.media.MediaPlayer
import android.os.IBinder
import android.util.Log
import android.widget.Toast

class TestService : Service() {

    private lateinit var mediaPlayer: MediaPlayer

    override fun onCreate() {
        super.onCreate()
        Log.d("debug", "onCreate()")

        // ..\res\raw\sample.mp3
        mediaPlayer = MediaPlayer.create(this, R.raw.kanpai)
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        Log.d("debug", "onStartCommand()")

        val context = applicationContext

        val channelId = "default"

        val title: String = getString(R.string.app_name)

        val notificationManager = getSystemService(NOTIFICATION_SERVICE)
                as NotificationManager

        val pendingIntent: PendingIntent =
                      Intent(this, MainActivity::class.java).let { notificationIntent ->
                PendingIntent.getActivity(this, 0, notificationIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                )
            }

        // Notification Channel 設定
        val channel = NotificationChannel(
            channelId, title, NotificationManager.IMPORTANCE_DEFAULT
        )

        notificationManager.createNotificationChannel(channel)

        val notification = Notification.Builder(context, channelId)
            .setContentTitle(title) // android標準アイコンから
            .setSmallIcon(android.R.drawable.ic_media_play)
            .setContentText("MediaPlay")
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setWhen(System.currentTimeMillis())
            .build()

        // startForeground
        startForeground(1, notification)
        audioStart()
        return START_NOT_STICKY
        //return START_STICKY;
        //return START_REDELIVER_INTENT;
    }

    private fun audioStart() {
        // ループ
        mediaPlayer.isLooping = true

        mediaPlayer.start()

        // トースト
        val str = "Start Walking\n(c)Music-Note.jp"
        val toast: Toast = Toast.makeText(this, str, Toast.LENGTH_LONG)
        toast.show()

        // 終了を検知するリスナー
        mediaPlayer.setOnCompletionListener {
            Log.d("debug", "end of audio")
            audioStop()
            // Service終了
            stopSelf()
        }
    }

    private fun audioStop() {
        // 再生終了
        mediaPlayer.stop()
        // リセット
        mediaPlayer.reset()
        // リソースの解放
        mediaPlayer.release()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("debug", "onDestroy()")
        audioStop()
        // Service終了
        stopSelf()
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }
}

音源

音源は、こちらから kanpai.mp3 をダウンロードしました。
フリーWave,MP3

実行時の画面

エミュレーターでは、クラッシュします。
実機では、ちゃんと音源が再生されます。

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?