打盹模式的前台位置服务无法按预期工作

时间:2017-04-21 05:02:46

标签: java android android-6.0-marshmallow android-7.0-nougat doze

我创建了一个示例前台服务,以检查是否可以在每15分钟或30分钟后从后台获取位置。随着打盹模式的介绍,报警管理器在准确的时间不起作用。

在前台服务中,我尝试使用处理程序后延迟,但这也不起作用,因为我得到的间隔最多3小时。在下面的代码中我使用了ScheduledThreadPoolExecutor,它表现得更糟。我迟到了12个小时。我已经在Android 6.0上测试了这个。

有人可以为此建议解决这个问题吗?

package com.hitec16.foregroundservicetest;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MyService extends Service
        implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "MyService";
    private static final long INTERVAL = 1000 * 10;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    private static final long WAIT_INTERVAL = 1000 * 30;

    private ScheduledThreadPoolExecutor mExecutor;

    private int mCounter = 0;

    private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mCurrentLocation;
    private String mLastUpdateTime;

    public MyService() {
    }


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
//        throw new UnsupportedOperationException("Not yet implemented");
        return null;
    }

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

    @Override
    public int onStartCommand(final Intent intent, final int flags, final int startId) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                onStart_(intent, flags, startId);
                Looper.loop();
            }
        });
        thread.start();
//        onStart_(intent,flags,startId);

        return START_STICKY;
    }

    private void onStart_(Intent intent, int flags, int startId) {
        if (intent.getAction().equals(Constants.STARTFOREGROUND_ACTION)) {
            Logger.d("Received Start Foreground Intent ");

            createLocationRequest();
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();

            connectToGoogleApi();
            showNotification();
            Toast.makeText(getApplicationContext(), "Service Started!", Toast.LENGTH_SHORT).show();
            Logger.d("work finished");

//            fetchLocationAgain();
            mExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(2);
            mExecutor.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {

                    try {

                        startLocationUpdates();
                    } catch (Exception e) {
                        Log.d(getClass().getSimpleName(), "Exception caught: " + e.getMessage());
                    }
                    Log.d("Test", "test");
                }
            }, 30, 60 * 15, TimeUnit.SECONDS);
        }
    }

    private void showNotification() {
        Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.setAction(Constants.MAIN_ACTION);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("Fused Location Service")
                .setTicker("ticker text")
                .setContentText("My Location")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .setContentIntent(pendingIntent)
                .setOngoing(true)
                .build();

        startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
                notification);
    }

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, MyService.this);
        mCounter = 0;
        Logger.d("Location update stopped .......................");
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Logger.d("onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
        try {
            startLocationUpdates();
        } catch (Exception e) {
            Log.d(getClass().getSimpleName(), "Exception caught: " + e.getMessage());
        }
    }

    @Override
    public void onConnectionSuspended(int i) {    
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Logger.d("Connection failed: " + connectionResult.toString());
    }

    @Override
    public void onLocationChanged(Location location) {
        if (mCounter < 3) {
            Log.d(getClass().getSimpleName(), "returned....");
            mCounter++;
            return;
        }
        Logger.d("Firing onLocationChanged..............................................");
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());

        Logger.d("Location latitude and longitude :" + location.getLatitude() + " ," + location.getLongitude()
                + " , Accuracy : " + location.getAccuracy() + ", location provider : " + location.getProvider() + "Time : " + mLastUpdateTime);

        stopLocationUpdates();
    }

    protected void startLocationUpdates() throws Exception {
        PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this, Looper.getMainLooper());
        Logger.d("Location update started ..............: ");
    }

    @Override
    public void onDestroy() {
        disconnectFromGoogleApi();
        Log.d(getClass().getSimpleName(), "on destroy called");
        mExecutor.shutdown();
        super.onDestroy();
    }

    private void connectToGoogleApi() {
        Logger.d("connectToGoogleApi fired ..............");
        mGoogleApiClient.connect();
    }

    private void disconnectFromGoogleApi() {
        Logger.d("disConnectFromGoogleApi fired ..............");
        mGoogleApiClient.disconnect();
    }
}

0 个答案:

没有答案