締造Android推送服務不死之身

jmxyandy 8年前發布 | 6K 次閱讀 安卓開發 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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!