如果之前未授予或拒绝权限,如何每次都询问活动开始的权限

Posted

技术标签:

【中文标题】如果之前未授予或拒绝权限,如何每次都询问活动开始的权限【英文标题】:How to ask every time for permission on activity start if the permission is not granted or denied previously 【发布时间】:2021-11-18 05:21:31 【问题描述】:

我正在开发一个需要用户位置的安卓应用,每次用户登录到应用时。

我已经编写了代码来获取用户位置并且工作正常,但问题是如果用户两次拒绝权限它没有再次询问,这是我的代码:

public class MainActivity extends AppCompatActivity 
    String myLocation = "";
    private LocationRequest locationRequest;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(5000);
        locationRequest.setFastestInterval(2000);
        getCurrentLocation();
    

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) 
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) 
                if (isGPSEnabled()) 
                    getCurrentLocation();
                 else 
                    turnOnGPS();
                
            
        
    

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 2) 
            if (resultCode == Activity.RESULT_OK) 
                getCurrentLocation();
            
        
    

    private void getCurrentLocation() 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
            if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 
                if (isGPSEnabled()) 
                    LocationServices.getFusedLocationProviderClient(MainActivity.this)
                            .requestLocationUpdates(locationRequest, new LocationCallback() 
                                @Override
                                public void onLocationResult(@NonNull LocationResult locationResult) 
                                    super.onLocationResult(locationResult);
                                    LocationServices.getFusedLocationProviderClient(MainActivity.this)
                                            .removeLocationUpdates(this);
                                    if (locationResult != null && locationResult.getLocations().size() > 0) 
                                        int index = locationResult.getLocations().size() - 1;
                                        double latitude = locationResult.getLocations().get(index).getLatitude();
                                        double longitude = locationResult.getLocations().get(index).getLongitude();
                                        myLocation = "Latitude: " + latitude + " Longitude: " + longitude;
                                        Toast.makeText(getApplicationContext(), myLocation, Toast.LENGTH_LONG).show();
                                    
                                
                            , Looper.getMainLooper());
                 else 
                    turnOnGPS();
                
             else 
                requestPermissions(new String[]Manifest.permission.ACCESS_FINE_LOCATION, 1);
            
        
    

    private void turnOnGPS() 
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
        builder.setAlwaysShow(true);
        Task<LocationSettingsResponse> result = LocationServices.getSettingsClient(getApplicationContext())
                .checkLocationSettings(builder.build());
        result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() 
            @Override
            public void onComplete(@NonNull Task<LocationSettingsResponse> task) 
                try 
                    LocationSettingsResponse response = task.getResult(ApiException.class);
                    Toast.makeText(MainActivity.this, "GPS is already tured on", Toast.LENGTH_SHORT).show();
                 catch (ApiException e) 
                    switch (e.getStatusCode()) 
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try 
                                ResolvableApiException resolvableApiException = (ResolvableApiException) e;
                                resolvableApiException.startResolutionForResult(MainActivity.this, 2);
                             catch (IntentSender.SendIntentException ex) 
                                ex.printStackTrace();
                            
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            //Device does not have location
                            break;
                    
                
            
        );
    

    private boolean isGPSEnabled() 
        LocationManager locationManager = null;
        boolean isEnabled = false;
        if (locationManager == null) 
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        
        isEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        return isEnabled;
    
  

因为,用户的位置对于应用程序的运行是必需的。现在,我希望应用:

1- 如果之前未授予或拒绝权限,请在活动开始时请求权限。 2-如果授予权限,则继续进行,否则关闭活动。

那么,我怎样才能做到这一点。 谢谢

【问题讨论】:

【参考方案1】:

您可以使用checkSelfPermission检查用户是否已授予权限,如果没有,则您再次请求权限,否则使用程序流程处理。

 if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED)

         doStuff()

   else 
    
         requestStoragePermission()
     

【讨论】:

【参考方案2】:

但问题是,如果用户两次拒绝权限,它并没有询问 再次,

是的,一旦用户拒绝许可并选中“不再询问”,您就不能再次询问。此复选框通常在第二个权限请求时默认选中。请注意,在 api 11 上,没有复选框,并且拒绝是自动的 auto-denial auto-reset。

方法是,您无需对此做任何假设,只需输入处理它的逻辑即可。如果被拒绝,您只能通知用户所需的权限。官方文档说:ref

如果 ContextCompat.checkSelfPermission() 方法返回 PERMISSION_DENIED,调用 shouldShowRequestPermissionRationale()。如果 此方法返回 true,向用户显示教育 UI。在这个 UI,描述为什么用户想要启用的功能需要 特殊权限。

info

【讨论】:

以上是关于如果之前未授予或拒绝权限,如何每次都询问活动开始的权限的主要内容,如果未能解决你的问题,请参考以下文章

只要状态没有被授予,如何一直询问位置权限-Flutter

html5用户如果拒绝获取经纬度之后页面加载一直提示拒绝获取经纬度,怎麽获取权限,页面每次加载都能

对话框“不再询问”的 Android M 权限问题

测试录音权限问题

html5获取地理位置,如果用户拒绝了,之后每次加载都提示:拒绝获取地理位置,如何获取权限:如果用

API Guide(十四)之Permissions