oppo和小米手机后台定位服务不工作

Posted

技术标签:

【中文标题】oppo和小米手机后台定位服务不工作【英文标题】:Background location service is not working in oppo and MI phones 【发布时间】:2018-08-30 03:47:59 【问题描述】:

在我的 android 应用程序中,定位服务是作为后台服务实现的。我已经用不同的手机(如 samsung、micromax、Moto、lenovo、nexus)对其进行了测试,它适用于所有手机。但是当我在 Oppo(colorOS)中运行时和 MI(MIUI OS),我的服务在一段时间后停止。我已经用 MainActivity.this.finish() 完成了 MainActivity。

【问题讨论】:

你能解决这个问题吗?因为我也遇到了同样的问题。 我的后台服务没有在 Oppo 真我设备中运行 任何建议或解决方案 【参考方案1】:

在 oncreate() 方法上方的活动中添加以下代码:


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

从 oncreate method() 调用上述代码:-

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

创建这个类:

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 回调 = (PermissionCallbacks) 对象;

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



在清单中添加:-

    <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" />

在应用程序的 gradle 文件中添加以下内容:

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

【讨论】:

此活动代码中的 SurveyApp 是什么?实际上我的代码已经准备好了位置捕获服务。它只需要在 oppo 和 MI 上运行

以上是关于oppo和小米手机后台定位服务不工作的主要内容,如果未能解决你的问题,请参考以下文章

oppo-coloros、vivo-funtouch os、小米-MIUI os等定制操作系统新推出的设备,如何保护后台服务/报警被杀?

在小米或 Oppo 或 Vivo 手机上 - 应用程序任务未按预期工作

Android AndroidQ 小米 oppo等后台启动界面问题 解决方案

Android AndroidQ 小米 oppo等后台启动界面问题 解决方案

什么是后台运行

android中的后台服务没有运行像oppo,vivo等设备