締造Android推送服務不死之身
以后自己會用到這個記錄一下
廢話就不多說了,直奔主題:
首先是推送的配置,這里就不在敘述:使用的是androidpn;github中有源碼,這里不是本貼的重點:
1.首先弄明白兩點:
(1)當資源不夠用的時候,手機的服務可能被kill掉,
(2)當手機重啟的時候,應用的服務是沒有被開啟的;也就是你不打開應用,服務不會自動開啟
根據以上兩點,我們可以對癥下藥;
N1:提供一個工具類:主要判斷服務的開啟,應用的前后臺的運行情況、開啟廣播監聽,每一分鐘檢測一次開啟推送服務等
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.mc.androidpn.client.Constants;
import com.mc.androidpn.client.ServiceManager;
import com.mc.mycardlicense.activity.R;
import com.mc.mycardlicense.receiver.PushAlarmReceiver;
/**
* 靜態工具類:主要判斷服務的開啟,應用的前后臺的運行情況、開啟廣播監聽,每一分鐘檢測一次開啟推送服務等
public class CommonStaticUtil {
private static final String TAG = "CommonStaticUtil";
/**
* 用來判斷服務是否在運行.
* @param mContext 上下文
* @param className 判斷的服務名字
* [url=home.php?mod=space&uid=309376]@return[/url] isRunning :true 在運行 、false 不在運行
*/
public static boolean isServiceRunning(Context mContext, String className) {
//默認標記:為false
boolean isRunning = false;
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
//獲取正在運行的服務
List<ActivityManager.RunningServiceInfo> serviceList = activityManager.getRunningServices(30);
//如果沒有,那么返回false
if (!(serviceList.size() > 0)) {
return false;
}
//如果有,那么迭代List,判斷是否有當前某個服務
for (int i = 0; i < serviceList.size(); i++) {
if (serviceList.get(i).service.getClassName().equals(className) == true) {
isRunning = true;
break;
}
}
return isRunning;
}
/**
* 判斷程序是否在當前前臺運行
*
* @return true程序在當前前臺運行、false的時候程序不在當前前臺運行
*/
public static boolean isRunningForeground (Context context){
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
//The activity component at the top of the history stack of the task. This is what the user is currently doing.
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
String currentPackageName = cn.getPackageName();
if(!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(context.getPackageName()))
{
return true ;
}
return false ;
}
/**
* 程序是否在前臺隊列中運行
* @param mContext 上下文
* @return true 標識是在隊列里、false標識不在前臺桟列
*/
public static boolean isAppOnForeground(Context mContext) {
// Returns a list of application processes that are running on the device
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
String packageName = mContext.getApplicationContext().getPackageName();
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null)
return false;
for (RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName)&& appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
return false;
}
/**
* 開啟后臺推送服務
* @param context 上下文
*/
public static void startService(Context context){
Logger.i(TAG, "----startService-class----------------");
if(!CommonStaticUtil.isServiceRunning(context, StaticMember.SERVICENAME)){
Logger.i(TAG, "Service 沒有開啟,開啟推送服務........>");
ServiceManager serviceManager = new ServiceManager(context);
serviceManager.setNotificationIcon(R.drawable.ic_launcher);
serviceManager.startService();
}else{
Logger.i(TAG, "Service 推送服務已開啟........>");
}
}
/**
* 關閉 推送服務
* @param context 上下文
*/
public static void stopService(Context context){
Logger.i(TAG, “關閉 推送服務……..”);
// 關閉推送服務
ServiceManager serviceManager = new ServiceManager(context);
serviceManager.setNotificationIcon(R.drawable.ic_launcher);
serviceManager.stopService();
//刪除配置文件
SharedPreferences preferences = context.getSharedPreferences(Constants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
Editor editor = preferences.edit();
editor.clear();
editor.commit();
}
/**
開啟廣播監聽,每一分鐘檢測一次開啟推送服務
@param context 上下文傳遞 */
public static void startReceiver(Context context){
Logger.i(TAG, “開啟廣播監聽……..”);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent2 = new Intent(context, PushAlarmReceiver.class);
//發送一個廣播
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, intent2, 0);
//1分鐘定時重復發送–:即一分鐘檢測一次服務有沒有開啟,沒有開啟就開啟服務
alarmManager.setRepeating(AlarmManager.RTC, 0, 60 * 1000,pendingIntent);
}
/**
<li>獲取設備的deviceId用來做推送username</li>
<li>@param context</li>
<li>@return 返回設備的DeviceID號
*/
public static String getDeiviceID(Context context){
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
/*
* 唯一的設備ID:
* GSM手機的 IMEI 和 CDMA手機的 MEID.
* Return null if device ID is not available.
*/
return tm.getDeviceId();
}
}
N2:定義廣播接收者,定時判斷服務有沒有開啟
/**
* 廣播接受者 定時判斷開啟服務
@author wangl(Mail:WangleiDree@gmail.com)
*/
public class PushAlarmReceiver extends BroadcastReceiver {
private static final String TAG = “PushAlarmReceiver”;
private Context context;
private static int count=0;//1分鐘檢測下后臺服務是否開啟
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
Log.i(TAG, "-----------------1 minutes to in------------>>>>>>>>");
CommonStaticUtil.startService(context);
Log.i(TAG, "-----------------1 minutes to out------------>>>>>>>>");
}
}
N3:定義一個廣播接受者:當機器重啟了 ,那么使用這個廣播接收者來循環調用開啟服務
package com.mc.mycardlicense.receiver;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.mc.mycardlicense.utils.CommonStaticUtil;
import com.mc.mycardlicense.utils.Logger;
/**
* 廣播接收者:當機器重啟了 ,那么使用這個廣播接收者來循環調用開啟服務
@author wangl(Mail:WangleiDree@gmail.com)
*/
public class PushStartupReceiver extends BroadcastReceiver {
private static final String TAG = “PushStartupReceiver”;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, “—————–PushStartupReceiver in 手機重啟————>>>>>>>>”);
}
}
N4:配置manifest文件:主要是廣播和服務(根據實際包名定義)
<!-- 定時開啟服務的廣播 -->
<receiver
android:name="com.mc.mycardlicense.receiver.PushAlarmReceiver"
android:enabled="true" />
<!-- 手機重啟的廣播 -->
<receiver android:name="com.mc.mycardlicense.receiver.PushStartupReceiver" >
<intent-filter android:priority="1000" >
<category android:name="android.intent.category.HOME" />
<action android:name="android.intent.action.BOOT_COMPLETED" > </action>
</intent-filter>
</receiver>
來自:http://www.androidchina.net/5525.html
本文由用戶 jmxyandy 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!