Android本地推送
阿新 • • 發佈:2019-02-16
推送基本介面
//獲取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了,