AlarmManager&安培; onStartCommand [英] AlarmManager & onStartCommand

查看:206
本文介绍了AlarmManager&安培; onStartCommand的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发android上一个GPS跟踪应用程序。
我用AlarmManager来唤醒设备每5分钟。
我开发了一个日志文件,显示该应用程序直到我receieve一刻的伟大工程
 公众诠释onStartCommand(意向意图,诠释标志诠释startId)与startId = 1再次....在这种情况下,我注意到,所有的变量都复位所以我又初始化所有变量..的问题是,一旦发生这种情况我不断收到与startID = 1再次与几个电话应用程序后,相同的事件只是停止,直到我打开ActivityForm和服务再次绑定!

日志是这里的坏事件:

  @Jun 17日上午03点29分31秒onStartCommand:标志0:startId:3:意向:意向{CMP = com.usegps2_1 / .LocationService}
@Jun 17日上午三时34分10秒onStartCommand:标志0:startId:1:意向:意向{CMP = com.usegps2_1 / .LocationService}
@Jun 17日上午三时34分10秒StartService与mbServiceStarted = TRUE
@Jun 17日上午三时34分十一秒通话InitGPS
@Jun 17日上午三时34分十一秒lastKnownLocation: Location[mProvider=gps,mTime=1308274198000,mLatitude=30.10493179906883,mLongitude=31.379563305705755,mHasAltitude=true,mAltitude=85.0,mHasSpeed=true,mSpeed=0.0,mHasBearing=true,mBearing=313.8908,mHasAccuracy=true,mAccuracy=10.0,mExtras=Bundle[mParcelledData.dataSize=4]]
@Jun 17日上午4点48分17秒onStartCommand:标志0:startId:1:意向:意向{CMP = com.usegps2_1 / .LocationService}
@Jun 17日上午4点48分17秒StartService与mbServiceStarted = TRUE
@Jun 17日上午4点48分17秒的呼叫InitGPS
@Jun 17日上午4点48分17秒lastKnownLocation: Location[mProvider=gps,mTime=1308274198000,mLatitude=30.10493179906883,mLongitude=31.379563305705755,mHasAltitude=true,mAltitude=85.0,mHasSpeed=true,mSpeed=0.0,mHasBearing=true,mBearing=313.8908,mHasAccuracy=true,mAccuracy=10.0,mExtras=Bundle[mParcelledData.dataSize=4]]

GPS服务code是在这里:

 导入java.text.DateFormat中;
进口java.util.Date;
进口java.util.Timer中;
进口java.util.TimerTask中;
进口java.util.concurrent.TimeUnit中;
进口android.app.AlarmManager;
进口android.app.Notification;
进口android.app.NotificationManager;
进口android.app.PendingIntent;
进口android.app.Service;
进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;
进口android.content.IntentFilter;
进口android.location.Location;
进口android.location.LocationManager;
进口android.os.Binder;
进口android.os.IBinder;
进口android.os.PowerManager;
进口android.os.SystemClock;
进口android.telephony.TelephonyManager;
进口android.util.Log;
进口android.widget.Toast;
进口android.media *。公共类LocationService延伸服务{    / * -------------------------------------属性* /
    INT NOTIFICATION_ID = 11283;
    私人NotificationManager mNotificationManager;
    公共MainActivity mMainActivity = NULL;
    保护PowerManager.WakeLock mWakeLock;
    保护AlarmManager mAlarMgr;
    受保护的PendingIntent AlarmIntent;    保护通知mNotification;
    受保护的PendingIntent mContentIntent;    受保护的静态最后双D2R = Math.PI / 180.0;    //位置变量
    受保护的静态最终诠释mAlarmRepeatRate = 5 * 60 * 1000;
    受保护的静态最终诠释mLocationTimeMinUpdate = 20000; //为信号之间等待的最短时间。
    受保护的静态最终诠释mLocationDistanceMinUpdate = 25; //回调之前最小米
    受保护的静态最终诠释TWO_MINUTES = 2 * 60 * 1000; //用于定义老读数    // TODO:这应该是速度的函数。与分和放大器;最大值。
    受保护的静态最终诠释MIN_Ma prefreshRate = 10000; //率用于发送到Web服务。    保护长mLocationNextSentTime;
    公共字符串mDeviceID = NULL;
    公共字符串mBatteryLevel = NULL;
    保护字符串mMobileServiceURL =htt​​p://locationbook.net/Tracking.asmx;
    公共布尔mUseGPSOnly;
    公共布尔mEnableBeeps;
    公共布尔mEnableDebug;
    公共字符串mSpeed​​Text =0;
    公共布尔mbBeepStarted = FALSE;
    公共布尔mbStarted = FALSE;
    公共布尔mbServiceStarted = FALSE;    公共场所mLastLocation = NULL;
    受保护的LocationManager mlocManager;
    保护MainGpsListener mMainGpsListener;
    保护MainLocationListener mlocListenerGPS;
    保护MainLocationListener mlocListenerNW;    保护ToneGenerator的mTG;
    保护浮动MSPEED;
    //这是从客户端接收的交互的对象。看到
    // RemoteService一个更完整的例子。
    私人最终的IBinder mBinder =新LocalBinder();    / * EOF属性* /
     / **
     *为类客户端访问。因为我们总是知道这个服务
     *在同一进程中作为它的客户运行时,我们并不需要处理
     * IPC。
     * /
    公共类LocalBinder扩展粘结剂{
        LocationService的getService(){
            返回LocationService.this;
        }
    }    / **
     * @see android.app.Service#onBind(意向)
     * /
    @覆盖
    公众的IBinder onBind(意向意图){
        // TODO把你的code在这里
        返回mBinder;
    }    / **
     * @see android.app.Service#的onCreate()
     * /
    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        // TODO:输入此位置重新创建报警电话的时候。
        mbServiceStarted = FALSE;
        com.usegps2_1.Logger.Log(getBaseContext(),的onCreate);    }    / **
     * @see android.app.Service#在onStart(意向,INT)
     * /
    @覆盖
    公共无效调用onStart(意向意图,诠释startId){
        // TODO把你的code在这里
        super.onStart(意向,startId);    }
    @覆盖
    公共无效的onDestroy(){        如果(mEnableDebug)Logger.Log(getBaseContext(),的onDestroy);        mAlarMgr.cancel(AlarmIntent);        如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_0,1500);
        如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);        //取消永久通知。
        mNotificationManager.cancel(NOTIFICATION_ID); //删除通知        如果(mbStarted ==真)
        {
            mlocListenerNW.mLocationService = NULL;
            mlocListenerGPS.mLocationService = NULL;
            mMainGpsListener.mLocationService = NULL;
            mlocManager.removeUpdates(mlocListenerNW);
            mlocManager.removeUpdates(mlocListenerGPS);
            mlocManager = NULL;
        }
        / **我认为这个功能就不会被调用除非我想关闭
        *从收盘mWakeLock prevent它。因此,我们可以让这里关闭屏幕。
        * /
        mWakeLock.release();        //告诉我们停止了该用户。
        Toast.makeText(这一点,服务退出,Toast.LENGTH_SHORT).show();
        super.onDestroy();
    }
     公众诠释onStartCommand(意向意图,诠释标志诠释startId){
           //我们希望该服务继续运行,直到它被明确
           //停止,因此返回粘​​。            / **
             * http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html
             * 1 - 应用程序调用startService()。
             * 2 - 这项服务获得的onCreate(),在onStart(),然后产生一个后台线程做一些工作。
             * 3本系统内存紧​​张,因此具有杀死当前正在运行的服务。
             * 4-后来,当内存是免费的,重新启动该服务,并得到所谓的onCreate(),但不是在onStart()
             *因为一直没有startService另一个呼叫()用新的意图命令发送。
             * START_STICKY是基本相同的previous行为,
             *
             *其中该服务左开始,将以后由系统重新启动。
             *从平台的previous版本中的唯一的区别是
             *如果它被重新启动,因为它的进程被终止,
             * onStartCommand()将会被调用该服务的下一个实例用空意图,而不是没有被调用的。
             *该适当地使用这种模式要经常检查这种情况并处理它的服务。
             *
             *从Android的书。
             * [2]标志参数可以用来发现服务的启动方式。特别是可以使用
             清单9-2所示* code段,以确定是否以下任一情况下是正确的:
             *? START_FLAG_REDELIVERY指示意图参数是造成重新传递
             *系统运行时的终止有服务之前,它被明确为stopSelf呼叫停止。
             *? START_FLAG_RETRY指示服务已异常终止之后已经重新启动。
             *的时候,服务是previously设置为START_STICKY通过。
             * /
            com.usegps2_1.Logger.Log(getBaseContext(),onStartCommand:国旗:+将String.valueOf(标志)+:startId:+将String.valueOf(startId)+:意图:+ intent.toString() );            如果(意向== NULL)
            {
                // TODO如果它是一个重新开始,做一些事情。
                updateNotification(重新启动的);
                如果酶(mTG!= NULL)
                {
                    如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_5,2000);
                }
            }            //mAlarMgr.cancel(null);            //参见[2]
            如果((标志&安培; START_FLAG_RETRY)== 0){
                //调试从上述条件错了,它应该是!= 0。
                //这里写code前检讨,请检查并。
            }
            其他{
                // TODO替代后台进程。
            }            StartService();           返回START_STICKY;
         }     / **
      *读取preference设置并应用它们。
      * /
     公共无效的申请preferenceSttings()
     {
        mMobileServiceURL =自preferenceManager.GetServiceURL(getApplication());
        mUseGPSOnly =自preferenceManager.GetGPSOnly(getApplication());
        mEnableBeeps =自preferenceManager.GetBeepsEnabled(getApplication());
        mEnableDebug =自preferenceManager.GetDebugEnabled(getApplication());
     }     / **
      *从外部调用,以启动服务。
      * /
     公共无效StartService()
     {
         如果(mbServiceStarted == FALSE)
         {
             mbServiceStarted = TRUE;            // TODO:请记得使用PARTIAL_WAKE_LOCK代替.SCREEN_DIM_WAKE_LOCK的
            电源管理PM =(电源管理)getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,我的标签);
            mWakeLock.acquire();            应用preferenceSttings();            如果(mEnableDebug)Logger.Log(getBaseContext(),StartService重新初始化= TRUE);
            TelephonyManager telephonyManager =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
            mDeviceID = telephonyManager.getDeviceId();
            showNotification();            的mTG =新ToneGenerator(1,80);            如果(mAlarMgr!= NULL)
            如果(mEnableDebug)Logger.Log(getBaseContext(),mAlarMgr是真);            mAlarMgr =(AlarmManager)getSystemService(Context.ALARM_SERVICE);
            意图int​​entToFire =新意图(GPSBroadcastReceiver.ReceiverName);
            AlarmIntent = PendingIntent.getBroadcast(在此,0,intentToFire,0);
            mAlarMgr.cancel(AlarmIntent); //有一个匹配的意图删除任何警报。 [BUG]避免造成许多报警......造成含多处报警电话与mbServiceStarted = false当检查调试文件。
            mAlarMgr.setRepeating(AlarmManager.RTC_WAKEUP,SystemClock.elapsedRealtime()+ mAlarmRepeatRate,mAlarmRepeatRate,AlarmIntent);            //注册在电池
            this.registerReceiver(this.mBatInfoReceiver,新的IntentFilter(Intent.ACTION_BATTERY_CHANGED));             StartLocation();
         }
         其他
         {             // updateNotification(再次呼吁在运行);
         }         // * /
     }     保护无效showNotification()
        {
            mNotificationManager =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
            //定义通知
            mNotification =新的通知(R.drawable.step,跟踪的,System.currentTimeMillis的());
            mNotification.flags = Notification.FLAG_ONGOING_EVENT;
            //定义通知操作
            意向意图=新意图(getApplicationContext(),MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            mContentIntent = PendingIntent.getActivity(LocationService.this,0,意向,PendingIntent.FLAG_CANCEL_CURRENT);            //设置通知
            mNotification.setLatestEventInfo(LocationService.this,它是gettext(R.string.app_name),单击以显示主屏,mContentIntent);
            //添加它
            mNotificationManager.notify(NOTIFICATION_ID,mNotification);
        }     保护无效updateNotification(CharSequence的说明)
      {
          如果(mNotification == NULL)回报;
          mNotification.when = System.currentTimeMillis的();
            //设置通知
          mNotification.setLatestEventInfo(LocationService.this,getText(R.string.app_name),Description,mContentIntent);
            //添加它
          mNotificationManager.notify(NOTIFICATION_ID,mNotification);
      }
     / * ------------------------------------------------ -GPS方法* /      保护无效StartLocation()
        {
            如果(mbStarted ==真)
            {
                Toast.makeText(getApplicationContext(),已在运行,Toast.LENGTH_SHORT).show();
                返回;
            }            如果(mEnableDebug)Logger.Log(getBaseContext(),InitGPS真);            mbStarted = TRUE;
            mLocationNextSentTime = 0; //发送一次u得到的数据
            如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_1,1000);
            //使用的LocationManager类获取GPS位置
            mlocManager =(的LocationManager)getSystemService(Context.LOCATION_SERVICE);
            Toast.makeText(getApplicationContext()已启动,Toast.LENGTH_SHORT).show();
            位置LOC = mlocManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);            //尝试读取当前位置
            如果(LOC!= NULL){
                mLastLocation =禄;
                如果(mEnableDebug)Logger.Log(getBaseContext(),lastKnownLocation:+ loc.toString());
            }
            其他
            {
                updateNotification(获取位置);            }            mlocListenerGPS =新MainLocationListener(本);
            mlocListenerNW =新MainLocationListener(本);
            mlocListenerGPS.mProvider =全球定位系统;
            mlocListenerNW.mProvider =NW;            mMainGpsListener =新MainGpsListener(本);
            //定义,响应位置更新的监听器
            mlocManager.addGpsStatusListener(mMainGpsListener);
            mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,mLocationTimeMinUpdate,mLocationDistanceMinUpdate,mlocListenerGPS);
            mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,mLocationTimeMinUpdate,mLocationDistanceMinUpdate,mlocListenerNW);            如果(mEnableDebug)Logger.Log(getBaseContext(),全球定位系统重新初始化);            // * /
        }        公共无效UpdateLocation(LOC位置,字符串提供商)
        {            尝试
            {
                如果(mUseGPSOnly&安培;及(提供程序=GPS)!)回报;                如果(mbStarted == FALSE)
                {
                    updateNotification(假);
                }
                如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_9,200);                串E = loc.toString();
                如果(mEnableDebug)Logger.Log(getBaseContext(),新位置);
                如果(mEnableDebug)Logger.Log(getBaseContext(),loc.toString());                如果(isBetterLocation(LOC,mLastLocation)== FALSE)
                {
                    updateNotification(所在地忽略);
                    返回;
                }
                mLastLocation =禄;                mMainActivity.mtxtTime.setText(DateFormat.getDateInstance()格式(新的Date()));
                mMainActivity.mtxtLatitude.setText(loc.getLatitude()+纬度);
                mMainActivity.mtxtLongitude.setText(loc.getLongitude()+LNG);                浮速度= loc.getSpeed​​(); //如果设置由GetSpeed​​值被称为INSITE isBetterLocation
                mSpeed​​Text = Float.toString(速度);
                mMainActivity.mtxtSpeed​​.setText(mSpeed​​Text +公里/秒);                如果((loc.getTime()> mLocationNextSentTime))
                {                    mLocationNextSentTime =(长)(loc.getTime()+ MIN_Ma prefreshRate *(140 - 速度)/ 140);                    如果(mEnableDebug)Logger.Log(getBaseContext(),下一步的HTTP:+将String.valueOf(mLocationNextSentTime));                    WebMethodProxy客户端=新WebMethodProxy(mMobileServiceURL +/ UpdateLocation);
                    client.AddParam(GUID,mDeviceID);
                    client.AddParam(纬度,Double.toString(loc.getLatitude()));
                    client.AddParam(经度,Double.toString(loc.getLongitude()));
                    client.AddParam(速度,mSpeed​​Text);
                    client.AddParam(电池,mBatteryLevel);                    //如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_5,500);                    尝试{
                        client.Execute(WebMethodProxy.RequestMethod.POST_JSON);
                    }赶上(例外五){
                        e.printStackTrace();                        // TODO:错误消息无法连接到服务器
                        如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_9,2500);
                        字符串ERR =(e.getMessage()== NULL)全球定位系统错误:e.getMessage();?                        如果(mEnableDebug)Logger.Log(getBaseContext(),失败:+ ERR);                        Log.e(TrackGPSERR);
                        mMainActivity.mtxtMessage.setText(不能访问Internet来更新位置。);
                        返回;
                    }                    串响应= client.getResponse();
                    响应=(响应== NULL)没有网络的答复:?响应;                    如果(mEnableDebug)Logger.Log(getBaseContext(),HTTP DONE:+响应);
                    Toast.makeText(getApplicationContext(),更新[+提供商+]:+响应,Toast.LENGTH_SHORT).show();
                    updateNotification(位置更新);                }
                其他
                {
                    updateNotification(位置被忽略。);
                }
            }
            赶上(例外五)
            {
                如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);
                 字符串ERR =(e.getMessage()== NULL)全球定位系统错误:e.getMessage();?
                 Log.e(TrackGPSERR);
                 updateNotification(DEBUG1:+ e.getMessage());
                 返回;
            }        }
        / **
         *在两点之间米返回距离。
         * @参数NewLocation
         * @参数CurrentLocation
         * @返回
         * /
        保护浮动CalculateSpeed​​(位置NewLocation,位置CurrentLocation){
            尝试
            {
            双dlong =(NewLocation.getLongitude() - CurrentLocation.getLongitude())* D2R;
            双DLAT =(NewLocation.getLatitude() - CurrentLocation.getLatitude())* D2R;
            双一= Math.pow(Math.sin(DLAT / 2.0),2)+ Math.cos(CurrentLocation.getLatitude()* D2R)* Math.cos(NewLocation.getLatitude()* D2R)* Math.pow(数学.sin(dlong / 2.0),2);
            双c = 2 * Math.atan2(的Math.sqrt(a)中,的Math.sqrt(1-A));
            双D = 6367000 * C;
            双TimeDelta = NewLocation.getTime() - CurrentLocation.getTime();
            回报(浮)(D / TimeDelta)* 3600;
            }
            赶上(例外五)
            {
                如果(mEnableBeeps)mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);
                 Log.e(TrackGPS,e.getMessage());
                 updateNotification(DEBUG2:+ e.getMessage());
                返回0;
            }        }        / **确定一个位置读数是否大于当前的位置锁定更好
         *逻辑:
         *如果太老返回FALSE。
         *如果太新返回True反正作为目前太旧。
         *如果更准确,然后返回TRUE
         *如果更新,相同或更准确,然后返回TRUE。
         *如果更新,不太准确,但同一个运营商返回true。
         * ------------------------------------------------- -----
         *时间精度相同的供应返回
         * ------------------------------------------------- -----
         *太老X X FALSE
         *太新X X TRUE
         *较早的X轴正TRUE
         *较新的X轴正TRUE
         *较新的相同的X TRUE
         *较新的少真真
         * ================================================= =====
         * @参数的位置要评估新位置
         * @参数currentBestLocation目前位置锁定到要比较新一
        * /
        保护布尔isBetterLocation(地点位置,位置currentBestLocation){
            尝试
            {
            (0)location.setSpeed​​; // preSET            如果(currentBestLocation == NULL){
                //一个新的位置总是比没有好位置
                如果(mEnableDebug)Logger.Log(getBaseContext(),修:第一个位置);
                返回true;
            }            //检查新的位置修正是新还是旧,
            长timeDelta = location.getTime() - currentBestLocation.getTime();
            布尔isSignificantlyNewer = timeDelta> TWO_MINUTES;
            布尔isSignificantlyOlder = timeDelta< -TWO_MINUTES;
            布尔isNewer = timeDelta> 0;            //如果它因为目前的位置已经超过两分钟,使用新位置
            //因为用户可能已经移动
            如果(isSignificantlyNewer){
                如果(mEnableDebug)Logger.Log(getBaseContext(),修:isSignificantlyNewer);
                返回true;
            //如果新的位置是两分多钟老,它必须是雪上加霜
            }否则如果(isSignificantlyOlder){
                如果(mEnableDebug)Logger.Log(getBaseContext(),被拒绝:isSignificantlyOlder);
                返回false;
            }            //检查新的位置锁定是否或多或少准确
            INT accuracyDelta =(int)的(location.getAccuracy() - currentBestLocation.getAccuracy());
            布尔isLessAccurate = accuracyDelta> 0;
            布尔isMoreAccurate = accuracyDelta< 0;
            布尔isSignificantlyLessAccurate = accuracyDelta> 200;            //检查新旧位置都来自同一个供应商
            布尔isFromSameProvider = isSameProvider(location.getProvider(),
                    currentBestLocation.getProvider());            //使用及时性和准确性的组合确定位置的质量
            如果(isMoreAccurate){
                location.setSpeed​​(CalculateSpeed​​(位置,currentBestLocation));
                如果(mEnableDebug)Logger.Log(getBaseContext(),修:isMoreAccurate);
                返回true;
            }否则如果(isNewer&安培;&安培;!isLessAccurate){
                location.setSpeed​​(CalculateSpeed​​(位置,currentBestLocation));
                如果(mEnableDebug)Logger.Log(getBaseContext(),修:isNewer而不是isLessAccurate);
                返回true;
            }否则如果(isNewer&安培;&安培;!isSignificantlyLessAccurate和放大器;&安培; isFromSameProvider){
                location.setSpeed​​(CalculateSpeed​​(位置,currentBestLocation));
                如果(mEnableDebug)Logger.Log(getBaseContext(),修:isNewer和LessAccurate但是从同一供应商);                返回true;
            }            如果(mEnableDebug)Logger.Log(getBaseContext(),被拒绝:???);            返回false;
            }
            赶上(例外五)
            {
                updateNotification(Debug3:+ e.getMessage());
                返回false;
            }
        }        / **两个提供检查是否相同* /
        保护布尔isSameProvider(字符串provider1,Provider2的字符串){
            如果(provider1 == NULL){
              Provider2的回报== NULL;
            }
            返回provider1.equals(Provider2之间);
        }        / * GPS方法:EOF * /        / * ------------------------------------------------ -BAT方法* /
        保护广播接收器mBatInfoReceiver =新的广播接收器(){            @覆盖            公共无效的onReceive(上下文为arg0,意图意图){              INT级= intent.getIntExtra(水平,0);
              双电压= intent.getIntExtra(电压,0);
              双batteryTemperature = intent.getIntExtra(温度,0);              //更新电池电量。
              mBatteryLevel =将String.valueOf(水平);              如果(水平< 31)
              {
                  mMainActivity.mtxtBatteryInfo.setText(级别:+ Double.toString(水平)+请连接充电器。);
                  mMainActivity.mtxtBatteryInfo.setTextColor(0xffff0033);
              }
              其他
              {
                  mMainActivity.mtxtBatteryInfo.setText(级别:+ Double.toString(水平)+%电压:+将String.valueOf(Double.toString(电压/ 1000.0))+温度+ Double.toString(batteryTemperature /10.0 )+C);
                  mMainActivity.mtxtBatteryInfo.setTextColor(0xff99ff33);
              }
            }          };
        / * BAT方法:EOF * /
}


解决方案

我可以看到一些在这里的问题。

首先,在onStart(意向意图,诠释startId)是德precated,你并不需要实现这个方法(特别是如果你要做的就是 super.onStart(意向,startId) ;

二,你不必取消重复闹钟设置之前,作为报警经理会为你做的。

更重要的是,你应该只获得您onStartCommand方法的持续时间之后锁。获得它在一开始,然后在最后释放它 - 一个理想里面最后块,以便在出现异常的情况下锁仍然释放。目前该锁获得了第一次收到一个意图,然后一直保持到服务终止,$ P $从冬眠时,它无关pventing的CPU - 这将影响电池的寿命

对于意图反复运 - 如果正在服务的变量重新初始化,然后它听起来像你的服务正在被重新启动的Andr​​oid,因为它死了。您在检查logcat中(当运行连接)任何堆栈跟踪?也许进程ID添加到您的日志输出,所以你可以发现,当这种情况正在发生。

这可能是Android是杀死你的服务,如果它认为它已经变得反应迟钝。你已经把相当多的处理器中,你可能要考虑分解为单独的类本 - 那么它会更容易COM prehend什么服务在做什么,它是怎么了?

I develop a GPS Tracking app on android. I use AlarmManager to wake up the device every 5 minutes. I developed a log file that shows that the application works great until a moment when I receieve public int onStartCommand(Intent intent, int flags, int startId) with startId = 1 again .... in this case I noticed that all variables are reset so I initialize all variables again .. the issue is that once this happens I keep getting same event with startID = 1 again and after few calls the app just stops until i open the ActivityForm and bind with service again !!!

the log is here for the bad events:

@Jun 17, 2011 3:29:31 AM onStartCommand:flags:0:startId:3:intent:Intent { cmp=com.usegps2_1/.LocationService }
@Jun 17, 2011 3:34:10 AM onStartCommand:flags:0:startId:1:intent:Intent { cmp=com.usegps2_1/.LocationService }
@Jun 17, 2011 3:34:10 AM StartService with mbServiceStarted=TRUE
@Jun 17, 2011 3:34:11 AM call InitGPS
@Jun 17, 2011 3:34:11 AM lastKnownLocation: Location[mProvider=gps,mTime=1308274198000,mLatitude=30.10493179906883,mLongitude=31.379563305705755,mHasAltitude=true,mAltitude=85.0,mHasSpeed=true,mSpeed=0.0,mHasBearing=true,mBearing=313.8908,mHasAccuracy=true,mAccuracy=10.0,mExtras=Bundle[mParcelledData.dataSize=4]]
@Jun 17, 2011 4:48:17 AM onStartCommand:flags:0:startId:1:intent:Intent { cmp=com.usegps2_1/.LocationService }
@Jun 17, 2011 4:48:17 AM StartService with mbServiceStarted=TRUE
@Jun 17, 2011 4:48:17 AM call InitGPS
@Jun 17, 2011 4:48:17 AM lastKnownLocation: Location[mProvider=gps,mTime=1308274198000,mLatitude=30.10493179906883,mLongitude=31.379563305705755,mHasAltitude=true,mAltitude=85.0,mHasSpeed=true,mSpeed=0.0,mHasBearing=true,mBearing=313.8908,mHasAccuracy=true,mAccuracy=10.0,mExtras=Bundle[mParcelledData.dataSize=4]]

GPS Service code is here:

import java.text.DateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import android.media.*;

public class LocationService extends Service {

    /* ------------------------------------- Attributes */
    int NOTIFICATION_ID = 11283;
    private NotificationManager mNotificationManager; 
    public MainActivity mMainActivity = null;
    protected PowerManager.WakeLock mWakeLock;
    protected AlarmManager mAlarMgr;
    protected PendingIntent AlarmIntent ;

    protected Notification mNotification;
    protected PendingIntent mContentIntent;

    protected static final double d2r = Math.PI / 180.0;

    // Location Variables
    protected static final int mAlarmRepeatRate = 5 * 60 * 1000;
    protected static final int mLocationTimeMinUpdate = 20000;      // minimum time for wait between signals.
    protected static final int mLocationDistanceMinUpdate =  25;    // minimum meters before call back
    protected static final int TWO_MINUTES =  2 * 60 * 1000;        // used to define old readings

    // TODO : This should be a function in speed. with min & max value.
    protected static final int MIN_MapRefreshRate= 10000 ; // rate used to send to webservice.

    protected long mLocationNextSentTime; 
    public String mDeviceID=null;
    public String mBatteryLevel=null;
    protected String mMobileServiceURL = "http://locationbook.net/Tracking.asmx";
    public Boolean mUseGPSOnly;
    public Boolean mEnableBeeps ;
    public Boolean mEnableDebug;
    public String mSpeedText="0";
    public boolean mbBeepStarted = false;
    public boolean mbStarted = false;


    public boolean mbServiceStarted = false;

    public Location mLastLocation =null;


    protected LocationManager mlocManager ;
    protected MainGpsListener mMainGpsListener;
    protected MainLocationListener mlocListenerGPS; 
    protected MainLocationListener mlocListenerNW;

    protected ToneGenerator mTG;
    protected float mSpeed;
    // This is the object that receives interactions from clients.  See
    // RemoteService for a more complete example.
    private final IBinder mBinder = new LocalBinder();

    /* EOF Attributes */


     /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
        LocationService getService() {
            return LocationService.this;
        }
    }

    /**
     * @see android.app.Service#onBind(Intent)
     */
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Put your code here
        return mBinder;
    }

    /**
     * @see android.app.Service#onCreate()
     */
    @Override
    public void onCreate() {
        super.onCreate();


        // TODO: Input this here to re-create when alarm calls.
        mbServiceStarted = false;
        com.usegps2_1.Logger.Log(getBaseContext(), "onCreate");

    }

    /**
     * @see android.app.Service#onStart(Intent,int)
     */
    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Put your code here
        super.onStart(intent, startId);

    }


    @Override
    public void onDestroy() {

        if (mEnableDebug)Logger.Log(getBaseContext(), "onDestroy");

        mAlarMgr.cancel(AlarmIntent);

        if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_0,1500);
        if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);

        // Cancel the persistent notification.
        mNotificationManager.cancel(NOTIFICATION_ID); // Remove Notification

        if (mbStarted == true)
        {
            mlocListenerNW.mLocationService=null;
            mlocListenerGPS.mLocationService=null;
            mMainGpsListener.mLocationService=null;
            mlocManager.removeUpdates(mlocListenerNW);
            mlocManager.removeUpdates(mlocListenerGPS);
            mlocManager=null;
        }


        /** I assume that this function will not be called except when I want to close
        * as mWakeLock prevent it from closing. so we can allow closing the screen here.
        */
        mWakeLock.release();

        // Tell the user we stopped.
        Toast.makeText(this, "Service Exit", Toast.LENGTH_SHORT).show();


        super.onDestroy();
    }


     public int onStartCommand(Intent intent, int flags, int startId) {
           // We want this service to continue running until it is explicitly
           // stopped, so return sticky.

            /**
             * http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html
             * 1- An application calls startService().
             * 2- That service gets onCreate(), onStart(), and then spawns a background thread to do some work.
             * 3- The system is tight on memory, so has to kill the currently running service.
             * 4- Later when memory is free, the service is restarted, and gets onCreate() called but not onStart() 
             * because there has not been another call to startService() with a new Intent command to send it.
             * START_STICKY is basically the same as the previous behavior,
             *  
             * where the service is left "started" and will later be restarted by the system. 
             * The only difference from previous versions of the platform is that 
             * it if it gets restarted because its process is killed, 
             * onStartCommand() will be called on the next instance of the service with a null Intent instead of not being called at all. 
             * Services that use this mode should always check for this case and deal with it appropriately.
             * 
             * from Android Book.
             * [2] The flag parameter can be used to discover how the Service was started. In particular you can use the
             * code snippet shown in Listing 9-2 to determine if either of the following cases is true:
             * ? START_FLAG_REDELIVERY Indicates that the Intent parameter is a redelivery caused by the
             * system run time’s having terminated the Service before it was explicitly stopped by a call to stopSelf.
             * ? START_FLAG_RETRY Indicates that the Service has been restarted after an abnormal termination.
             * Passed in when the Service was previously set to START_STICKY.
             */


            com.usegps2_1.Logger.Log(getBaseContext(), "onStartCommand:flags:" + String.valueOf(flags) + ":startId:" + String.valueOf(startId)+ ":intent:" + intent.toString());

            if (intent == null)
            {
                // TODO If it’s a restart, do something.
                updateNotification("Restarted");
                if (mTG != null)
                {
                    if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_5,2000);
                }
            }



            //mAlarMgr.cancel(null);

            // see [2]
            if ((flags & START_FLAG_RETRY) == 0) {
                // FROM DEBUGGING the above condition is wrong it should be != 0.
                // PLease check and review before writing code here.
            }
            else {
                // TODO Alternative background process.
            }

            StartService();

           return  START_STICKY;
         }

     /**
      * Read preference settings and apply them.
      */
     public void ApplyPreferenceSttings()
     {
        mMobileServiceURL = CustomPreferenceManager.GetServiceURL(getApplication());
        mUseGPSOnly= CustomPreferenceManager.GetGPSOnly(getApplication());
        mEnableBeeps= CustomPreferenceManager.GetBeepsEnabled(getApplication()) ;
        mEnableDebug =  CustomPreferenceManager.GetDebugEnabled(getApplication());
     }

     /**
      * Called from outside to start service.
      */
     public void StartService ()
     {


         if (mbServiceStarted == false)
         {
             mbServiceStarted = true;

            // TODO: please remember to use PARTIAL_WAKE_LOCK instead of .SCREEN_DIM_WAKE_LOCK
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
            mWakeLock.acquire();

            ApplyPreferenceSttings();

            if (mEnableDebug)Logger.Log(getBaseContext(), "StartService re-initialize=TRUE");


            TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
            mDeviceID = telephonyManager.getDeviceId();


            showNotification();

            mTG = new ToneGenerator (1,80);

            if (mAlarMgr != null)
            if (mEnableDebug)Logger.Log(getBaseContext(), "mAlarMgr is true");

            mAlarMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
            Intent intentToFire = new Intent (GPSBroadcastReceiver.ReceiverName);
            AlarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);
            mAlarMgr.cancel(AlarmIntent); //Remove any alarms with a matching Intent. [BUG] avoid creating many alarms ... caused multipl alarm call with mbServiceStarted=False when check debugging files.
            mAlarMgr.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + mAlarmRepeatRate , mAlarmRepeatRate, AlarmIntent);

            // Register in Battery
            this.registerReceiver(this.mBatInfoReceiver,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

             StartLocation();
         }
         else
         {

             //updateNotification("called again while running");
         }

         // */ 
     }



     protected void showNotification ()
        {
            mNotificationManager = (NotificationManager) getSystemService (Context.NOTIFICATION_SERVICE);
            // Define Notification
            mNotification = new Notification(R.drawable.step, "Tracking on", System.currentTimeMillis());
            mNotification.flags = Notification.FLAG_ONGOING_EVENT;
            // Define Notification Action
            Intent  intent = new Intent(getApplicationContext(), MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            mContentIntent = PendingIntent.getActivity(LocationService.this, 0,intent, PendingIntent.FLAG_CANCEL_CURRENT);

            // Set Notification
            mNotification.setLatestEventInfo(LocationService.this,getText(R.string.app_name),"click to display main screen",mContentIntent);
            // Add it
            mNotificationManager.notify(NOTIFICATION_ID, mNotification);
        }

     protected void updateNotification (CharSequence Description)
      {
          if (mNotification ==null) return ;
          mNotification.when=System.currentTimeMillis();
            // Set Notification
          mNotification.setLatestEventInfo(LocationService.this,getText(R.string.app_name),Description,mContentIntent);
            // Add it
          mNotificationManager.notify(NOTIFICATION_ID, mNotification);
      }
     /*-------------------------------------------------GPS Methods*/

      protected void StartLocation ()
        {
            if (mbStarted == true)
            {
                Toast.makeText( getApplicationContext(),"already running",Toast.LENGTH_SHORT).show();
                return ; 
            }

            if (mEnableDebug)Logger.Log(getBaseContext(), "InitGPS true");

            mbStarted = true;
            mLocationNextSentTime = 0 ; // Send once u get data
            if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_1,1000);




            // Use the LocationManager class to obtain GPS locations
            mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
            Toast.makeText( getApplicationContext(),"Started",Toast.LENGTH_SHORT).show();


            Location loc= mlocManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

            // try to read current position
            if(loc != null){
                mLastLocation=loc;
                if (mEnableDebug)Logger.Log(getBaseContext(), "lastKnownLocation: " + loc.toString());
            }
            else
            {
                updateNotification ("getting location");

            }

            mlocListenerGPS = new MainLocationListener(this);
            mlocListenerNW  = new MainLocationListener(this);
            mlocListenerGPS.mProvider="GPS";
            mlocListenerNW.mProvider="NW";

            mMainGpsListener = new MainGpsListener(this);
            // Define a listener that responds to location updates


            mlocManager.addGpsStatusListener(mMainGpsListener);
            mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, mLocationTimeMinUpdate, mLocationDistanceMinUpdate, mlocListenerGPS);
            mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, mLocationTimeMinUpdate, mLocationDistanceMinUpdate, mlocListenerNW);

            if (mEnableDebug)Logger.Log(getBaseContext(), "GPS reinitialized");

            // */
        }



        public void UpdateLocation (Location loc, String Provider)
        {

            try
            {
                if (mUseGPSOnly  && (Provider != "GPS")) return ;

                if (mbStarted == false)
                {
                    updateNotification("false");
                }


                if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_9,200);

                String E = loc.toString();
                if (mEnableDebug)Logger.Log(getBaseContext(), "New Location");
                if (mEnableDebug)Logger.Log(getBaseContext(), loc.toString());

                if (isBetterLocation (loc,mLastLocation)==false)
                {
                    updateNotification ("location ignored");
                    return ;
                }


                mLastLocation = loc;

                mMainActivity.mtxtTime.setText(DateFormat.getDateInstance().format(new Date()));
                mMainActivity.mtxtLatitude.setText(loc.getLatitude() + " lat");
                mMainActivity.mtxtLongitude.setText(loc.getLongitude() + " lng");

                float speed = loc.getSpeed(); // value if set by GetSpeed that is called insite isBetterLocation
                mSpeedText=Float.toString(speed) ;
                mMainActivity.mtxtSpeed.setText(mSpeedText + " km/s");



                if ((loc.getTime() > mLocationNextSentTime))
                {

                    mLocationNextSentTime = (long) (loc.getTime() + MIN_MapRefreshRate * ( 140 - speed)/ 140);

                    if (mEnableDebug)Logger.Log(getBaseContext(), "Next HTTP: " + String.valueOf(mLocationNextSentTime));

                    WebMethodProxy client = new WebMethodProxy(mMobileServiceURL + "/UpdateLocation");
                    client.AddParam("guid", mDeviceID);
                    client.AddParam("latitude",Double.toString(loc.getLatitude()));
                    client.AddParam("longitude", Double.toString(loc.getLongitude()));
                    client.AddParam("speed", mSpeedText);
                    client.AddParam("battery",mBatteryLevel);       

                    //if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_5,500);

                    try {
                        client.Execute(WebMethodProxy.RequestMethod.POST_JSON);
                    } catch (Exception e) {
                        e.printStackTrace();

                        // TODO : error message cannot connect to server
                        if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_9,2500);
                        String err = (e.getMessage() == null)?"GPS Error":e.getMessage();

                        if (mEnableDebug)Logger.Log(getBaseContext(), "Failed: " + err);

                        Log.e("TrackGPS",err);
                        mMainActivity.mtxtMessage.setText("Cannot reach Internet to update location.");
                        return ;
                    }

                    String response = client.getResponse();
                    response = (response ==null)?"no web reply":response;

                    if (mEnableDebug)Logger.Log(getBaseContext(), "HTTP DONE: " + response );


                    Toast.makeText( getApplicationContext(),"Updated[" + Provider + "]:" + response,Toast.LENGTH_SHORT).show();
                    updateNotification ("location updated");

                }
                else
                {
                    updateNotification ("location ignored.");
                }
            }
            catch (Exception e)
            {
                if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);
                 String err = (e.getMessage() == null)?"GPS Error":e.getMessage();
                 Log.e("TrackGPS",err);
                 updateNotification ("DEBUG1: " + e.getMessage());
                 return ; 
            }

        }


        /**
         * Returns distance in meters between two points.
         * @param NewLocation
         * @param CurrentLocation
         * @return
         */
        protected float CalculateSpeed (Location NewLocation, Location CurrentLocation) {
            try
            {
            double dlong = (NewLocation.getLongitude() - CurrentLocation.getLongitude()) * d2r;
            double dlat = (NewLocation.getLatitude() - CurrentLocation.getLatitude()) * d2r;
            double a = Math.pow(Math.sin(dlat/2.0), 2) + Math.cos(CurrentLocation.getLatitude()*d2r) * Math.cos(NewLocation.getLatitude()*d2r) * Math.pow(Math.sin(dlong/2.0), 2);
            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
            double d = 6367000 * c;
            double TimeDelta = NewLocation.getTime() - CurrentLocation.getTime();
            return (float) (d/TimeDelta) * 3600;
            }
            catch (Exception e)
            {
                if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);
                 Log.e("TrackGPS",e.getMessage());
                 updateNotification ("DEBUG2: " + e.getMessage());
                return 0;
            }

        }

        /** Determines whether one Location reading is better than the current Location fix
         * Logic:
         *  if too old return FALSE.
         *  if too new return TRUE anyway as the current is too old.
         *  if more accurate then return TRUE 
         *  if newer and same or more accurate then return TRUE.
         *  if newer and less accurate but same provider return TRUE.
         *  ------------------------------------------------------
         *  Time        Accuracy    Same Provider       Return
         *  ------------------------------------------------------
         *  Too Old         x           x               FALSE
         *  Too New         x           x               TRUE
         *  Older         Plus          x               TRUE
         *  Newer         Plus          x               TRUE
         *  Newer         Same          x               TRUE
         *  Newer         Less        TRUE              TRUE
         *  ======================================================
         * @param location  The new Location that you want to evaluate
         * @param currentBestLocation  The current Location fix, to which you want to compare the new one
        */
        protected boolean isBetterLocation(Location location, Location currentBestLocation) {
            try
            {
            location.setSpeed(0); // preset

            if (currentBestLocation == null) {
                // A new location is always better than no location
                if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: first location");
                return true;
            }

            // Check whether the new location fix is newer or older
            long timeDelta = location.getTime() - currentBestLocation.getTime();
            boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
            boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
            boolean isNewer = timeDelta > 0;

            // If it's been more than two minutes since the current location, use the new location
            // because the user has likely moved
            if (isSignificantlyNewer) {
                if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isSignificantlyNewer");
                return true;
            // If the new location is more than two minutes older, it must be worse
            } else if (isSignificantlyOlder) {
                if (mEnableDebug)Logger.Log(getBaseContext(), "Rejected: isSignificantlyOlder");
                return false;
            }

            // Check whether the new location fix is more or less accurate
            int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
            boolean isLessAccurate = accuracyDelta > 0;
            boolean isMoreAccurate = accuracyDelta < 0;
            boolean isSignificantlyLessAccurate = accuracyDelta > 200;

            // Check if the old and new location are from the same provider
            boolean isFromSameProvider = isSameProvider(location.getProvider(),
                    currentBestLocation.getProvider());

            // Determine location quality using a combination of timeliness and accuracy
            if (isMoreAccurate) {
                location.setSpeed(CalculateSpeed (location,currentBestLocation));
                if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isMoreAccurate");
                return true;
            } else if (isNewer && !isLessAccurate) {
                location.setSpeed(CalculateSpeed (location,currentBestLocation));
                if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isNewer and not isLessAccurate");
                return true;
            } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
                location.setSpeed(CalculateSpeed (location,currentBestLocation));
                if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isNewer and LessAccurate but from same provider");

                return true;
            }

            if (mEnableDebug)Logger.Log(getBaseContext(), "Rejected: ???");

            return false;
            }
            catch (Exception e)
            {
                updateNotification ("Debug3: " + e.getMessage());
                return false;
            }
        }

        /** Checks whether two providers are the same */
        protected boolean isSameProvider(String provider1, String provider2) {
            if (provider1 == null) {
              return provider2 == null;
            }
            return provider1.equals(provider2);
        }

        /*GPS Methods:EOF*/



        /*-------------------------------------------------BAT Methods*/
        protected BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){

            @Override

            public void onReceive(Context arg0, Intent intent) {

              int level = intent.getIntExtra("level", 0);
              double voltage= intent.getIntExtra("voltage", 0) ;
              double batteryTemperature = intent.getIntExtra("temperature", 0); 

              // update battery level.
              mBatteryLevel = String.valueOf(level);

              if (level < 31)
              {
                  mMainActivity.mtxtBatteryInfo.setText("level: " + Double.toString(level) + " pls connect to charger.");
                  mMainActivity.mtxtBatteryInfo.setTextColor(0xffff0033);
              }
              else
              {
                  mMainActivity.mtxtBatteryInfo.setText("level: " + Double.toString(level) + "% voltage: " + String.valueOf(Double.toString(voltage / 1000.0)) + " Temp: " + Double.toString(batteryTemperature /10.0) + " c");
                  mMainActivity.mtxtBatteryInfo.setTextColor(0xff99ff33);
              }
            }

          };
        /*BAT Methods:EOF*/
}

解决方案

I can see a number of issues here.

First, onStart(Intent intent, int startId) is deprecated, you don't need to implement this method (especially if all you do is super.onStart(intent, startId);).

Second, you don't need to cancel the repeating alarm before you set it, as the alarm manager will do that for you.

Most importantly, you should only acquire the wake lock for the duration of your onStartCommand method. Acquire it at the beginning, then release it at the end - ideally inside a finally block so that in the event of an exception the lock is still released. At the moment the lock is acquired the first time an intent is received, and then held until the service is terminated, preventing the CPU from hibernating when it has nothing to do - this will affect battery life.

As for repeated delivery of the intent - if your service variables are being re-initialised then it sounds like your service is being restarted by Android because it died. Have you checked in the logcat (when running connected) for any stack traces? Maybe add the process ID to your log output so you can spot when this is happening.

It is possible that Android is killing your service, if it thinks it has become unresponsive. You've put quite a bit of processing in, you might want to think about decomposing this into separate classes - then it will be easier to comprehend what the service is doing and where it is going wrong.

这篇关于AlarmManager&安培; onStartCommand的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆