nirasan's tech blog

趣味や仕事の覚え書きです。Linux, Perl, PHP, Ruby, Javascript, Android, Cocos2d-x, Unity などに興味があります。

Unity で Android ネイティブプラグインの実装 - 一定時間起動していない場合にローカル通知を出すバックグラウンド処理の実装

はじめに

  • 前回に引き続き Unity での Android ネイティブプラグインの実装
  • 今回は、アプリ起動後に非アクティブにしたまま一定時間が経過したら、ローカル通知を出して呼び戻す機能の実装。

プラグイン側の実装

バックグラウンドで実行される Service を実装

  • バックグラウンドで実行される処理は IntentService の拡張クラスとして実装する
  • 以下は実行後一定時間がたったらローカル通知を送信する Service の実装
package info.nirasan.notifytest;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class NotifyIntentService extends IntentService {
	
	public static volatile boolean shouldContinue = true;

	public NotifyIntentService (String name) {
		super(name);
	}
	
	public NotifyIntentService () {
		super("NotifyIntentService");
	}
	
	@Override
    protected void onHandleIntent(Intent intent) {
		
		shouldContinue = true;
		
        // 非同期処理を行うメソッド。タスクはonHandleIntentメソッド内で実行する
        Log.d("NotifyIntentService","onHandleIntent Start");
        
        long endTime = System.currentTimeMillis() + 60*1000;
        while (System.currentTimeMillis() < endTime) {
            Log.d("NotifyIntentService","onHandleInten " + String.valueOf(endTime));
            synchronized (this) {
                try {
                    wait(endTime - System.currentTimeMillis());
                    if (!shouldContinue) {
                    	stopSelf();
                    	return;
                    }
                    
                    NotifyTest notifyTest = new NotifyTest();
                	notifyTest.sendNotification();
                } catch (Exception e) {
                }
            }
        }
    }
}

Service の呼び出し

  • 前回作成した NotifyTest.java に Service 呼び出しメソッドを追加する。
package info.nirasan.notifytest;

import android.app.Activity;
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;
import android.util.Log;

import com.unity3d.player.UnityPlayer;

public class NotifyTest {
	
	public void startService() {
		Activity activity = UnityPlayer.currentActivity;
		Context context = activity.getApplicationContext();
		activity.startService(new Intent(context, NotifyIntentService.class));
	}
	
	public void stopService() {
		NotifyIntentService.shouldContinue = false;
	}
	
	public void sendNotification() {
		... 省略 ...
	}
}

AndroidManifest.xml の編集

  • application タグの直下に以下の要素を挿入する。
		<service android:name="info.nirasan.notifytest.NotifyIntentService"></service>

Unity 側の実装

  • 前回作成した NotifyTestScript を編集し、アプリが非アクティブ化した時に Service が起動するように。
using UnityEngine;
using System.Collections;

public class NotifyTestScript : MonoBehaviour {

	static AndroidJavaObject m_plugin = null;
	static GameObject        m_instance;

	public void Awake () {
		// gameObject変数はstaticでないのでstatic関数から呼ぶことが出来ない.
		// そのためstaticの変数にあらかじめコピーしておく.
		m_instance = gameObject;
#if UNITY_ANDROID && !UNITY_EDITOR
		// プラグイン名をパッケージ名+クラス名で指定する。
		m_plugin = new AndroidJavaObject( "info.nirasan.notifytest.NotifyTest" );
#endif
	}

	void OnApplicationPause (bool pauseStatus)
	{
		if (pauseStatus) {
			Debug.Log("applicationWillResignActive or onPause");
#if UNITY_ANDROID && !UNITY_EDITOR
			m_plugin.Call ("startService");
#endif
		} else {
			Debug.Log("applicationDidBecomeActive or onResume");
#if UNITY_ANDROID && !UNITY_EDITOR
			m_plugin.Call ("stopService");
#endif
		}
	}

}