Plugin 主要只有一個檔案 ( AlarmReceiver.java ) :
package com.macaronics.notification; import java.util.Calendar; import android.app.Activity; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; 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.os.Bundle; import android.util.Log; import com.unity3d.player.UnityPlayer; public class AlarmReceiver extends BroadcastReceiver { public static void startAlarm(String name, String title, String label, int secondsFromNow){ Activity act =UnityPlayer.currentActivity; Log.i("Unity", "startAlarm..."); Calendar c = Calendar.getInstance(); c.add(Calendar.SECOND, secondsFromNow); long alarmTime = c.getTimeInMillis(); Log.i("Unity", "alarm time +"+secondsFromNow); // Schedule the alarm! AlarmManager am = (AlarmManager)act.getSystemService(Context.ALARM_SERVICE); Intent ii =new Intent(act, AlarmReceiver.class); ii.putExtra("name", name); ii.putExtra("title", title); ii.putExtra("label", label); am.set(AlarmManager.RTC_WAKEUP, alarmTime, PendingIntent.getBroadcast(act, 0, ii, 0)); } //<receiver android:process=":remote_notification" android:name="AlarmReceiver"></receiver> @Override public void onReceive(Context context, Intent intent) { Log.d("Unity", "Alarm Recieved!"); NotificationManager mNM = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); Bundle bb =intent.getExtras(); Class<?> cc = null; try { cc = context.getClassLoader().loadClass("com.unity3d.player.UnityPlayerProxyActivity"); } catch (ClassNotFoundException e1) { e1.printStackTrace(); return; } 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; Notification notification = new Notification(appIconResId, (String)bb.get("name"), System.currentTimeMillis()); int id =(int)(Math.random()*10000.0f)+1; PendingIntent contentIntent = PendingIntent.getActivity(context, id, new Intent(context, cc), 0); notification.setLatestEventInfo(context, (String)bb.get("title"), (String)bb.get("label"), contentIntent); Log.i("Unity", "notify("+id+") with "+(String)bb.get("title")+", "+(String)bb.get("label")); mNM.notify(id, notification); } }
其中函數 startAlarm 主要負責在 Alarm Service 設定 Alarm 事件的啟動時間,接收 Alarm 事件的對象 (com.macaronics.notification.AlarmReceiver ) ,傳遞的資料 (name, title, label),當 Alarm 事件呼叫啟動 onReceive 函數之後,onReceive 則是依照傳遞過來的資料利用 Notification Service 來產生 Notification。
編譯 AlarmReceiver.java (OSX 環境) :
編譯 AlarmReceiver.java (OSX 環境) :
#!/bin/sh ANDROID_JAR=/Users/macaronics/Desktop/applications/adt-bundle-mac-x86_64-20130917/sdk/platforms/android-13/android.jar UNITY_JAR=/Applications/Unity4.2.1/Unity.app/Contents/PlaybackEngines/AndroidPlayer/bin/classes.jar javac ./*.java -cp $ANDROID_JAR:$UNITY_JAR -d . jar cvfM ../AlarmReceiver.jar com/ rm -rf ./com
其中 ANDROID_JAR 是 Android SDK 底下的 android.jar 路徑,UNITY_JAR 是 Unity 底下 classes.jar 的路徑,javac 指令將目前資料夾底下所有的 java 檔案 compile 成 class 檔案並置於相對應於 package name 的資料夾路徑底下,jar 指令則是將資料夾打包成 jar 檔案 (值得注意的是 package name 與資料夾路徑必須要一致,例如 package name 為 com.macaronics.notification,則其 class 檔案須置於 ./com/macaronics/notification/ 底下。 )
設定 AndroidManifest.xml,在 AndroidManifest.xml 的 application 底下新增 :
<receiver android:process=":remote" android:name="com.macaronics.notification.AlarmReceiver"></receiver>
底下為 AndroidManifest.xml 完整內容 :
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" android:theme="@android:style/Theme.NoTitleBar" android:versionName="1.0" android:versionCode="10"> <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="false"> <receiver android:process=":remote" android:name="com.macaronics.notification.AlarmReceiver"></receiver> <activity android:name="com.unity3d.player.UnityPlayerProxyActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" > </activity> <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" > <meta-data android:name="android.app.lib_name" android:value="unity" /> <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" /> </activity> </application> <uses-feature android:glEsVersion="0x00020000" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> </manifest>
將編譯完成的 AlarmReceiver.jar 以及 AndroidManifest.xml 置於 Unity 專案資料夾的 Assets/Plugins/Android/ 底下。
建立一個 C# Script 測試結果,其內容如下 :
using UnityEngine; using System.Collections; public class AlarmReceiver : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } AndroidJavaObject nativeObj =null; void OnGUI(){ if (GUI.Button(new Rect(Screen.width*0.5f-90.0f, 100.0f, 180.0f, 100.0f), "Create Notification")){ if (nativeObj ==null) nativeObj =new AndroidJavaObject("com.macaronics.notification.AlarmReceiver"); nativeObj.CallStatic("startAlarm", new object[4]{"THIS IS NAME", "THIS IS TITLE", "THIS IS LABEL", 10}); } } }
當使用者按下 Create Notification 按鈕之後 Plugin 會建立一個 10 秒後顯示 Notification 的 Alarm 事件。
本範例的完整 Unity 程式碼可以在 http://github.com/phardera/unity3d_notification_android 下載。
Very useful!
回覆刪除Muy bueno muchas gracias (Y)
回覆刪除