我正在尝试在Android应用中创建空白文件。我的代码在Android 5上运行良好,但是当我在Android 7或更高版本上进行测试时,它没有打印异常就失败了。
我的代码是:
downloadLocation = new File(Environment.getExternalStorageDirectory() + "/" + "folder" + System.currentTimeMillis());
downloadLocation.mkdir();
downloadFile = new File(downloadLocation, "file" + System.currentTimeMillis());
downloadFile.createNewFile();
请注意,我已经声明了变量和所有内容,只是没有包括在内。 downloadLocation和downloadFile变量都是File类型。
在我使用的Android 5物理设备上,它运行良好。然后,我使用Android 7虚拟设备进行了测试,但是它失败了,没有在日志中打印错误。问题出在第二段代码,特别是最后一行。我之所以知道这一点,是因为我在每行与每个日志输出之间都放置了一个日志,除了创建文件后的日志。
当没有错误显示时,调试某些东西非常困难,尽管存在捕获错误,该错误应该打印堆栈跟踪和异常。
有什么想法吗?
请注意,我知道该文件和文件夹尚不存在,因为我在该名称后附加了一个时间戳以防止进行测试,因为我100%知道该文件将具有唯一的名称发布中的名称。这就是为什么我没有将每个块都包含在if语句中的原因,该语句将检查以确保文件/文件夹不存在。
答案 0 :(得分:0)
您的代码可能抛出未找到文件异常。在downloadLocation.mkdir()
通话之后:
if (downloadLocation.exists()) { System.out.println("File Exists"); }
您会注意到该消息不会打印。这是因为您从来没有写目录的权限。
将以下内容添加到您的AndroidManifest.xml中:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
一个简单的方法来处理请求权限是一个很棒的库:EasyPermissions
使用EasyPermissions,您的代码可能类似于:
1。)您在活动中调用一个函数以触发创建文件:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
writeFiles();
}
2。)writeFiles将需要确保在执行文件操作之前已授予权限:
@AfterPermissionGranted(PERMISSIONS_REQUEST_CODE)
private void writeFiles() {
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (EasyPermissions.hasPermissions(this, permissions)) {
try {
File downloadLocation = new File(Environment.getExternalStorageDirectory() + "/" + "folder" + System.currentTimeMillis());
downloadLocation.mkdir();
if (downloadLocation.exists()) {
Log.i("writeFiles()", downloadLocation.getAbsolutePath());
}
File downloadFile = new File(downloadLocation, "file" + System.currentTimeMillis());
downloadFile.createNewFile();
} catch (Exception e) {
Log.e("ERROR", e.getMessage(), e);
}
} else {
// Do not have permissions, request them now
EasyPermissions.requestPermissions(this, "Your permission rationale", PERMISSIONS_REQUEST_CODE, permissions);
}
}
3。)为了使EasyPermissions在授予权限后再次自动调用writeFiles(),您需要添加以下覆盖:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
您会发现PERMISSIONS_REQUEST_CODE
使用了两次。这只是一个常量整数,您可以从Activity调用onRequestPermissionsResult时用来标识权限请求。只要它是唯一的,它就可以是您想要的任何数字(例如1000)。我链接到EasyPermissions的文档,该文档将进一步解释它的工作原理,但这大大简化了您处理运行时权限的方式。
编辑: 以下链接将帮助解释有关请求应用程序权限的更多信息:
过去,当用户将您的应用安装到Play商店中时,系统会向他们显示您的应用所需的权限列表。如果用户继续安装该应用程序,则会自动授予所有权限。 Android 6改变了这一点,现在用户可以更好地控制要授予每个应用程序的权限。
某些权限仍然不需要用户批准,这些权限被视为普通权限。一个示例是INTERNET
权限。其他可能会影响隐私,系统数据等的权限被视为危险权限,并且要求用户通过权限对话框(如上所示)授予它们。我在上面发布的第二个URL将向您显示一些表,列出每个权限的资格。
请记住,如果用户拒绝许可并选中“不再显示”框,则对话框将永远不会再显示给他们,他们将不得不进入系统设置中的“应用”并从那里。如果您想帮助用户进入此屏幕,可以使用以下意图:
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", getPackageName(), null));
startActivity(intent);