如何让屏幕睡眠时在后台运行android应用程序?

问题描述:

我正在开发一个跟踪应用程序,通过每3秒获取其当前位置来跟踪用户。当屏幕开启时,我可以获取经纬度值。但是当屏幕睡觉时。我无法获取数据。如何让屏幕睡眠时在后台运行android应用程序?

CODE:

@Override 
public void onLocationChanged(Location location) { 
    mLastLocation = location; 
    if (mCurrLocationMarker != null) 
    { 
     mCurrLocationMarker.remove(); 
    } 
    latitude = location.getLatitude(); 
    longitude = location.getLongitude(); 
    latLngcurrent = new LatLng(location.getLatitude(), location.getLongitude()); 

    Toast.makeText(context,String.valueOf(latitude)+" "+String.valueOf(longitude), Toast.LENGTH_LONG).show(); 

    Log.d("onLocationChanged", String.format("latitude:%.3f longitude:%.3f",latitude,longitude)); 


    Log.d("onLocationChanged", "Exit"); 
    Toast.makeText(this, "exiting LocationChanged ", Toast.LENGTH_SHORT).show(); 
    } 

上面给出onLocationChanged方法取入纬度经度值每3秒。我应该怎么做才能让这个方法运行,即使屏幕在睡觉。我已阅读关于Wakelock不知道如何实施它,任何帮助将不胜感激。提前致谢。

注:的应用程序完美运行时,多任务的完成,

+2

使用服务https://developer.android .COM /引导/组件/服务。HTML –

+0

使用Wakelog和服务类做 –

+0

用户IntentService代替 – Amy

您需要使用Service即使屏幕睡眠或您的应用程序未打开,也可获取位置更新。

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 

public class MyLocationService extends Service 
{ 
    private static final String TAG = "MyLocationService"; 
    private LocationManager mLocationManager = null; 
    private static final int LOCATION_INTERVAL = 3000; 
    private static final float LOCATION_DISTANCE = 10f; 

    LocationListener[] mLocationListeners = new LocationListener[] { 
      new LocationListener(LocationManager.GPS_PROVIDER), 
      new LocationListener(LocationManager.NETWORK_PROVIDER) 
    }; 

    @Override 
    public IBinder onBind(Intent arg0) 
    { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     Log.e(TAG, "onStartCommand"); 
     super.onStartCommand(intent, flags, startId); 
     return START_STICKY; 
    } 

    @Override 
    public void onCreate() 
    { 
     Log.e(TAG, "onCreate"); 
     initializeLocationManager(); 
     try { 
      mLocationManager.requestLocationUpdates(
        LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, 
        mLocationListeners[1]); 
     } catch (java.lang.SecurityException ex) { 
      Log.i(TAG, "fail to request location update, ignore", ex); 
     } catch (IllegalArgumentException ex) { 
      Log.d(TAG, "network provider does not exist, " + ex.getMessage()); 
     } 
     try { 
      mLocationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, 
        mLocationListeners[0]); 
     } catch (java.lang.SecurityException ex) { 
      Log.i(TAG, "fail to request location update, ignore", ex); 
     } catch (IllegalArgumentException ex) { 
      Log.d(TAG, "gps provider does not exist " + ex.getMessage()); 
     } 
    } 

    @Override 
    public void onDestroy() 
    { 
     Log.e(TAG, "onDestroy"); 
     super.onDestroy(); 
     if (mLocationManager != null) { 
      for (int i = 0; i < mLocationListeners.length; i++) { 
       try { 
        mLocationManager.removeUpdates(mLocationListeners[i]); 
       } catch (Exception ex) { 
        Log.i(TAG, "fail to remove location listners, ignore", ex); 
       } 
      } 
     } 
    } 

    private void initializeLocationManager() { 
     Log.e(TAG, "initializeLocationManager"); 
     if (mLocationManager == null) { 
      mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 
     } 
    } 

    // create LocationListener class to get location updates 
    private class LocationListener implements android.location.LocationListener 
    { 
     Location mLastLocation; 

     public LocationListener(String provider) 
     { 
      Log.e(TAG, "LocationListener " + provider); 
      mLastLocation = new Location(provider); 
     } 

     @Override 
     public void onLocationChanged(Location location) 
     { 
      Log.e(TAG, "onLocationChanged: " + location); 
      mLastLocation.set(location); 
     } 

     @Override 
     public void onProviderDisabled(String provider) 
     { 
      Log.e(TAG, "onProviderDisabled: " + provider); 
     } 

     @Override 
     public void onProviderEnabled(String provider) 
     { 
      Log.e(TAG, "onProviderEnabled: " + provider); 
     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) 
     { 
      Log.e(TAG, "onStatusChanged: " + provider); 
     } 
    } 
} 

添加MyLocationService到您AndroidManifest.xml也:

<service android:name=".MyLocationService" android:process=":mylocation_service" /> 

不要忘了在你的AndroidManifest.xml文件中添加以下两种权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 

启动服务从活动:

通过将Intent(指定要启动的服务)传递给startService(),您可以从活动或其他应用程序组件启动service。 Android系统调用服务的方法onStartCommand()并将其传递给Intent。

Intent intent = new Intent(this, MyLocationService.class); 
startService(intent); 

更新:

您需首先partial wake lock即使设备屏幕关闭后运行的服务。

如果您保持部分唤醒锁,无论显示超时或屏幕状态如何,甚至在用户按下电源按钮后,CPU都将继续运行。

为了获得唤醒锁:

PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 
WakeLock wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock"); 
wakeLock.acquire(); 

释放它:

wakeLock.release(); 
+0

我现在就试试这个。有可能实现服务而不是扩展? @Priyank –

+0

@RakeshPolo [服务(https://developer.android.com/guide/components/services.html)是可以在后台执行长时间运行的操作的应用组件。所以,你需要扩展你的课程来实现它。在这里检查更多关于[服务类](https://developer.android.com/reference/android/app/Service.html) –

+0

我需要从具有xml设计的类中获取位置。所以我需要扩展AppCompatActivity。给我一些关于如何添加上面的代码并使其工作的思考@Priyank –

使用作业调度每3秒它也可以后得到的位置时,屏幕睡觉https://developer.android.com/reference/android/app/job/JobScheduler.html

+2

仅在API21可用+ –

+0

是马克作业调度仅在API 21+ – Jordon

+0

我知道可以将活路不管..所以我的意见.. 。? –

尝试使用ServiceJobScheduler和实施LocationListener

@Override 
public void onLocationChanged(Location location) { 
    mLastLocation = location; 
    if (mCurrLocationMarker != null) 
    { 
     mCurrLocationMarker.remove(); 
    } 
    latitude = location.getLatitude(); 
    longitude = location.getLongitude(); 
    latLngcurrent = new LatLng(location.getLatitude(),location.getLongitude()); 

    Toast.makeText(context,String.valueOf(latitude)+" "+String.valueOf(longitude), Toast.LENGTH_LONG).show(); 

    Log.d("onLocationChanged", String.format("latitude:%.3f longitude:%.3f",latitude,longitude)); 

    Log.d("onLocationChanged", "Exit"); 
    Toast.makeText(this, "exiting LocationChanged ", Toast.LENGTH_SHORT).show(); 
} 
+0

我使用的服务和实施LocationListener的,但现在得到这个[错误](http://stackoverflow.com/questions/43659683/unable-to-start-service-intent-cmp-com-appstech-knowntrack-mylocationservice)你能理解这个呢? @ user12345 –