我尝试使用以下代码复制图像文件:
InputStream fileInputStream = null;
OutputStream fileOutputStream = null;
String inPath = "/storage/emulated/0/Pictures/MyImage.jpg";
String outPath = "/storage/extSdCard/MyFolder/MyImage.jpg";
try {
verifyStoragePermissions(this);
fileInputStream = new FileInputStream(new File(inPath));
File outputFile = new File(outPath);
if (!outputFile.exists()) {
try {
outPutFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
fileOutputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[1024];
int read;
while ((read = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, read);
}
fileInputStream.close();
fileInputStream = null;
fileOutputStream.flush();
fileOutputStream.close();
fileOutputStream = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
这是验证sdk> = 23
上的存储权限的方法// 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) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
结果是在到达buffer
行之前发生此错误。
Unable to decode stream: java.io.FileNotFoundException: /storage/extSdCard/MyFolder/MyImage.jpg: open failed: ENOENT (No such file or directory)
我在我的设备上的SD卡和图库应用上MyFolder
将图像复制到此目录,没有任何问题。
注意:清单(在应用程序标记之前的正确位置)和内部活动(对于skd> = 23)授予权限。
编辑:
在fileOutputStream
之前实施了创建文件的建议(没有帮助)。
降低了targetSdkVersion以覆盖与权限相关的任何可能问题,但仍然没有成功。
targetSdkVersion 22
以这种方式创建File
:
File outFile = new File("/storage/extSdCard", "MyFolder/MyImage.jpg");
也没有结果。
我在Android 22版上测试它。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
答案 0 :(得分:0)
您需要先创建文件,如果文件不存在,FileOutputStream
将抛出该异常FileNotFoundException
File outputFile = new File(outPath);
file.createNewFile();
fileOutputStream = new FileOutputStream(outputFile);
答案 1 :(得分:0)
如果您在app gradle文件中使用targetSdkVersion 23
(或更高版本),则需要显式请求权限(可以是Activity的onCreate方法或按钮侦听器方法),如下所示。
private static final int CODE_WRITE_EXTERNAL = 10;
if (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Log.d(TAG, "onCreate: " + "Show explanation");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_WRITE_EXTERNAL );
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_WRITE_EXTERNAL );
}
} else {
Log.d(TAG, "onCreate: " + "Permission already granted!");
//Call your method to save the file
}
然后你需要实现下一个回调方法
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case CODE_WRITE_EXTERNAL : {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "onRequestPermissionsResult: Good to go!");
//Call your mehotd here
} else {
Log.d(TAG, "onRequestPermissionsResult: Bad user");
}
}
}
}
答案 2 :(得分:0)
这是我使用SAF完成工作的方式。
private void newcopyFile(File fileInput, String outputParentPath,
String mimeType, String newFileName) {
DocumentFile documentFileGoal = DocumentFile.fromTreeUri(this, treeUri);
String[] parts = outputParentPath.split("\\/");
for (int i = 3; i < parts.length; i++) { //ex: parts:{"", "storage", "extSdCard", "MyFolder", "MyFolder", "MyFolder"}
if (documentFileGoal != null) {
documentFileGoal = documentFileGoal.findFile(parts[i]);
}
}
if (documentFileGoal == null) {
Toast.makeText(MainActivity.this, "Directory not found", Toast.LENGTH_SHORT).show();
return;
}
DocumentFile documentFileNewFile = documentFileGoal.createFile(mimeType, newFileName);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
outputStream = getContentResolver().openOutputStream(documentFileNewFile.getUri());
inputStream = new FileInputStream(fileInput);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (outputStream != null) {
byte[] buffer = new byte[1024];
int read;
if (inputStream != null) {
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
}
if (inputStream != null) {
inputStream.close();
}
inputStream = null;
outputStream.flush();
outputStream.close();
outputStream = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}