1. 程式人生 > >Android本地推送

Android本地推送

推送基本介面

//獲取app圖示
int iconResId = 0;
if(applicationInfo!=null){
    iconResId = applicationInfo.icon;
}
if(iconResId == 0){
    iconResId=R.drawable.icon;
}
//獲取推送大圖示
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), iconResId);
//構建開啟介面
Intent intent1 = new Intent(context, MainActivity.class
); PendingIntent pendingIntent = PendingIntent.getActivity(context, id, intent1, PendingIntent.FLAG_ONE_SHOT); //構建推送物件 Notification.Builder builder =new Notification.Builder(context); builder.setSmallIcon(iconResId); builder.setLargeIcon(bitmap); builder.setTicker(datas[0]); builder.setContentTitle
(datas[0]); builder.setContentText(datas[1]); builder.setContentIntent(pendingIntent); //設定預設聲音 builder.setDefaults(Notification.DEFAULT_SOUND); //設定點選自動清除狀態列顯示 builder.setAutoCancel(true); NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); manager.notify
(id, builder.build());

與Alarm服務結合,定時推送訊息

首先需要建立一個Alarm廣播的接受者,當接收到訊息的時候,傳送通知

package com.example.alarmtest1;

import android.annotation.SuppressLint;
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.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.Toast;

public class AlarmReceiver extends BroadcastReceiver  {
    private NotificationManager m_notificationMgr = null;

    @SuppressLint("NewApi")
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "定時時間到了", Toast.LENGTH_SHORT).show();

        m_notificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (intent.getAction().equals(GlobalValues.TIMER_ACTION_REPEATING)) {
            Log.e("alarm_receiver", "週期鬧鐘");
        } else if (intent.getAction().equals(GlobalValues.TIMER_ACTION)) {

            int id = intent.getIntExtra("id", -1);
            Log.e("alarm_receiver", "定時鬧鐘"+id);
            SharedPreferences sharedPreferences = context.getSharedPreferences("LocalNotification", Context.MODE_PRIVATE);
            String message = sharedPreferences.getString("message_"+id, "XXXX,通知");
            String[] datas = message.split(",");
            Intent intent1 = new Intent(context, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, id, intent1, PendingIntent.FLAG_ONE_SHOT);
            ApplicationInfo applicationInfo = null;
            try {
                applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 128);
            } catch (NameNotFoundException e) {
            }
            int iconResId = 0;
            if(applicationInfo!=null){
                iconResId = applicationInfo.icon;
            }
            if(iconResId == 0){
                iconResId=R.drawable.icon;
            }
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), iconResId);
           int i= Notification.DEFAULT_SOUND;
           Notification.Builder builder =new Notification.Builder(context);
           builder.setSmallIcon(iconResId);
           builder.setLargeIcon(bitmap);
           builder.setTicker(datas[0]);
           builder.setContentTitle(datas[0]);
           builder.setContentText(datas[1]);
           builder.setContentIntent(pendingIntent);
           builder.setDefaults(Notification.DEFAULT_SOUND);
           builder.setAutoCancel(true);
//            Notification notify = new Notification.Builder(context)
//                    .setSmallIcon(iconResId) // 設定狀態列中的小圖片,尺寸一般建議在24×24
//                    .setLargeIcon(bitmap) // 這裡也可以設定大圖示
//                    .setTicker("XXXX") // 設定顯示的提示文字
//                    .setContentTitle(datas[0]) // 設定顯示的標題
//                    .setContentText(datas[1]) // 訊息的詳細內容
//                    .setContentIntent(pendingIntent) // 關聯PendingIntent
//                    .setDefaults(Notification.DEFAULT_SOUND)
//                    .setNumber(1) // 在TextView的右方顯示的數字,可以在外部定義一個變數,點選累加setNumber(count),這時顯示的和
//                    .getNotification(); // 需要注意build()是在API level16及之後增加的,在API11中可以使用getNotificatin()來
//            
//            notify.flags |= Notification.FLAG_AUTO_CANCEL;

            NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//            manager.notify(id, notify);
            manager.notify(id, builder.build());
            bitmap.recycle(); //回收bitmap
            LocalNotificationManager.getInstance().removeNotifiDate(id, context);
        }
    }
}

AndroidManifest配置

 <receiver android:name=".AlarmReceiver" >
            <intent-filter>
                <action android:name="com.e_eduspace.TIMER_ACTION_REPEATING" />
                <action android:name="com.e_eduspace.TIMER_ACTION1" />
            </intent-filter>
        </receiver>

建立通知建立、取消的管理類

package com.example.alarmtest1;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.util.Log;

public class LocalNotificationManager {
     String NotifyKey="timeList";
     String TAG="LocalNotificationManager";
     private static LocalNotificationManager instance;

     public static LocalNotificationManager getInstance(){
         if(instance==null){
             instance=new LocalNotificationManager();
         }
         return instance;
     }
     /**
      * 設定推送時間
      * @param id 推送id
      * @param afterSeconds 多少秒後開始傳送推送訊息
      * @param title 推送標題
      * @param content 推送內容
      * @param context
      */
     public void SetAlarmNotification(int id,int afterSeconds,String title,String content,Context context){
         AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         Intent myIntent = new Intent();
         myIntent.setAction(GlobalValues.TIMER_ACTION);
         myIntent.putExtra("id", id); 
         SharedPreferences sharedPreferences = context.getSharedPreferences("LocalNotification", Context.MODE_PRIVATE);
         SharedPreferences.Editor editor = sharedPreferences.edit();//獲取編輯器
         editor.putString("message_"+id, String.format("%s,%s", title,content));
         editor.commit();

         PendingIntent sender = PendingIntent.getBroadcast(context, id, myIntent,PendingIntent.FLAG_ONE_SHOT);
         long notifyTime = System.currentTimeMillis() + afterSeconds * 1000;
         alarm.set(AlarmManager.RTC_WAKEUP,notifyTime , sender);
         addNotifiDate(id,notifyTime,context);
     }

     public void UpdateAlarmNotification(int id,long notifyTime,Context context){
             AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
             Intent myIntent = new Intent();
             myIntent.setAction(GlobalValues.TIMER_ACTION);
             myIntent.putExtra("id", id);
             PendingIntent sender = PendingIntent.getBroadcast(context, id, myIntent,PendingIntent.FLAG_ONE_SHOT);
             alarm.set(AlarmManager.RTC_WAKEUP, notifyTime, sender);
             addNotifiDate(id,notifyTime,context);
    }

     /**
      * 取消推送
      * @param id
      * @param context
      */
     public void CancelLocalNotification(int id,Context context){
         CancelLocalNotification(id,context,true);
     }

     public void CancelLocalNotification(int id,Context context,boolean isClearCache){
         AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         Intent myIntent = new Intent();
         myIntent.setAction(GlobalValues.TIMER_ACTION);
         myIntent.putExtra("id", id);
         if(isClearCache){
             SharedPreferences sharedPreferences = context.getSharedPreferences("LocalNotification", Context.MODE_PRIVATE);
             SharedPreferences.Editor editor = sharedPreferences.edit();//獲取編輯器
             editor.remove("message_"+id);
             editor.commit(); 
         }
         PendingIntent sender = PendingIntent.getBroadcast(context, 0, myIntent,0);
         alarm.cancel(sender);
         removeNotifiDate(id,context);
     }


     /**
      * 殺程序的時候,推送相關的服務都會終止,因此需要在進入遊戲的時候,重新整理之前儲存的推送內容
      * 每次啟動,重新整理本地定時通知內容
      */
     public void updateNotifiDate(Context context){
         Map<Integer, String > map = getLocalNofyTimeData(context);
         Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
         long curTime = System.currentTimeMillis();
         ArrayList<Integer> removeKeyList=new ArrayList<Integer>();
         while(it.hasNext()){

             Map.Entry<Integer, String> en = it.next();
             Integer id = en.getKey();
             long notifyTime = Long.parseLong(en.getValue());
             CancelLocalNotification(id,context,false);
             if(notifyTime<curTime){
                 removeKeyList.add(id);
                 Log.i(TAG, "過期key is "+id+",value is"+notifyTime);
                 continue;
             }
             UpdateAlarmNotification(id,notifyTime,context);

         }
         Log.i(TAG, "curTime is "+curTime);
         //刪除過期的key
         if(removeKeyList.size()>0){
             for(int i=0;i<removeKeyList.size();i++){
                 map.remove(removeKeyList.get(i));
                 Log.i(TAG, "過期key is "+removeKeyList.get(i));
             }

             resaveLocalNofyTimeData(map,context);
         }


     }


     public void addNotifiDate(int id,long notifyTime,Context context){
         Map<Integer, String > map = getLocalNofyTimeData(context);
         map.put(id, notifyTime+"");
         resaveLocalNofyTimeData(map,context);
     }

     public void removeNotifiDate(int id,Context context){
         Map<Integer, String > map = getLocalNofyTimeData(context);
         if(map.containsKey(id)){
             map.remove(id);
         }
         resaveLocalNofyTimeData(map,context);
     }


     public Map<Integer, String > getLocalNofyTimeData(Context context){
        Map<Integer, String > map = new HashMap<Integer, String >();
        SharedPreferences sharedPreferences = context.getSharedPreferences("LocalNotification", Context.MODE_PRIVATE);
         String times="";
         if(sharedPreferences.contains(NotifyKey)){
             times=sharedPreferences.getString(NotifyKey, "");
         }
         if(times.length()>0){
             String[] arr = times.split(",");
             for(int i=0;i<arr.length;i++){
                String[] items = arr[i].split("_");
                if(items.length==2){
                    int id = Integer.parseInt(items[0]);
                    String time=items[1];
                    map.put(id, time);
                }
             }
         }

         return map;
    }

     public void resaveLocalNofyTimeData(Map<Integer, String > map,Context context){
         SharedPreferences sharedPreferences = context.getSharedPreferences("LocalNotification", Context.MODE_PRIVATE);
         SharedPreferences.Editor editor = sharedPreferences.edit();
         Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
         StringBuilder sb=new StringBuilder();
         int index=0;
         while(it.hasNext()){
             Map.Entry<Integer, String> en = it.next();
             Integer key = en.getKey();
             String value = en.getValue(); 
             if(index>0){
                 sb.append(String.format(",%d_%s", key,value));
             }else{
                 sb.append(String.format("%d_%s", key,value));
             }
             index++;
         }
         editor.putString(NotifyKey, sb.toString());
         Log.i(TAG, "notifyData is "+sb.toString());
         editor.commit();
     }


}

一些全域性變數

package com.example.alarmtest1;

public class GlobalValues {
     // 週期性的鬧鐘
    public final static String TIMER_ACTION_REPEATING = "com.e_eduspace.TIMER_ACTION_REPEATING";
    // 定時鬧鐘
    public final static String TIMER_ACTION = "com.e_eduspace.TIMER_ACTION1";
}

測試

package com.example.alarmtest1;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {
    int index=0;

    private LocalNotificationManager localNotificationManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localNotificationManager=new LocalNotificationManager();
        updateNotifiDate();
    }

    public void OnClick(View v){
        Toast.makeText(getApplicationContext(), "sjskjs", Toast.LENGTH_SHORT).show();
        SetAlarmNotification(index++,6,"this is a test title","this is content"+index);
    }



 public void SetAlarmNotification(int id ,int afterSeconds,String title,String content){
     localNotificationManager.SetAlarmNotification(id, afterSeconds, title, content, getApplicationContext());
 }

// public void UpdateAlarmNotification(int id,long notifyTime){
//   localNotificationManager.UpdateAlarmNotification(id, notifyTime, getApplicationContext());
//}

 public void CancelLocalNotification(int id){
     localNotificationManager.CancelLocalNotification(id, getApplicationContext());
 }


 /**
  * 每次啟動,重新整理本地定時通知內容
  */
 void updateNotifiDate(){
     localNotificationManager.updateNotifiDate(getApplicationContext());
 }

// void addNotifiDate(int id,long notifyTime){
//   localNotificationManager.addNotifiDate(id, notifyTime, getApplicationContext());
// }
// 
// void removeNotifiDate(int id){
//   localNotificationManager.removeNotifiDate(id, getApplicationContext());
// }


// Map<Integer, String > getLocalNofyTimeData(){
//  return localNotificationManager.getLocalNofyTimeData(getApplicationContext());
//}
// 
// void resaveLocalNofyTimeData(Map<Integer, String > map){
//   localNotificationManager.resaveLocalNofyTimeData(map, getApplicationContext());
// }


 //--------設定聲音
 private static Uri getSoundUri(String soundName)
 {
   if ((soundName == null) || (soundName.equals(""))) {
     return Uri.EMPTY;
   }

    File soundFile = new File(soundName);
   if (!soundFile.exists()) {
     return Uri.EMPTY;
   }
   return Uri.fromFile(soundFile);
 }

}

多訊息推送主要事項

1 註冊廣播
PendingIntent sender = PendingIntent.getBroadcast(context, id, myIntent,PendingIntent.FLAG_ONE_SHOT);
第二個引數設定為推送訊息id,相同的id推送結果會被覆蓋

2、notifcation要顯示多條,那麼NotificationManager.notify( id, notify); 中的要保持不一樣;
如果id值一樣,那麼就把之前的notify覆蓋更新為當期最新的;

3、點選notification 進入到activity, 使用到pendingIntent類方法,PengdingIntent.getActivity()的第二個引數,即請求引數,
實際上是通過該引數來區別不同的Intent的,如果id相同,就會覆蓋掉之前的Intent了,