我正在尝试实现 Android 10 的 ACCESS_MEDIA_LOCATION 权限,以便访问照片的位置。
首先,应用程序请求 READ_EXTERNAL_STORAGE 权限,以便使用 MediaStore 访问照片。
然后应用程序使用 ExifInterface 读取照片的位置。在 Android 10 中,ExifInterface 失败,因为它没有权限。
我尝试添加 ACCESS_MEDIA_LOCATION 的权限请求,但没有出现权限请求框。然而,随后获得了许可!
如果我在获得 READ_EXTERNAL_STORAGE 权限之前先请求 ACCESS_MEDIA_LOCATION,则会出现权限请求框。
如果我随后请求 READ_EXTERNAL_STORAGE 权限,则不会出现权限请求框,但随后又会授予权限。 (我知道这样做没有意义,但我只是想看看发生了什么。)
我真的很困惑。为了访问照片的位置,应该请求用户的许可,这是有道理的,但是如果之前已授予 READ_EXTERNAL_STORAGE,为什么 ACCESS_MEDIA_LOCATION 的权限框不会出现?为什么在未经用户同意的情况下授予权限?
我是否缺少某些内容会使权限框出现?
下面的代码片段。
安卓清单:
<manifest ...>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
…
片段1:
public class Fragment1 extends Fragment {
…
public View onCreateView(...
…
Log.d(TAG, "Entering Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
String[] permission = {Manifest.permission.READ_EXTERNAL_STORAGE};
this.requestPermissions(permission, 1);
Log.d(TAG, "Exiting Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
...
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Log.d(TAG, "Fragment1 Request Permissions callback");
for (int i = 0; i < permissions.length; i++)
Log.d(TAG, "Permission " + permissions[0] + ", " + grantResults[0] );
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
}
片段2:
public class Fragment2 extends Fragment {
...
public View onCreate(...
…
Log.d(TAG, "Entering Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
String[] permission = {Manifest.permission.ACCESS_MEDIA_LOCATION};
this.requestPermissions(permission, 1); // No permission box appears here :-(
Log.d(TAG, "Exiting Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION");
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
…
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Log.d(TAG, "Fragment2 Request Permissions callback");
for (int i = 0; i < permissions.length; i++)
Log.d(TAG, "Permission " + permissions[0] + ", " + grantResults[0] );
Log.d(TAG, "Permission ACCESS_MEDIA_LOCATION, " + this.requireContext().checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION));
Log.d(TAG, "Permission READ_EXTERNAL_STORAGE, " + this.requireContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
}
当在 Nexus 6 API 29 模拟器上运行时,会弹出 READ_EXTERNAL_STORAGE 的第一个 UI 框,然后我点击“允许”。然后我转到第二个片段,但调用 requestPermissions 时没有弹出 UI 框。
这是日志。可以看到,当调用requestPermissions时,权限是不允许的,但是当它到达回调时,权限已经被授予:
2020-10-20 12:17:38.154 8830-8830/com.example.example1 D/ContentValues: Entering Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE
2020-10-20 12:17:38.155 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:38.155 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, -1
2020-10-20 12:17:38.162 8830-8830/com.example.example1 D/ContentValues: Exiting Fragment1 requestPermissions operation for permission READ_EXTERNAL_STORAGE
2020-10-20 12:17:38.163 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:38.164 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, -1
2020-10-20 12:17:49.544 8830-8830/com.example.example1 D/ContentValues: Fragment1 Request Permissions callback
2020-10-20 12:17:49.544 8830-8830/com.example.example1 D/ContentValues: Permission android.permission.READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:49.545 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:49.546 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:55.312 8830-8830/com.example.example1 D/ContentValues: Entering Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION
2020-10-20 12:17:55.313 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:55.318 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:55.327 8830-8830/com.example.example1 D/ContentValues: Exiting Fragment2 requestPermissions operation for permission ACCESS_MEDIA_LOCATION
2020-10-20 12:17:55.328 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, -1
2020-10-20 12:17:55.329 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0
2020-10-20 12:17:55.621 8830-8830/com.example.example1 D/ContentValues: Fragment2 Request Permissions callback
2020-10-20 12:17:55.622 8830-8830/com.example.example1 D/ContentValues: Permission android.permission.ACCESS_MEDIA_LOCATION, 0
2020-10-20 12:17:55.623 8830-8830/com.example.example1 D/ContentValues: Permission ACCESS_MEDIA_LOCATION, 0
2020-10-20 12:17:55.623 8830-8830/com.example.example1 D/ContentValues: Permission READ_EXTERNAL_STORAGE, 0