Unity 指定時間ローカルプッシュ通知処理を書いてみた Android編
-- 8/26追記 今北工業さんが私の記事のtypoを修正してくださりました〜! こちらも参考にしてくださいm( )m
今月末に引っ越しを控え案件のタスクを残したくないraharuです
さて、前回に引き続きUnityのNative連携のAndro編です。
流れとしてはAlarmManagerで登録
レシーバーで受信したらローカル通知を投げるという事をしたいだけなのにクソはまった。。
※まだAndroidPluginの作成環境が出来てない人はこちらの記事で環境を構築してください。
パッケージ名は自由ですが、
今回はnet.raharu.localnotifypluginです
これあとでAndroidManifestに使うので重要
java側
localNotification.java
package net.raharu.localnotifyplugin; import java.util.Calendar; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.util.Log; import com.unity3d.player.UnityPlayer; public class localNotification { /** * 時間指定でローカル通知を投げる * @param message * @param unixtime * @param primary_key */ public void sendNotification(String message, long unixtime, int primary_key) { Log.i("Unity", "SendNotificationStart"); // インテント作成 Activity activity = UnityPlayer.currentActivity; Context context = activity.getApplicationContext(); Intent intent = new Intent(context, NotificationReceiver.class); //渡す値 intent.putExtra("MESSAGE", message); intent.putExtra("PRIMARY_KEY", primary_key); //10秒後にアラーム(デバック用) Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.add(Calendar.SECOND, 10); PendingIntent sender = PendingIntent.getBroadcast(context, primary_key, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis() , sender); } }
NotificationReceiver.java
package net.raharu.localnotifyplugin; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v4.app.NotificationCompat; /** * レシーバー * * @author raharu */ public class NotificationReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //値の取得 String message = intent.getStringExtra("MESSAGE"); Integer primary_key = intent.getIntExtra("PRIMARY_KEY", 0); // intentからPendingIntentを作成 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); // LargeIcon の Bitmap を生成 final PackageManager pm = context.getPackageManager(); ApplicationInfo applicationInfo = null; try { applicationInfo = pm.getApplicationInfo(context.getPackageName(),PackageManager.GET_META_DATA); } catch (NameNotFoundException e) { e.printStackTrace(); return; } final int appIconResId = applicationInfo.icon; Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), appIconResId); // NotificationBuilderを作成 NotificationCompat.Builder builder = new NotificationCompat.Builder(context); builder.setContentIntent(pendingIntent); builder.setTicker("通知がとどきました"); //ステータスバーに届くテキスト builder.setSmallIcon(appIconResId); //アイコン builder.setContentTitle("タイトルだよ!!"); // タイトル builder.setContentText(message); // 本文(サブタイトル) builder.setLargeIcon(largeIcon); //開いた時のアイコン builder.setWhen(System.currentTimeMillis()); //通知に表示される時間(※通知時間ではない!) // 通知時の音・バイブ・ライト builder.setDefaults(Notification.DEFAULT_ALL); builder.setAutoCancel(true); // NotificationManagerを取得 NotificationManager manager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE); // Notificationを作成して通知 manager.notify(primary_key, builder.build()); } }
このパッケージをjarとしてエクスポートしてAssets/Plugin/Androidの直下に起きます。
Unity側
AndroidMnifest.xmlにレシーバーと権限を追加
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="XXXXXXXXXXXX" android:installLocation="preferExternal" android:theme="@android:style/Theme.NoTitleBar" android:versionCode="1" android:versionName="1.0"> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true"/> <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="true"> <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name"> <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" /> <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" /> </activity> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> #ここに通知されるレシーバーを登録する(パッケージ名+クラス名) <receiver android:name="net.raharu.localnotifyplugin.NotificationReceiver" android:process=":remote" /> </application> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="20" /> <uses-feature android:glEsVersion="0x00020000" /> <uses-permission android:name="android.permission.INTERNET" /> #バイブレートの権限追加 <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> </manifest>
こんな感じで呼び出せる
#if UNITY_ANDROID AndroidJavaObject m_plugin = new AndroidJavaObject( "net.raharu.localnotifyplugin.localNotification"); if (m_plugin != null){ m_plugin.Call("sendNotification", "本文だよ!!!!", [unixtime], [unique_id]); } #endif
unixtimeは通知したい時間(今回は強制で10秒後にしてるけども。。)
第三引数はユニークな値を入れるとよし
これで時間指定したローカル通知が届くようになりました。
当たり前の事かも知れないけど一本アプリ作るのに
c# java obj-c phpと4言語扱うのに
mono eclipse xcode vimを言ったり来たりして段々今何言語書いてるのか分からなくなってくる。
ネイティブ連携は面倒くさいね!
参考にさせて頂きました