缔造Android推送服务不死之身
jmxyandy
9年前
<p>以后自己会用到这个记录一下</p> <p>废话就不多说了,直奔主题:</p> <p>首先是推送的配置,这里就不在叙述:使用的是androidpn;github中有源码,这里不是本贴的重点:</p> <p>1.首先弄明白两点:</p> <p>(1)当资源不够用的时候,手机的服务可能被kill掉,</p> <p>(2)当手机重启的时候,应用的服务是没有被开启的;也就是你不打开应用,服务不会自动开启</p> <p>根据以上两点,我们可以对症下药;</p> <p>N1:提供一个工具类:主要判断服务的开启,应用的前后台的运行情况、开启广播监听,每一分钟检测一次开启推送服务等</p> <pre> <code class="language-java">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(); } }</code></pre> <p>N2:定义广播接收者,定时判断服务有没有开启</p> <pre> <code class="language-java">/** * 广播接受者 定时判断开启服务 @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------------>>>>>>>>"); } }</code></pre> <p>N3:定义一个广播接受者:当机器重启了 ,那么使用这个广播接收者来循环调用开启服务</p> <pre> <code class="language-java">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 手机重启————>>>>>>>>”); } }</code></pre> <p>N4:配置manifest文件:主要是广播和服务(根据实际包名定义)</p> <pre> <code class="language-java"><!-- 定时开启服务的广播 --> <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></code></pre> <p> </p> <p>来自:http://www.androidchina.net/5525.html</p> <p> </p>