Unity本地推送消息(一)

IOS平台

请参考这个文档IOS本地消息通知LocalNotification的使用
以及 Unity官网API文档

Android平台

Unity在Android端的推送,是通过AndroidStudio打jar包的方式来实现的

1.AndroidStudio工程

关于打jar包可以参考我的另一篇文章:Unity调用安卓Native(Android Studio),处理好打jar包前的一系列准备。主要是:导入Unity的class.jar,对应版本的android.jar,在build.gradle里写好打jar包的task

2.写核心代码

新建一个class: AndroidNotificator 继承于BroadcastReceiver 在下面的代码里写的很明确

package cn.gfplay.noti;

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.os.Bundle;
import com.unity3d.player.UnityPlayer;
/**
 * 用于生成 / 清除本地通知推送的插件
 * 仅在安卓平台有效
 */
public class AndroidNotificator extends BroadcastReceiver {
    private static int m_nLastID = 0;
    /**
     * 显示数秒后的通知
     *
     * @param pAppName 应用名
     * @param pTitle 通知标题
     * @param pContent 通知内容
     * @param pDelaySecond 延迟时间
     * @param pIsDailyLoop 是否每日自动推送
     * @throws IllegalArgumentException 错误信息
     */
    public static void ShowNotification(String pAppName, String pTitle, String pContent, int pDelaySecond, boolean pIsDailyLoop) throws IllegalArgumentException {
        if(pDelaySecond < 0)
        {
            throw new IllegalArgumentException("The param: pDelaySecond < 0");
        }
        Activity curActivity = UnityPlayer.currentActivity;
        Intent intent = new Intent("UNITY_NOTIFICATOR");
        intent.putExtra("appname", pAppName);
        intent.putExtra("title", pTitle);
        intent.putExtra("content", pContent);
        PendingIntent pi =  PendingIntent.getBroadcast(curActivity, 0, intent, 0);
        AlarmManager am = (AlarmManager)curActivity.getSystemService(Context.ALARM_SERVICE);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, pDelaySecond);
        long alarmTime = calendar.getTimeInMillis();
        if (pIsDailyLoop){
            am.setRepeating(
                    AlarmManager.RTC_WAKEUP,
                    alarmTime,
                    30, // 暂时用30秒测试,一般应该为24小时即86400秒
                    pi);
        } else {
            am.set(
                    AlarmManager.RTC_WAKEUP,
                    alarmTime,
                    pi);
        }
    }
    /**
     * 清除所有通知,包括日常通知
     */
    public static void ClearNotification() {
        Activity act = UnityPlayer.currentActivity;
        NotificationManager nManager = (NotificationManager)act.getSystemService(Context.NOTIFICATION_SERVICE);

        for(int i = m_nLastID; i >= 0; i--) {
            nManager.cancel(i);
        }
        m_nLastID = 0;
    }
    @SuppressWarnings("deprecation")
    public void onReceive(Context pContext, Intent pIntent) {

        Class unityActivity = null;
        try {
            unityActivity = pContext.getClassLoader().loadClass("com.unity3d.player.UnityPlayerProxyActivity");
        } catch (Exception ex) {
            ex.printStackTrace();
            return;
        }
        ApplicationInfo applicationInfo = null;
        PackageManager pm = pContext.getPackageManager();
        try {
            applicationInfo = pm.getApplicationInfo(pContext.getPackageName(), PackageManager.GET_META_DATA);
        } catch (Exception ex) {
            ex.printStackTrace();
            return;
        }
        Bundle bundle = pIntent.getExtras();
        PendingIntent contentIntent = PendingIntent.getActivity(
                pContext,
                m_nLastID,
                new Intent(pContext, unityActivity),
                0);

        Notification.Builder builder = new Notification.Builder(pContext)
                .setAutoCancel(true)
                .setContentTitle((String)bundle.get("title"))
                .setContentText((String)bundle.get("content"))
                .setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.abc)
                .setWhen(System.currentTimeMillis())
                .setOngoing(true);
        Notification  notification=builder.getNotification();

        NotificationManager nm = (NotificationManager)pContext.getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(m_nLastID, notification);

        m_nLastID++;
    }
}

PS:
1.在src/main/res/drawable/下添加一张图片作为推送的Icon即在setSmallIcon(R.drawable.abc)处设置(目前还没研究明白,按这个代码测试推送的图片就是应用的icon)
对应到Unity中就是 Assets/Plugins/Android/res/drawable/ 否则会出现图片丢失的问题.
2.在AndroidMainifest.xml中需要添加一个receiver具体代码如下



  
  
    
      
        
        
        
      
      
    
    
      
        
      
    
  
  
  
  
  
  

加的是这一部分

      
        
          
        
    

PS:注意一下包名,很多地方都有 com.xxx.xxx.className

jar包以及xml和相关资源准备好,就进到Unity工程中进行处理了.
再Unity直接调用就可以了,用AndroidJavaObject 这个类,我贴上自己的代码(copy了一下)供参考:

using UnityEngine;
using UnityEngine.UI;
public class JARTest : MonoBehaviour
{
  public Text Text_Message;
#if UNITY_ANDROID
    private AndroidJavaObject m_ANObj = null;
#endif
  public void Button_1_Clicked()
  {
#if UNITY_ANDROID
        if(InitNotificator())
        {
            m_ANObj.CallStatic(
                "ShowNotification",
                Application.productName,
                "温馨提示",
                "多喝热水",
                10,
                true);
            this.Text_Message.text = "Notification will show in 10sec.";
        }
#endif
  }
  public void Button_2_Clicked()
  {
#if UNITY_ANDROID
        if(InitNotificator())
        {
            m_ANObj.CallStatic("ClearNotification");
            this.Text_Message.text = "Notification has been cleaned";
        }
#endif
  }
#if UNITY_ANDROID
    private bool InitNotificator()
    {
        if (m_ANObj == null)
        {
            try
            {
                m_ANObj = new AndroidJavaObject("cn.gfplay.noti.AndroidNotificator");
            }
            catch
            {
                this.Text_Message.text = "Init AndroidNotificator Fail";
                return false;
            }
        }
        if (m_ANObj == null)
        {
            this.Text_Message.text = "AndroidNotificator Not Found.";
            return false;
        }
        return true;
    }
#endif
}

贴上我的Unity截图,简单的用原生UI测试了一下


Unity本地推送消息(一)_第1张图片
image.png

遇到的一些问题:

1.推送的icon还还不是特清楚
2.出现过闪退的情况,原因是XML中的MainActivity错误

package cn.gfplay.noti;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

在XML的第五行的最后修改一下就好使了

 

3.目前只是推送一个消息,并没有添加点击事件,后续会在更新,调用不同的Notification.Builder的重载应该就是好使的.
后续写在了另一篇文章里Unity通知栏推送消息(二)

你可能感兴趣的:(Unity本地推送消息(一))