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)
回覆刪除