Как скопировать изображение в существующий каталог на SD-карте?

android android-sdcard fileoutputstream file-copying

130 просмотра

3 ответа

1493 Репутация автора

Я пытаюсь скопировать файл изображения с этим кодом:

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)

У меня MyFolderна SD-карте и приложениях галереи на моем устройстве без проблем копируются изображения в этот каталог.

ПРИМЕЧАНИЕ: разрешения предоставляются в манифесте (в правильном месте перед тегом приложения) и во внутренней активности (для skd> = 23).

правок:

  1. Реализовано предложение по созданию файла ранее fileOutputStream(не помогло).

  2. Понизил targetSdkVersion для преодоления любых возможных проблем, связанных с разрешениями, и все еще безуспешно.

targetSdkVersion 22

  1. Создание 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" />
Автор: Eftekhari Источник Размещён: 18.07.2016 08:27

Ответы (3)


0 плюса

6289 Репутация автора

Вам нужно сначала создать файл, FileOutputStreamсгенерирует это исключение, если файл не существует FileNotFoundException

File outputFile = new File(outPath);
file.createNewFile();
fileOutputStream = new FileOutputStream(outputFile);
Автор: Wilik Размещён: 18.07.2016 08:39

0 плюса

34 Репутация автора

если вы используете targetSdkVersion 23(или выше) в своем файле gradle приложения, вам нужно явно запросить разрешение (может быть в методе onCreate в Activity или в методе прослушивания кнопки), например так ...

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");
                }
            }
        }
    }
Автор: Jonathan Sánchez Muñoz Размещён: 18.07.2016 09:50

0 плюса

1493 Репутация автора

Решение

Это способ, которым я использовал 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();
}
}
Автор: Eftekhari Размещён: 04.12.2016 11:27
Вопросы из категории :
32x32