【问题标题】:Permission: Call requires permission which may be rejected by user权限:调用需要权限,可能会被用户拒绝
【发布时间】:2019-03-26 20:49:37
【问题描述】:

在 Android Studio 下编译时,我收到了本文标题中指定的警告。我尝试使用以下代码获取 GPS 更新:

    try {
        LocMgr = (LocationManager)getSystemService( LOCATION_SERVICE );
        LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
        //LocMgr.addNmeaListener( this );   // NMEA
    }
    catch(Exception e) {
        UI.warningBox( this, "GPS appears to be either absent or disabled" );
    }

奇怪的是,我的应用程序在没有任何运行时许可请求的情况下仍然运行良好。但是我确实在清单中请求了权限。

    uses-permission  android:name="android.permission.ACCESS_FINE_LOCATION"
    uses-permission  android:name="android.permission.ACCESS_COARSE_LOCATION"

我没有不高兴,但我期待失败或至少是安全异常。

为什么 Android Studio 如此(出乎意料地)宽容?

顺便说一下,我的模块的 gradle 脚本包括

    defaultConfig {
    applicationId "MY_APP_ID"
    minSdkVersion 11
    targetSdkVersion 26
    }

【问题讨论】:

  • 在最后一个api中试一下,看看行为是否一样。
  • 我在 Android V8.0,API 26 上进行测试。
  • 您是否在干净的设备上进行测试?没有在之前的会话中授予权限?

标签: android android-permissions user-permissions


【解决方案1】:

您的应用未在运行时请求权限,因为您没有添加代码。此外,在最近的 Android 上添加了运行时权限(我猜是在 Android M 上开始的)。

因此,在以前的 Android 版本中,您的应用可以正常运行,因为您只需将权限添加到清单。

在新版本上,您必须在运行时额外请求权限。缺乏权限并不总是导致崩溃。他们只能在日志等上生成警告。

无论如何,要消除该警告,您必须在运行时请求权限。下面,你可以找到一个小例子:

public class MainActivity extends AppCompatActivity implements LocationListener {

    private final static int LOCATION_PERMISSION_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ....

        try {
            LocMgr = (LocationManager) getSystemService(LOCATION_SERVICE);

            if (ActivityCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
                  && ActivityCompat.checkSelfPermission(this, permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // Missing both permissions. User didn't accept them yet. Request
                ActivityCompat.requestPermissions(this, new String[] {permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_CODE);
            } else {
                // Have permissions. Don't need to request. Just request location
                LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
            }
        } catch(Exception e) {
            UI.warningBox( this, "GPS appears to be either absent or disabled" );
        }

        ....
    }

    @Override
    public void onRequestPermissionsResult(final int requestCode,
            @NonNull final String[] permissions,
            @NonNull final int[] grantResults) {
        if(requestCode == LOCATION_PERMISSION_CODE) {
            if(grantResults.length > 1
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED /* ACCESS_FINE_LOCATION */
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED /* ACCESS_COARSE_LOCATION */) {
                // User accepted both permissions. request location updates
                LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    您使用什么版本的 android 来运行您的应用程序?在 marshmallow(api 级别 23)之前,您可以访问许多服务,例如 LocationService,而无需实际征求用户的许可。

    您甚至可以在未经许可的情况下使用 wifi 和蓝牙。当时是权限的狂野西部。从那以后情况发生了变化,因为您的最高级别 api 可能会请求权限(您没有处理),这就是您收到警告的原因

    如果你可以访问谷歌服务,你应该使用 fusedlocationprovider,如果没有创建服务来持续轮询,locationservice 不会给出有效的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-19
      • 1970-01-01
      相关资源
      最近更新 更多