「Unity/Native連携/Kotlinバックグランド通知」の版間の差分
提供: 初心者エンジニアの簡易メモ
行2: | 行2: | ||
通知欄を見に行くと、追加される。トップ画面へのpopupはされない。(IMPORTANCE_HIGHや、NotificationCompat.PRIORITY_HIGHを追加でpopupされると合ったが何故かされない・・・) | 通知欄を見に行くと、追加される。トップ画面へのpopupはされない。(IMPORTANCE_HIGHや、NotificationCompat.PRIORITY_HIGHを追加でpopupされると合ったが何故かされない・・・) | ||
− | == | + | ==準備確認== |
[[Android/kotlin/Notification]] [ショートカット] | [[Android/kotlin/Notification]] [ショートカット] | ||
2024年9月11日 (水) 23:26時点における最新版
はじめに
通知欄を見に行くと、追加される。トップ画面へのpopupはされない。(IMPORTANCE_HIGHや、NotificationCompat.PRIORITY_HIGHを追加でpopupされると合ったが何故かされない・・・)
準備確認
Android/kotlin/Notification [ショートカット]
Unity側
RenkeiScene.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System; public class RenkeiScene : MonoBehaviour { [SerializeField] Button alarmButton; void Start() { alarmButton.onClick.AddListener(CallMethodAlarm); } void CallMethodAlarm() { SetAlarm(10); } #if UNITY_ANDROID && !UNITY_EDITOR public void SetAlarm(int second) { Debug.Log("SetAlarm second=" + second); using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject context = activity.Call<AndroidJavaObject>("getApplicationContext"); AndroidJavaClass alarmReceiver = new AndroidJavaClass("com.example.mylibrary.AlarmReceiver"); alarmReceiver.CallStatic("setAlarm", context, second); } } // 権限付与 public void RequestExactAlarmPermission() { using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject alarmPermissionHelper = new AndroidJavaObject("com.example.alarmapp.AlarmPermissionHelper"); alarmPermissionHelper.Call("requestExactAlarmPermission", activity); } } #endif }
Android側
AlarmPermissionHelper.kt
package com.example.mylibrary import android.content.Intent import android.provider.Settings import android.app.AlarmManager import android.content.Context import android.os.Build import android.net.Uri class AlarmPermissionHelper { fun requestExactAlarmPermission(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager if (!alarmManager.canScheduleExactAlarms()) { // アラームの許可がない場合、設定画面を開く val intent = Intent().apply { action = Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM data = Uri.parse("package:${context.packageName}") } context.startActivity(intent) } } } }
AlarmReceiver.kt
package com.example.mylibrary import android.app.AlarmManager import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.os.SystemClock import android.util.Log import java.util.Calendar import android.os.Build import androidx.core.app.NotificationCompat class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Log.i("AlarmReceiver", "Notification triggered") // 通知を作成して表示 val notificationId = 1 val channelId = "alarm_channel" val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channelName = "Alarm Channel" val channelDescription = "Channel for alarm notifications" val importance = NotificationManager.IMPORTANCE_HIGH val notificationChannel = NotificationChannel(channelId, channelName, importance).apply { description = channelDescription } notificationManager.createNotificationChannel(notificationChannel) Log.i("AlarmReceiver", "Notification Channel Created") // API 26+ の場合 val notification = NotificationCompat.Builder(context, channelId) .setSmallIcon(android.R.drawable.ic_notification_overlay) // 通知アイコン .setContentTitle("アラーム通知") // 通知タイトル .setContentText("指定した時間が経過しました!") // 通知内容 .setPriority(NotificationCompat.PRIORITY_HIGH) .build() notificationManager.notify(notificationId, notification) Log.i("AlarmReceiver", "Notification Posted") } else { // API 26 未満の場合 val notification = NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_notification) // 通知アイコン .setContentTitle("アラーム通知") // 通知タイトル .setContentText("指定した時間が経過しました!") // 通知内容 .setPriority(NotificationCompat.PRIORITY_HIGH) .build() notificationManager.notify(notificationId, notification) Log.i("AlarmReceiver", "Notification Posted") } } companion object { @JvmStatic fun setAlarm(context: Context, second: Int) { val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager val intent = Intent(context, AlarmReceiver::class.java) val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) val triggerAtMillis = SystemClock.elapsedRealtime() + calculateTriggerTime(second) alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtMillis, pendingIntent) } private fun calculateTriggerTime(second: Int): Long { // 現在の時間を取得 val now = System.currentTimeMillis() val calendar = Calendar.getInstance() calendar.timeInMillis = now // 現在の時間に指定された秒を加算 calendar.add(Calendar.SECOND, second) // 計算された時間が現在の時間より後であることを確認 return calendar.timeInMillis - now } } }
Assets/Plugins/Android/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <!-- アラーム受信に必要な権限(通常は不要) --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <!-- 通知権限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <application> <receiver android:name="com.example.mylibrary.AlarmReceiver" android:enabled="true" android:exported="true" /> <activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="@style/UnityThemeSelector"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> </activity> </application> </manifest>
Assets/Plugins/Android/mainTemplate.gradle
dependencies { + implementation 'androidx.core:core:1.12.0' }
NotificationCompatを使うためandroidxが必要。
Assets/Plugins/Android/gradleTemplate.properties
android.useAndroidX=true android.enableJetifier=true