【问题标题】:Using LocationListener (with google play service) as service consume too much battery (Android 4.4.2)使用 LocationListener(带有 google play 服务)作为服务消耗太多电池(Android 4.4.2)
【发布时间】:2014-02-12 03:23:15
【问题描述】:

我有一个每 30 秒返回当前位置的服务,我的问题是该服务消耗了大约 40% 的电池。 GPS 图标始终处于活动状态,即使我增加了时间间隔。我在 Nexus 4 android 4.4.2 上看到了这个问题。一旦回调 OnLocationChanged 被调用,GPS 就会一直处于唤醒状态,这会消耗整个电池。使用我的其他手机 Nexus One android 2.2.3 时,我看不到这个问题,GPS 每 30 秒打开一次然后关闭。而且我没有电池确认。该服务使用位置请求,带有 .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY),但使用 GPS 和网络除外,情况并非如此。我认为android 4.4.2 有问题或者是Google play 服务

这是我的服务代码:

public class MyServiceGpsDebug extends Service implements       
 GooglePlayServicesClient.ConnectionCallbacks,    
 GooglePlayServicesClient.OnConnectionFailedListener,LocationListener 
 {

     IBinder mBinder = new LocalBinder();

      private LocationClient mLocationClient;
      private LocationRequest mLocationRequest;
      // Flag that indicates if a request is underway.
      private boolean mInProgress;

      private Boolean servicesAvailable = false;

      public class LocalBinder extends Binder 
      {
            public MyServiceGpsDebug getServerInstance() 
            {
                return MyServiceGpsDebug.this;
            }
      }

      @Override
      public void onCreate() 
      {
          super.onCreate();

          mInProgress = false;
          // Create the LocationRequest object
          mLocationRequest = LocationRequest.create();
          // Use high accuracy
          mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
          // Set the update interval to 5 seconds
          mLocationRequest.setInterval(Constants.UPDATE_INTERVAL);
          // Set the fastest update interval to 1 second
          mLocationRequest.setFastestInterval(Constants.FASTEST_INTERVAL);

          servicesAvailable = servicesConnected();
          mLocationClient = new LocationClient(this, this, this);   
      }

          private boolean servicesConnected() 
      {

          // Check that Google Play services is available
          int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

          // If Google Play services is available
          if (ConnectionResult.SUCCESS == resultCode) 
          {
              return true;
          } 
          else
          {
              return false;
          }
      }

      public int onStartCommand (Intent intent, int flags, int startId)
      {
          super.onStartCommand(intent, flags, startId);

          if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
            return START_STICKY;

          setUpLocationClientIfNeeded();
          if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress)
          {
            appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Started", Constants.LOG_FILE);
            mInProgress = true;
            mLocationClient.connect();
          }

          return START_STICKY;
      }

      private void setUpLocationClientIfNeeded()
      {
            if(mLocationClient == null) 
                  mLocationClient = new LocationClient(this, this, this);
      }

          @Override
      public void onLocationChanged(Location location) 
      {
          // Report to the UI that the location was updated
          String msg = Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude());
          Log.d("debug", msg);
          // Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
          appendLog(msg, Constants.LOCATION_FILE);
      }

      @Override
      public IBinder onBind(Intent intent) 
      {
            return mBinder;
      }

      public String getTime() 
      {
            SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return mDateFormat.format(new Date());
      }

      public void appendLog(String text, String filename)
      {       
             File logFile = new File(filename);
             if (!logFile.exists())
             {
                try
                {
                   logFile.createNewFile();
                } 
                catch (IOException e)
                {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                }
             }
             try
             {
                //BufferedWriter for performance, true to set append to file flag
                BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
                buf.append(text);
                buf.newLine();
                buf.close();
             }
             catch (IOException e)
             {
                // TODO Auto-generated catch block
                e.printStackTrace();
             }
      }

      @Override
      public void onDestroy()
      {
          // Turn off the request flag
          mInProgress = false;
          if(servicesAvailable && mLocationClient != null)
          {
                mLocationClient.removeLocationUpdates(this);
                // Destroy the current location client
                mLocationClient = null;
          }
          // Display the connection status
          // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
          appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Stopped", Constants.LOG_FILE);
          super.onDestroy();  
      }


      @Override
      public void onConnected(Bundle bundle) 
      {

          // Request location updates using static settings
          mLocationClient.requestLocationUpdates(mLocationRequest, this);
          appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Connected", Constants.LOG_FILE);

      }

      @Override
      public void onDisconnected() 
      {
          // Turn off the request flag
          mInProgress = false;
          // Destroy the current location client
          mLocationClient = null;
          // Display the connection status
          // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
          appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected", Constants.LOG_FILE);
      }


      @Override
      public void onConnectionFailed(ConnectionResult connectionResult) 
      {
        mInProgress = false;

          if (connectionResult.hasResolution()) 
          {

          // If no resolution is available, display an error dialog
          } else {

          }
      }


      public final class Constants 
      {

            // Milliseconds per second
            private static final int MILLISECONDS_PER_SECOND = 1000;
            // Update frequency in seconds
            private static final int UPDATE_INTERVAL_IN_SECONDS = 60;
            // Update frequency in milliseconds
            public static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
            // The fastest update frequency, in seconds
            private static final int FASTEST_INTERVAL_IN_SECONDS = 60;
            // A fast frequency ceiling in milliseconds
            public static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
            // Stores the lat / long pairs in a text file
            public static final String LOCATION_FILE = "sdcard/location.txt";
            // Stores the connect / disconnect data in a text file
            public static final String LOG_FILE = "sdcard/log.txt";


            /**
             * Suppress default constructor for noninstantiability
             */
            private Constants() {
                throw new AssertionError();
            }
      }
}

【问题讨论】:

    标签: gps android-location


    【解决方案1】:

    我在使用 Nexus 4 时遇到了类似的问题。我的应用有一项使用位置更新的服务(融合位置或 android 提供程序,而不是两者)。对于所有 android 手机,一切正常,但在 Nexus4 中,即使我杀死了应用程序(通过 DDMS,100% 停止),手机也会在一段时间后变热和变慢。唯一的解决办法是杀死 Google play 服务。 我认为 nexus 4 的播放服务存在错误。有一个肮脏的解决方案可以每 30 分钟杀死一次 Google Play 服务,例如如果 phone=nexus4,但我不知道这是否可能

    【讨论】:

    • 终于有人和我有同样的问题了:)。这个bug已经有两个问题了:code.google.com/p/android/issues/…和这个code.google.com/p/android/issues/…
    • 但是没有答案,等待修复。
    • 是的,抱歉,我想添加评论(不是答案)...我的错 :-)
    • @benomma777,更新到 Google Play Services 4.4.52 后问题似乎解决了。我的 N4 的自动更新还没有准备好,所以从 XDA (link) 获得了 apk(对于 nexus 4,你需要 -036 版本)。刚做了一个小时的压力测试(3G,gps 更新与你的值相似),一切似乎都很好。尚未将 Play 服务库更新到应用程序,因为它尚未在 android SDK 管理器中可用
    • @benomma777,我认为在您的情况下,GPS 将保持开启状态。在姜饼案例中,事情的工作方式有所不同,这可以在使用 GPS 时在系统日志中看到。也许您必须在 onLocationChanged 中停止定位并使用某个计时器重新启动。还请设置 mLocationRequest.setSmallestDisplacement(5) //e.g. 5米节省大量电池。这意味着如果用户没有移动 5 米远,GPS 可能不会取新值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 2013-05-13
    相关资源
    最近更新 更多