Java 具有打盹模式的前台位置服务未按预期工作

Java 具有打盹模式的前台位置服务未按预期工作,java,android,android-6.0-marshmallow,android-7.0-nougat,doze,Java,Android,Android 6.0 Marshmallow,Android 7.0 Nougat,Doze,我创建了一个示例前台服务,以检查是否有可能每隔15分钟或30分钟从后台获取位置。由于引入了打盹模式,报警管理器无法在准确的时间工作 在前台服务中,我尝试使用处理程序post delay,但这也不起作用,因为我的间隔长达3小时。在下面的代码中,我使用了ScheduledThreadPoolExecutor,它的性能甚至更差。我被耽搁了12个小时。我已经在android 6.0上测试过了 有人能建议一个解决这个问题的方法吗 package com.hitec16.foregroundservicet

我创建了一个示例前台服务,以检查是否有可能每隔15分钟或30分钟从后台获取位置。由于引入了打盹模式,报警管理器无法在准确的时间工作

在前台服务中,我尝试使用处理程序post delay,但这也不起作用,因为我的间隔长达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();
    }
}
package com.hitec16.foregroundservicetest;
导入android.app.Notification;
导入android.app.pendingent;
导入android.app.Service;
导入android.content.Intent;
导入android.location.location;
导入android.os.Bundle;
导入android.os.IBinder;
导入android.os.Looper;
导入android.support.annotation.NonNull;
导入android.support.annotation.Nullable;
导入android.support.v4.app.NotificationCompat;
导入android.util.Log;
导入android.widget.Toast;
导入com.google.android.gms.common.ConnectionResult;
导入com.google.android.gms.common.api.GoogleAppClient;
导入com.google.android.gms.common.api.pendingreult;
导入com.google.android.gms.common.api.Status;
导入com.google.android.gms.location.FusedLocationProviderApi;
导入com.google.android.gms.location.LocationListener;
导入com.google.android.gms.location.LocationRequest;
导入com.google.android.gms.location.LocationServices;
导入java.text.DateFormat;
导入java.util.Date;
导入java.util.concurrent.Executors;
导入java.util.concurrent.ScheduledThreadPoolExecutor;
导入java.util.concurrent.TimeUnit;
公共类MyService扩展服务
实现LocationListener、GoogleAppClient.ConnectionCallbacks、GoogleAppClient.OnConnectionFailedListener{
私有静态最终字符串TAG=“MyService”;
专用静态最终长间隔=1000*10;
专用静态最终最长最快_间隔=1000*5;
专用静态最终长等待时间间隔=1000*30;
私有ScheduledThreadPoolExecutor;
私有整数mCounter=0;
私有FusedLocationProviderApi FusedLocationProviderApi=LocationServices.FusedLocationApi;
位置请求mLocationRequest;
GoogleapClient MGoogleapClient;
位置mCurrentLocation;
私有字符串mLastUpdateTime;
公共MyService(){
}
@凌驾
公共IBinder onBind(意向){
//TODO:将通信通道返回到服务。
//抛出新的UnsupportedOperationException(“尚未实现”);
返回null;
}
@凌驾
public void onCreate(){
super.onCreate();
}
@凌驾
公共int onStartCommand(最终意图、最终int标志、最终int startId){
Thread Thread=新线程(new Runnable(){
@凌驾
公开募捐{
Looper.prepare();
onStart(意向、标志、startId);
loop.loop();
}
});
thread.start();
//onStart(意向、标志、startId);
返回开始时间;
}
私有void onStart_u2;(Intent-Intent、int-flags、int-startId){
if(intent.getAction().equals(Constants.STARTFOREGROUND_ACTION)){
Logger.d(“收到启动前景意图”);
createLocationRequest();
mgoogleapclient=新的Googleapclient.Builder(此)
.addApi(LocationServices.API)
.addConnectionCallbacks(此)
.addOnConnectionFailedListener(此)
.build();
连接到ogleapi();
showNotification();
Toast.makeText(getApplicationContext(),“服务已启动!”,Toast.LENGTH\u SHORT.show();
Logger.d(“工作完成”);
//fetchLocationReach();
mExecutor=(ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(2);
mExecutor.scheduleWithFixedDelay(新的Runnable(){
@凌驾
公开募捐{
试一试{
startLocationUpdates();
}捕获(例外e){
Log.d(getClass().getSimpleName(),“捕获异常:”+e.getMessage());
}
Log.d(“测试”、“测试”);
}
},30,60*15,时间单位为秒);
}
}
私有void showNotification(){
Intent notificationIntent=新的Intent(this,MainActivity.class);
notificationIntent.setAction(常量.MAIN_动作);
notificationIntent.setFlags(Intent.FLAG\u活动\u新任务
|意图。标记活动(清除任务);
PendingEvent PendingEvent=PendingEvent.getActivity(此,0,
通知意图,0);
Notification Notification=新建NotificationCompat.Builder(此)
.setContentTitle(“融合定位服务”)
.setTicker(“股票代码文本”)
.setContentText(“我的位置”)
.setSmallIcon(R.mipmap.ic_启动器)
.setContentIntent(挂起内容)
.setContentIntent(挂起内容)
.正在进行(正确)
.build();
startForeground(常量.通知\ ID.前台\服务,
通知);
}
受保护的void createLocationRequest(){
mlLocationRequest=新位置请求();
mlLocationRequest.setInterval(间隔);
mLocationRequest.SetFastTestInterval(最快间隔);
mLocationRequest.setPriority(位置请求.优先级高精度);
}
受保护的void stopLocationUpdates(){
LocationServices.FusedLocationApi.RemovelocationUpdate(
mGoogleApiClient,MyService.this);
mCounter=0;
Logger.d(“位置更新已停止…”。。。。