我有一个Android 7.0测试设备和我的APK目标=“targetSdkVersion 22”,其中包含:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
使用:
final File f = new
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "DressUpBaby" + photonumber + ".png");
f.createNewFile();
此时我收到警告:
W/System.err: java.io.IOException: Permission denied
如何保存文件?当我在Eclipse上创建它时,这是有效的,但是现在我已经更新并转移到Android Studio,它似乎已经破坏了一些东西。
答案 0 :(得分:10)
如果您定位到 SDK 29 ,并且在成功请求WRITE_EXTERNAL_STORAGE权限后仍然出现“拒绝权限”错误,则应添加
android:requestLegacyExternalStorage="true"
转到AndroidManifest.xml中的应用程序定义。
<manifest ... >
<!-- This attribute is "false" by default on apps targeting
Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
请参阅https://developer.android.com/training/data-storage/compatibility
答案 1 :(得分:8)
如果您在API级别23或更高级别上运行应用程序,则必须在运行时请求权限。
请求权限:
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, WRITE_REQUEST_CODE);
然后处理结果:
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case WRITE_REQUEST_CODE:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Granted.
}
else{
//Denied.
}
break;
}
}
答案 2 :(得分:5)
Android N引入了一种新的权限模型,该模式仅在应用程序真正需要时才会请求权限,而不是像以前那样在安装期间。
使用以下代码询问权限
注意 - 还要在清单文件中添加所需的权限
如果您没有要求主要活动的权限传递对上下文/活动的引用
以下示例显示了要求写入外部存储的权限的示例,可以同时重新安排多个permisisons(谷歌不推荐)。
public class MainActivity extends AppCompatActivity {
/**
* Variables for requiesting permissions, API 25+
*/
private int requestCode;
private int grantResults[];
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED ){
//if you dont have required permissions ask for it (only required for API 23+)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
onRequestPermissionsResult(requestCode,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},grantResults);
}
@Override // android recommended class to handle permissions
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("permission","granted");
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.uujm
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
//app cannot function without this permission for now so close it...
onDestroy();
}
return;
}
// other 'case' line to check fosr other
// permissions this app might request
}
}
答案 3 :(得分:1)
如果即使授予了权限并且您已经实施了权限检查,您也会得到拒绝权限错误,
将 targetSdkVersion 和 compilesdkversion 从 29 更改为 28 或其他任何较低级别。
答案 4 :(得分:1)
与答案“确保您未针对api级别29 ...”有关,我发现了这一点。
https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory
。。。。。。。。
“ getExternalStoragePublicDirectory”
此方法已在API级别29中弃用。
为了提高用户隐私,不建议直接访问共享/外部存储设备。当应用程序定位到Build.VERSION_CODES.Q时,此方法返回的路径不再可供应用程序直接访问。通过迁移到Context#getExternalFilesDir(String),MediaStore或Intent#ACTION_OPEN_DOCUMENT之类的替代方案,应用程序可以继续访问共享/外部存储中存储的内容。
。。。。。。。。
因此,在这种情况下,您必须用其他方法替换“ getExternalStoragePublicDirectory”。
答案 5 :(得分:0)
这是我在类似情况下所做的:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
void checkForPermissions()
{
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
// This part I didn't implement,because for my case it isn't needed
Log.i(TAG,"Unexpected flow");
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission is already granted, call the function that does what you need
onFileWritePermissionGranted();
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay!
// call the function that does what you need
onFileWritePermissionGranted();
} else {
Log.e(TAG, "Write permissions has to be granted tp ATMS, otherwise it cannot operate properly.\n Exiting the program...\n");
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
void onFileWritePermissionGranted()
{
// Write to some file
}
答案 6 :(得分:0)
在最新版本的android中,请求权限有点不同,例如, 如果您想先访问存储权限 您需要从 Manifest.xml 请求访问权限
喜欢:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
最重要的是不要忘记从 Manifets.xml 的应用程序标签中允许这一点,
`android:requestLegacyExternalStorage="true"'
//并从您的活动中创建方法以请求运行权限 从任何需要的活动中调用此函数。
private boolean requestPermission(){
boolean request=true;
String[] permissions={Manifest.permission.CAMERA,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION};
if (permissions.length!=0){
ActivityCompat.requestPermissions(this,permissions,102);
request= true;
}
else{
toastMsg("Permissions Denied");
println("Permissions not allowed by User...");
request=false;
}
return request;
}