使用 Android 创建文件时出现权限被拒绝错误,即使已授予权限
Getting a Permission denied error when creating a file with Android, even when permission is given
我的清单中有这个:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
这是我尝试创建和写入文件的地方(它位于名为 EnterUserInfo.java
:
的文件中
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
System.out.println("INSIDEEEEEE");
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
} else {
System.out.println("HEREEEEEEEEE");
}
}
private void writeToFile(String data, Context context) {
verifyStoragePermissions(this);
String FILENAME = "new_clients.txt";
String string = "hello world!";
try {
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileOutputStream fos = context.openFileOutput("new_clients.txt", Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
当我尝试创建文件时,出现以下内容:
I/System.out: HEREEEEEEEEE
W/ContextImpl: Failed to ensure /data/user/0/c.b.project/files: mkdir failed: EACCES (Permission denied)
W/FileUtils: Failed to chmod(/data/user/0/cs.b07.cscb07courseproject/files): android.system.ErrnoException: chmod failed: EACCES (Permission denied)
W/System.err: java.io.FileNotFoundException: /data/user/0/c.b.project/files/new_clients.txt (Permission denied)
W/System.err: at java.io.FileOutputStream.open(Native Method)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
W/System.err: at android.app.ContextImpl.openFileOutput(ContextImpl.java:506)
W/System.err: at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:192)
W/System.err: at EnterUserInfo.writeToFile(EnterUserInfo.java:69)
如您所见,它打印 here
表示已授予权限,但紧接着它给出了 Permission Denied
错误。知道如何解决这个问题吗?
编辑:附带说明,当它说它试图保存到 /data/user/0/cs.b07.cscb07courseproject/files
时,它是在项目中还是保存在我的计算机上?因为当我去我的终端做 cd /data/
或 cd /data
时,都找不到。
编辑:writeToFile()
在上面发布的同一个 class 和文件中调用,这是代码(当用户点击 "register" 按钮时下面的函数被调用UI:
public void createNewUser(View view) {
// a data string is created here:
// String data = "asd";
writeToFile(data, this);
}
编辑 2:请注意,我在 verifyStoragePermissions()
方法中确实在运行时请求了许可。除非这种请求许可的方式有问题(我不认为这是因为确实出现了提示要求用户许可),否则我认为问题出在其他地方。
在 运行 时间请求权限
从 Android 6.0(API 级别 23)开始,用户在应用 运行 时向应用授予权限,而不是在安装应用时。这种方法简化了应用安装过程,因为用户在安装或更新应用时不需要授予权限。
您好,首先您必须检查您使用的是哪个 android SDK 版本
如果它小于 23,那么您只需将您的许可放入清单文件即可
如果 android 版本大于 23 您应该将所有 权限放在清单文件中,并且您应该请求用户权限 运行 时间(仅第一次尝试)
为此你应该遵循这个 link
您可以做的另一件事是将 compileSdkVersion 和 buildToolsVersion 更改为 23 以下,例如 22(但我不会建议您这样做,因为您无法使用 23 以上的新功能)
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
}
}
如果不起作用请告诉我
您不需要任何权限来调用openFileOutput()
。这会将文件写入您的应用程序拥有的专用应用程序特定数据区域。
根据这些错误判断:
W/ContextImpl: Failed to ensure /data/user/0/c.b.project/files: mkdir failed: EACCES (Permission denied)
W/FileUtils: Failed to chmod(/data/user/0/cs.b07.cscb07courseproject/files): android.system.ErrnoException: chmod failed: EACCES (Permission denied)
看起来有人更改了您应用程序的私有数据目录 /data/user/0/c.b.project/
上的文件所有权(或访问权限)。此目录应归您应用程序的用户 ID 所有,因此您的应用程序应具有写入该目录的必要权限。
卸载您的应用程序(应该删除该目录)然后重新安装您的应用程序(应该重新创建具有正确权限的目录)。
我的清单中有这个:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
这是我尝试创建和写入文件的地方(它位于名为 EnterUserInfo.java
:
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
System.out.println("INSIDEEEEEE");
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
} else {
System.out.println("HEREEEEEEEEE");
}
}
private void writeToFile(String data, Context context) {
verifyStoragePermissions(this);
String FILENAME = "new_clients.txt";
String string = "hello world!";
try {
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileOutputStream fos = context.openFileOutput("new_clients.txt", Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
当我尝试创建文件时,出现以下内容:
I/System.out: HEREEEEEEEEE
W/ContextImpl: Failed to ensure /data/user/0/c.b.project/files: mkdir failed: EACCES (Permission denied)
W/FileUtils: Failed to chmod(/data/user/0/cs.b07.cscb07courseproject/files): android.system.ErrnoException: chmod failed: EACCES (Permission denied)
W/System.err: java.io.FileNotFoundException: /data/user/0/c.b.project/files/new_clients.txt (Permission denied)
W/System.err: at java.io.FileOutputStream.open(Native Method)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
W/System.err: at android.app.ContextImpl.openFileOutput(ContextImpl.java:506)
W/System.err: at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:192)
W/System.err: at EnterUserInfo.writeToFile(EnterUserInfo.java:69)
如您所见,它打印 here
表示已授予权限,但紧接着它给出了 Permission Denied
错误。知道如何解决这个问题吗?
编辑:附带说明,当它说它试图保存到 /data/user/0/cs.b07.cscb07courseproject/files
时,它是在项目中还是保存在我的计算机上?因为当我去我的终端做 cd /data/
或 cd /data
时,都找不到。
编辑:writeToFile()
在上面发布的同一个 class 和文件中调用,这是代码(当用户点击 "register" 按钮时下面的函数被调用UI:
public void createNewUser(View view) {
// a data string is created here:
// String data = "asd";
writeToFile(data, this);
}
编辑 2:请注意,我在 verifyStoragePermissions()
方法中确实在运行时请求了许可。除非这种请求许可的方式有问题(我不认为这是因为确实出现了提示要求用户许可),否则我认为问题出在其他地方。
在 运行 时间请求权限
从 Android 6.0(API 级别 23)开始,用户在应用 运行 时向应用授予权限,而不是在安装应用时。这种方法简化了应用安装过程,因为用户在安装或更新应用时不需要授予权限。
您好,首先您必须检查您使用的是哪个 android SDK 版本
如果它小于 23,那么您只需将您的许可放入清单文件即可
如果 android 版本大于 23 您应该将所有 权限放在清单文件中,并且您应该请求用户权限 运行 时间(仅第一次尝试)
为此你应该遵循这个 link
您可以做的另一件事是将 compileSdkVersion 和 buildToolsVersion 更改为 23 以下,例如 22(但我不会建议您这样做,因为您无法使用 23 以上的新功能)
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
}
}
如果不起作用请告诉我
您不需要任何权限来调用openFileOutput()
。这会将文件写入您的应用程序拥有的专用应用程序特定数据区域。
根据这些错误判断:
W/ContextImpl: Failed to ensure /data/user/0/c.b.project/files: mkdir failed: EACCES (Permission denied)
W/FileUtils: Failed to chmod(/data/user/0/cs.b07.cscb07courseproject/files): android.system.ErrnoException: chmod failed: EACCES (Permission denied)
看起来有人更改了您应用程序的私有数据目录 /data/user/0/c.b.project/
上的文件所有权(或访问权限)。此目录应归您应用程序的用户 ID 所有,因此您的应用程序应具有写入该目录的必要权限。
卸载您的应用程序(应该删除该目录)然后重新安装您的应用程序(应该重新创建具有正确权限的目录)。