How to make an android app run in background when the screen sleeps?

僤鯓⒐⒋嵵緔 提交于 2019-12-06 13:53:40

问题


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,


回答1:


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



回答2:


use job scheduler to get location after every 3 seconds it also works when screen sleep https://developer.android.com/reference/android/app/job/JobScheduler.html




回答3:


Try using Service or JobScheduler and implement 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();
}


来源:https://stackoverflow.com/questions/43650201/how-to-make-an-android-app-run-in-background-when-the-screen-sleeps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!