最新消息:欢迎访问Android开发中文站!联系QQ:1304524325

缔造Android推送服务不死之身

开发进阶 AndroidChina 1483浏览 1评论

以后自己会用到这个记录一下

废话就不多说了,直奔主题:

首先是推送的配置,这里就不在叙述:使用的是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>

转载请注明:Android开发中文站 » 缔造Android推送服务不死之身

您必须 登录 才能发表评论!

网友最新评论 (1)

  1. 这种做法不可取,耗电耗内存,会被当成流氓应用的。
    weichenxu2016-11-08 16:13