首页 > 解决方案 > 位置更新在奥利奥上的 OPPO、VIVO 和 MI 手机中不起作用

问题描述

我每 5 分钟在后台更新一次位置。

我在Android Oreo 和三星和摩托罗拉设备中检查了以下代码。它工作正常。但是当我签入 MI、OPPO 和 VIVO 时,如果我从最近的任务中删除应用程序,位置不会更新

我检查了这个解决方案,但没有奏效。

public class GpsTracker extends Service
        implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener {
    final static int REQUEST_LOCATION = 199;
    private static final String TAG = GpsTracker.class.getSimpleName();
    private static final int PERMISSIONS_REQUEST_PLAYLOCATION = 2000;
    private static final int PERMISSIONS_REQUEST_LOCATION = 2001;
    public static boolean IS_SERVICE_RUNNING = false;
    protected LocationManager locationManager;
    private PowerManager pm;
    private PowerManager.WakeLock wl;
    private Handler handler = new Handler();
    private boolean mPlayLocationPermissionGranted;
    private boolean mLocationPermissionGranted;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private Location mCurrentLocation;
    private LocationTypes locationTypes = LocationTypes.HEARTBEAT;
    private GPSTrackerVM gpsTrackerVM;
    private boolean noConnect = true;
    private Runnable periodicUpdate = new Runnable() {
        @Override
        public void run() {
            handler.postDelayed(periodicUpdate, 5 * 60 * 1000 - SystemClock.elapsedRealtime() % 1000);
            // whatever you want to do below
            Utils.Log(TAG, "run: Service");
            locationTypes = LocationTypes.HEARTBEAT;
            buildGoogleApiClient();
        }
    };

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.getAction() != null) {
            showNotification();
            Utils.Log(TAG, "onStartCommand: " + intent.getAction());
            switch (intent.getAction()) {
                case AppConfig.ACTION.START_FOREGROUND_ACTION:
                    Utils.Log(TAG, "Uploading Start");
                    locationTypes = LocationTypes.HEARTBEAT;
                    handler.post(periodicUpdate);
                    break;
                case AppConfig.ACTION.START_DAY:
                    locationTypes = LocationTypes.IN;
                    buildGoogleApiClient();
                    break;
                case AppConfig.ACTION.END_DAY:
                    locationTypes = LocationTypes.OUT;
                    buildGoogleApiClient();
                    break;
            }
        }
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        gpsTrackerVM = new GPSTrackerVM(MyApp.getInstance());
        pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp:GpsTracker");
        wl.acquire();
    }

    @Override
    public void onDestroy() {
        IS_SERVICE_RUNNING = false;
        super.onDestroy();
        wl.release();
    }

    private void mStopService() {
        Utils.Log(TAG, "Sync Stop");
        if (handler != null) {
            handler.removeCallbacks(periodicUpdate);
        }
        if (mGoogleApiClient != null) {
            mGoogleApiClient.disconnect();
        }
        stopForeground(true);
        stopSelf();
    }

    private void showNotification() {
        if (!IS_SERVICE_RUNNING) {
            String channelId = AppConfig.NOTIFICATION_ID.SYNC_CHANNEL;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                channelId = createmNotificationChannel();
            }

            Intent notificationIntent = new Intent();
            notificationIntent.setAction(AppConfig.ACTION.MAIN_ACTION);
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                    notificationIntent, 0);


            Bitmap icon = BitmapFactory.decodeResource(getResources(),
                    R.drawable.ic_logo_notification);

            Notification notification = new NotificationCompat.Builder(this, channelId)
                    .setContentTitle(getString(R.string.app_name))
                    .setTicker(getString(R.string.res_sync))
                    .setContentText(getString(R.string.res_sync))
                    .setSmallIcon(R.drawable.ic_logo_notification)
                    .setPriority(Notification.PRIORITY_DEFAULT)
                    .setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
                    .setContentIntent(pendingIntent)
                    .setOngoing(true)
                    .build();
            startForeground(AppConfig.NOTIFICATION_ID.FOREGROUND_SERVICE_SYNC,
                    notification);
            IS_SERVICE_RUNNING = true;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private String createmNotificationChannel() {
        String channelId = AppConfig.NOTIFICATION_ID.SYNC_CHANNEL;
        String channelName = AppConfig.NOTIFICATION_ID.SYNC_CHANNEL;
        NotificationChannel chan = new NotificationChannel(channelId,
                channelName, NotificationManager.IMPORTANCE_DEFAULT);
        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        service.createNotificationChannel(chan);
        return channelId;
    }

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

    public synchronized void buildGoogleApiClient() {
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            retrieveCurrentLocation();
            return;
        }

        mGoogleApiClient = new GoogleApiClient.Builder(MyApp.getInstance())
                .addConnectionCallbacks(this)
                .addApi(LocationServices.API)
                .build();
        createLocationRequest();
        mGoogleApiClient.connect();
    }

    public synchronized void stopLocationUpdates() {
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
//            mGoogleApiClient.disconnect();
        }
    }

    private void createLocationRequest() {
        long UPDATE_INTERVAL_IN_MILLISECONDS = 100000;
        long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
                UPDATE_INTERVAL_IN_MILLISECONDS / 2;

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        retrieveCurrentLocation();
    }

    private void retrieveCurrentLocation() {
        Log.d(TAG, "retrieveCurrentLocation: 11");
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        // get GPS status
        boolean checkGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (!checkGPS) {
            Utils.Log(TAG, "retrieveCurrentLocation: GPS is Off");
            updateCurrentLocation(null, "GPS is Turned Off");
            return;
        }
        if (!hasLocationPermissions()) {
            Utils.Log(TAG, "retrieveCurrentLocation: Location Permission Denied");
            updateCurrentLocation(null, "Location Permission Denied");
            return;
        }

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(mLocationRequest);
        builder.setAlwaysShow(true);
        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient,
                        builder.build());

        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult result) {
                mPlayLocationPermissionGranted = false;
                final Status status = result.getStatus();
                final LocationSettingsStates states = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        mPlayLocationPermissionGranted = true;
                        requestLocations();
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        mPlayLocationPermissionGranted = false;
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        Utils.Log(TAG, "retrieveCurrentLocation: GPS is On, but they need to allow location access from Settings");
                        updateCurrentLocation(null, "GPS is On, but they need to allow location access from Settings");
                        break;
                }

            }
        });

    }

    private void requestLocations() {
        Log.d(TAG, "requestLocations: 11");

        try {
            mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

            if (mCurrentLocation == null) {
                noConnect = true;
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (noConnect) {
                            updateCurrentLocation(null, "GPS is On, but your device needs one restart to continue locating the device.");
                        }
                    }
                }, 1000);
            }
//            updateCurrentLocation(mCurrentLocation);
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                    mLocationRequest, this);
        } catch (SecurityException ex) {
            ex.printStackTrace();
        }
    }


    private boolean hasLocationPermissions() {
        if (ActivityCompat.checkSelfPermission(MyApp.getInstance(),
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED
                &&
                ActivityCompat.checkSelfPermission(MyApp.getInstance(),
                        Manifest.permission.ACCESS_COARSE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED
                ) {
            mLocationPermissionGranted = true;
        } else {
            mLocationPermissionGranted = false;
        }
        return mLocationPermissionGranted;
    }

    @Override
    public void onLocationChanged(Location location) {
        Utils.LogW(TAG, "onLocationChanged: " + location.toString());
        if (noConnect) {
            noConnect = false;
        }
        updateCurrentLocation(location, "None");
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.d(TAG, "onConnectionFailed: ");
    }


    @Override
    public void onConnectionSuspended(int i) {
        Log.d(TAG, "onConnectionSuspended: ");

    }

    public void updateCurrentLocation(Location location, String remark) {
        mCurrentLocation = location;
        GPSData gpsData = new GPSData(UUID.randomUUID().toString());
        gpsData.setLatitude(location == null ? 0 : location.getLatitude());
        gpsData.setLongitude(location == null ? 0 : location.getLongitude());
        gpsData.setAddress("None");
        gpsData.setRemarks(remark);
        gpsData.setTimeStamp(System.currentTimeMillis() / 1000L);
        gpsData.setLocationType(locationTypes.getValue());
//        Log.w(TAG, "updateCurrentLocation: " + location);
        stopLocationUpdates();
        if (locationTypes == LocationTypes.IN) {
            Utils.Log(TAG, "In Success ");
            Intent startIntent = new Intent(this, GpsTracker.class);
            startIntent.setAction(AppConfig.ACTION.START_FOREGROUND_ACTION);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(startIntent);
            } else {
                startService(startIntent);
            }
        } else if (locationTypes == LocationTypes.OUT) {
            Utils.Log(TAG, "out Success ");
            mStopService();
        } else if (locationTypes == LocationTypes.HEARTBEAT) {
            Utils.Log(TAG, "HEARTBEAT Success ");
        }
        serverUpdate(gpsData);
    }

    private void serverUpdate(GPSData gpsData) {
        gpsTrackerVM.updateLocation(gpsData);
    }

    public void onPermissionGrantStatus(boolean isGratned) {
        Log.d(TAG, "onPermissionGrantStatus() called with: isGratned = [" + isGratned + "]");
    }
}

AndroidManifest.xml

<service android:name=".services.GpsTracker" />

标签: androidlocation

解决方案


推荐阅读