如何使屏幕睡眠时在后台运行Android应用程序? [英] How to make an android app run in background when the screen sleeps?

查看:226
本文介绍了如何使屏幕睡眠时在后台运行Android应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款跟踪应用程序,通过每3秒获取一次当前位置来跟踪用户。当屏幕开启时,我可以获取经纬度值。但是当屏幕睡觉时。我无法获取数据。



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不知道如何实施它,任何帮助将不胜感激。提前致谢。



注意:完成多任务处理后,应用程序可以完美运行, h2_lin>解决方案

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

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

public class MyLocationService extends Service
{
private static final String TAG =MyLocationService;
私人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;

$ b @Override
public int onStartCommand(Intent intent,int flags,int startId)
{
Log.e(TAG,onStartCommand );
super.onStartCommand(intent,flags,startId);
返回START_STICKY;


@Override
public void onCreate()
{
Log.e(TAG,onCreate);
initializeLocationManager();
尝试{
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,LOCATION_INTERVAL,LOCATION_DISTANCE,
mLocationListeners [1]);
} catch(java.lang.SecurityException ex){
Log.i(TAG,无法请求位置更新,忽略,前);
} catch(IllegalArgumentException ex){
Log.d(TAG,网络提供者不存在,+ ex.getMessage());
}
尝试{
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,LOCATION_INTERVAL,LOCATION_DISTANCE,
mLocationListeners [0]);
} catch(java.lang.SecurityException ex){
Log.i(TAG,无法请求位置更新,忽略,前);
} catch(IllegalArgumentException ex){
Log.d(TAG,gps provider does not exist+ ex.getMessage());


$ b @Override
public void onDestroy()
{
Log.e(TAG,onDestroy);
super.onDestroy();如果(mLocationManager!= null){
(int i = 0; i< mLocationListeners.length; i ++){
try {
mLocationManager.removeUpdates(mLocationListeners [i ]);
} catch(Exception ex){
Log.i(TAG,无法移除位置列表,忽略,ex);




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



//创建LocationListener类来获取位置更新
private class LocationListener实现android.location.LocationListener
{
Location mLastLocation;

public LocationListener(String provider)
{
Log.e(TAG,LocationListener+ provider);
mLastLocation =新位置(供应商);
}

@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);

$ b @Override
public void onStatusChanged(String provider,int status,Bundle extras)
{
Log.e(TAG,onStatusChanged: +提供者);





添加 MyLocationService 添加到 AndroidManifest.xml 中:

 < service android:name =。MyLocationServiceandroid:process =:mylocation_service/> 

不要忘记在 AndroidManifest.xml file:

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

从活动启动服务

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

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

更新:

您需要持有部分唤醒锁定才能运行服务在设备屏幕关闭之后。



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



获取唤醒锁:

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

释放它:

  wakeLock.release(); 


I am developing a Tracking app, which keeps tracks of the user by getting his current location for every 3 secs. I am able to fetch the lat long values when the screen is on. but when the screen sleeps. i am unable to fetch the datas.

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();
    }

The above given onLocationChanged method fetches the lat lon values for every 3 seconds. What should i do to make this method run even if the screen sleeps. I have read about Wakelock dont know how to implement it, any help will be appreciated. Thanks in advance.

Note: The app runs perfectly when multi tasking is done,

解决方案

You need to make use of Service to get location updates even if screen sleep or your app is not open.

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);
        }
    }
}

Add MyLocationService into your AndroidManifest.xml also:

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

Don't forgot to add below two permissions in your AndroidManifest.xml file:

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

Start Service from an activity:

You can start a service from an activity or other application component by passing an Intent (specifying the service to start) to startService(). The Android system calls the service's onStartCommand() method and passes it the Intent.

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

Update:

You need to hold partial wake lock to run service even after device screen off.

If you hold a partial wake lock, the CPU will continue to run, regardless of any display timeouts or the state of the screen and even after the user presses the power button.

To acquire wake lock:

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

To release it:

wakeLock.release();

这篇关于如何使屏幕睡眠时在后台运行Android应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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