Background location service is not working in oppo and MI phones

吃可爱长大的小学妹 提交于 2019-12-12 08:59:20

问题


In my android application,location service is implemented as background service.I have tested it with different phones(like samsung,micromax,Moto,lenovo,nexus) it works fine with all.But when i run in Oppo (colorOS) and MI (MIUI OS),my service is get stopped after some time interval.I have finished MainActivity with MainActivity.this.finish().


回答1:


put following code on your activity above oncreate() method:


private FusedLocationProviderClient mFusedLocationClient;
    EasyPermissionsLocation.PermissionCallbacks permissionCallbacks = new EasyPermissionsLocation.PermissionCallbacks() {
        @Override
        public void onPermissionsGranted(int requestCode, List perms) {

            LocationRequest mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(10000);
            mLocationRequest.setFastestInterval(5000);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                        .addLocationRequest(mLocationRequest);

            SettingsClient client = LocationServices.getSettingsClient(SurveyActivity.this);
            Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
            task.addOnSuccessListener(SurveyActivity.this, new OnSuccessListener<LocationSettingsResponse>() {
                @Override
                public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(SurveyActivity.this);
                    if (ActivityCompat.checkSelfPermission(SurveyActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                            && ActivityCompat.checkSelfPermission(SurveyActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    mFusedLocationClient.getLastLocation()
                            .addOnSuccessListener(SurveyActivity.this, new OnSuccessListener<Location>() {
                                @Override
                                public void onSuccess(Location location) {
                                    if (location != null) {
                                        ((SurveyApp)getApplication()).getUser().getCurrentSurvey().setLat(""+location.getLatitude());
                                        ((SurveyApp)getApplication()).getUser().getCurrentSurvey().setLng(""+location.getLongitude());
                                        Toast.makeText(SurveyActivity.this, "Location Captured", Toast.LENGTH_SHORT).show();
                                    }
                                }
                            });

                }
            });

            task.addOnFailureListener(SurveyActivity.this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    if (e instanceof ResolvableApiException) {
                        try {
                            ResolvableApiException resolvable = (ResolvableApiException) e;
                            resolvable.startResolutionForResult(SurveyActivity.this,
                                    REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException sendEx) {
                        }
                    }
                }
            });
    }


        @Override
        public void onPermissionsDenied(int requestCode, List perms, final boolean isAutoDenied) {
            if (isAutoDenied) {
                showDialog(getString(R.string.permanently_deny_location));
            }
        }

        @Override
        public void onPermissionsPermanentlyDeclined(int requestCode, List perms) {
            showDialog(getString(R.string.permanently_deny_location));
        }
    };

call above code from oncreate method():-

   EasyPermissionsLocation.requestPermissions(this, permissionCallbacks, getString(R.string.location_message), 100, Manifest.permission_group.LOCATION);

create this class:

public class EasyPermissionsLocation {

private static final String TAG = "EasyPermissions";
private static long timeWhenRequestingStart;
private static Object object;
private static AlertDialog dialog;
private static PermissionCallbacks callbacks;
private static HashMap<String, String[]> permissionGroups;
private static boolean shouldShowRationale = false;

public static boolean hasPermissions(Context context, String... perms) {
    // Always return true for SDK < M, let the system deal with the permissions
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        Log.w(TAG, "hasPermissions: API version < M, returning true by default");
        return true;
    }

    for (String perm : perms) {
        boolean hasPerm = (ContextCompat.checkSelfPermission(context, perm) ==
                PackageManager.PERMISSION_GRANTED);
        if (!hasPerm) {
            return false;
        }
    }

    return true;
}

public static void requestPermissions(final Object object, PermissionCallbacks callback, String rationale,
                                      final int requestCode, final String... perms) {
    requestPermissions(object, callback, rationale,
            android.R.string.ok,
            android.R.string.cancel,
            requestCode, perms);
}

public static void requestPermissions(final Object obj, final PermissionCallbacks callback, String rationale,
                                      @StringRes int positiveButton,
                                      @StringRes int negativeButton,
                                      final int requestCode, final String... permission) {

    callbacks = callback;
    object = obj;
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        // only for lower of M
        callbacks.onPermissionsGranted(requestCode, new ArrayList<String>(Arrays.asList(permission)));
        return;
    }


    checkCallingObjectSuitability(object);
    final String[] perms = getActualPermissions(object,
            permission);


    if (perms.length <= 0) {
        callbacks.onPermissionsGranted(requestCode, new ArrayList<String>(Arrays.asList(permission)));
        return;
    }

    shouldShowRationale = false;
    for (String perm : perms) {
        shouldShowRationale = shouldShowRationale || shouldShowRequestPermissionRationale(object, perm);
    }

    if (shouldShowRationale) {
        if (!TextUtils.isEmpty(rationale)) {
            if (dialog == null) {
                dialog = new AlertDialog.Builder(getActivity(object))
                        .setMessage(rationale)
                        .setCancelable(false)
                        .setPositiveButton(positiveButton, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog1, int which) {
                                executePermissionsRequest(object, perms, requestCode);
                                dialog.dismiss();
                            }
                        })
                        .create();
            } else {
                dialog.setMessage(rationale);
            }
            dialog.show();
        } else {
            executePermissionsRequest(object, perms, requestCode);
        }
    } else {
        timeWhenRequestingStart = System.currentTimeMillis();
        executePermissionsRequest(object, perms, requestCode);
    }
}

private static String[] getActualPermissions(Object object, String[] permission) {
    initPermissionGroups();
    ArrayList<String> permissionList = new ArrayList<String>();
    for (String indiPerm : permission) {
        if (permissionGroups.containsKey(indiPerm)) {
            String[] arr = permissionGroups.get(indiPerm);
            for (String s : arr) {
                if (!EasyPermissionsLocation.hasPermissions(getActivity(object), s)) {
                    permissionList.add(s);
                }
            }
        } else {
            if (!EasyPermissionsLocation.hasPermissions(getActivity(object), indiPerm)) {
                permissionList.add(indiPerm);
            }
        }
    }

    Set<String> set = new LinkedHashSet<String>(permissionList);

    return set.toArray(new String[set.size()]);
}

private static void initPermissionGroups() {
    if (permissionGroups == null) {
        permissionGroups = new HashMap<String, String[]>();
        permissionGroups.put(Manifest.permission_group.CALENDAR, new String[]{Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR});
        permissionGroups.put(Manifest.permission_group.CAMERA, new String[]{Manifest.permission.CAMERA});
        permissionGroups.put(Manifest.permission_group.CONTACTS, new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.GET_ACCOUNTS});
        permissionGroups.put(Manifest.permission_group.LOCATION, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION});
        permissionGroups.put(Manifest.permission_group.MICROPHONE, new String[]{Manifest.permission.RECORD_AUDIO});
        permissionGroups.put(Manifest.permission_group.PHONE, new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE, Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG, Manifest.permission.ADD_VOICEMAIL, Manifest.permission.USE_SIP, Manifest.permission.PROCESS_OUTGOING_CALLS});
        permissionGroups.put(Manifest.permission_group.SENSORS, new String[]{Manifest.permission.BODY_SENSORS});
        permissionGroups.put(Manifest.permission_group.SMS, new String[]{Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_WAP_PUSH, Manifest.permission.RECEIVE_MMS});
        permissionGroups.put(Manifest.permission_group.STORAGE, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE});
    }
}

public static void onRequestPermissionsResult(int requestCode, String[] permissions,
                                              int[] grantResults) {

// checkCallingObjectSuitability(object); // PermissionCallbacks callbacks = (PermissionCallbacks) object;

    // Make a collection of granted and denied permissions from the request.
    boolean showRationale = false;
    ArrayList<String> granted = new ArrayList<>();
    ArrayList<String> denied = new ArrayList<>();
    for (int i = 0; i < permissions.length; i++) {
        String perm = permissions[i];
        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
            granted.add(perm);
        } else {
            showRationale = shouldShowRequestPermissionRationale(object, perm);
            if (!showRationale) {
                timeWhenRequestingStart = System.currentTimeMillis() - 2;
            }
            denied.add(perm);
        }
    }
    boolean isPermenantlyDisabled = false;
    // Report granted permissions, if any.
    if (!granted.isEmpty() && denied.isEmpty()) {
        // Notify callbacks
        callbacks.onPermissionsGranted(requestCode, granted);
    }

    //if 100% fail then check for whether timing
    else if (granted.isEmpty() && !denied.isEmpty()) {
        if (!shouldShowRationale && !showRationale) {
            if (callbacks != null) {
                callbacks.onPermissionsDenied(requestCode, denied, true);
            }
        } else {
            long diff = System.currentTimeMillis() - timeWhenRequestingStart;
            if (diff < 150) {
                //means it is permenantly disabled
                isPermenantlyDisabled = true;
                if (callbacks != null) {
                    callbacks.onPermissionsPermanentlyDeclined(requestCode, denied);
                }
            }
            Log.i("TAG", diff + "");
        }

    }
    else if (!denied.isEmpty() && !isPermenantlyDisabled) {
        callbacks.onPermissionsDenied(requestCode, denied, false);
    }

}

@TargetApi(23)
private static boolean shouldShowRequestPermissionRationale(Object object, String perm) {
    if (object instanceof Activity) {
        return ActivityCompat.shouldShowRequestPermissionRationale((Activity) object, perm);
    } else if (object instanceof Fragment) {
        return ((Fragment) object).shouldShowRequestPermissionRationale(perm);
    } else if (object instanceof android.app.Fragment) {
        return ((android.app.Fragment) object).shouldShowRequestPermissionRationale(perm);
    } else {
        return false;
    }
}

@TargetApi(23)
private static void executePermissionsRequest(Object object, String[] perms, int requestCode) {
    checkCallingObjectSuitability(object);

    if (object instanceof Activity) {
        ActivityCompat.requestPermissions((Activity) object, perms, requestCode);
    } else if (object instanceof Fragment) {
        ((Fragment) object).requestPermissions(perms, requestCode);
    } else if (object instanceof android.app.Fragment) {
        ((android.app.Fragment) object).requestPermissions(perms, requestCode);
    }
}

@TargetApi(11)
private static Activity getActivity(Object object) {
    if (object instanceof Activity) {
        return ((Activity) object);
    } else if (object instanceof Fragment) {
        return ((Fragment) object).getActivity();
    } else if (object instanceof android.app.Fragment) {
        return ((android.app.Fragment) object).getActivity();
    } else {
        return null;
    }
}

private static void checkCallingObjectSuitability(Object object) {
    // Make sure Object is an Activity or Fragment
    boolean isActivity = object instanceof Activity;
    boolean isSupportFragment = object instanceof Fragment;
    boolean isAppFragment = object instanceof android.app.Fragment;
    boolean isMinSdkM = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;

    if (!(isSupportFragment || isActivity || (isAppFragment && isMinSdkM))) {
        if (isAppFragment) {
            throw new IllegalArgumentException(
                    "Target SDK needs to be greater than 23 if caller is android.app.Fragment");
        } else {
            throw new IllegalArgumentException("Caller must be an Activity or a Fragment.");
        }
    }

}

public interface PermissionCallbacks {

    void onPermissionsGranted(int requestCode, List<String> perms);

    void onPermissionsDenied(int requestCode, List<String> perms, boolean isAutoDenied);

    void onPermissionsPermanentlyDeclined(int requestCode, List<String> perms);

}

}


add in manifest:-

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

add following in app gradle file:

 implementation 'com.google.android.gms:play-services-location:11.8.0'


来源:https://stackoverflow.com/questions/49399308/background-location-service-is-not-working-in-oppo-and-mi-phones

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