Реализация File Picker в Android и копирование выбранного файла в другое место

Я пытаюсь реализовать File Picker в своем проекте Android. Что мне удалось сделать до сих пор:

Intent chooseFile;
Intent intent;
chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
intent = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(intent, PICKFILE_RESULT_CODE);

И затем в моем onActivityResult()

switch(requestCode){
 case PICKFILE_RESULT_CODE:
   if(resultCode==-1){
      Uri uri = data.getData();
      String filePath = uri.getPath();
      Toast.makeText(getActivity(), filePath,
                        Toast.LENGTH_LONG).show();
    }
 break;
}

Это открывает сборщик файлов, но это не то, что я хочу. Например, я хочу выбрать файл (.txt), а затем получить этот File, а затем использовать его. С помощью этого кода я думал, что получаю полный путь, но этого не произойдет; например, я получаю: /document/5318/. Но с этим путем я не могу получить файл. Я создал метод под названием PathToFile(), который возвращает File:

 private File PathToFile(String path) {
    File tempFileToUpload;
    tempFileToUpload = new File(path);
    return tempFileToUpload;
}

То, что я пытаюсь сделать, это позволить пользователю выбрать File из любых средств DropBox, Drive, SDCard, Mega и т.д.... И я не нахожу способ чтобы сделать это правильно, я попытался получить Path, затем получить File этим Path... но он не работает, поэтому я думаю, что лучше получить сам File, а затем с помощью это File программно я Copy this или Delete.

EDIT (текущий код)

Мой Intent

 Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
 chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
 chooseFile.setType("text/plain");
 startActivityForResult(
      Intent.createChooser(chooseFile, "Choose a file"),
      PICKFILE_RESULT_CODE
 );

У меня вопрос, потому что я не знаю, что поддерживается как text/plain, но я собираюсь рассказать об этом, но в данный момент это не имеет значения.

На моем onActivityResult() я использовал то же самое, что @Lukas Knuth answer, но я не знаю, могу ли я с ним Copy this File в другую часть от моего SDCard Я жду ответа.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
        Uri content_describer = data.getData();
        //get the path 
        Log.d("Path???", content_describer.getPath());
        BufferedReader reader = null;
        try {
            // open the user-picked file for reading:
            InputStream in = getActivity().getContentResolver().openInputStream(content_describer);
            // now read the content:
            reader = new BufferedReader(new InputStreamReader(in));
            String line;
            StringBuilder builder = new StringBuilder();

            while ((line = reader.readLine()) != null){
                builder.append(line);
            }
            // Do something with the content in
            text.setText(builder.toString());



        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

getPath() из @Y.S.

Я делаю это:

    String[] projection = { MediaStore.Files.FileColumns.DATA };
            Cursor cursor = getActivity().getContentResolver().query(content_describer, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(projection[0]);
cursor.moveToFirst();
cursor.close();
Log.d( "PATH-->",cursor.getString(column_index));

Получает NullPointerException:

java.lang.RuntimeException: Ошибка предоставления результата ResultInfo {who = null, request = 131073, result = -1, data = Intent {dat = file:///path typ = text/plain flg = 0x3}} to activity {info.androidhive.tabsswipe/info.androidhive.tabsswipe.MainActivity2}: java.lang.NullPointerException

EDIT с кодом, работающим благодаря @YS, @Lukas Knuth и @CommonsWare.

Это Intent, где я принимаю только файлы text/plain.

Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("text/plain");
startActivityForResult(
    Intent.createChooser(chooseFile, "Choose a file"),
    PICKFILE_RESULT_CODE
);

На моем onActivityResult() я создаю URI, где я получаю данные Intent, я создаю File, где я сохраняю абсолютный путь content_describer.getPath();, и то я сохраняю имя пути, чтобы использовать его в TextView с content_describer.getLastPathSegment(); (это было удивительно, что @YS не знал об этой функции), и я создаю второй File, который я назвал destination и Я отправляю AbsolutePath, чтобы создать этот File.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK){
        Uri content_describer = data.getData();
        String src = content_describer.getPath();
        source = new File(src);
        Log.d("src is ", source.toString());
        String filename = content_describer.getLastPathSegment();
        text.setText(filename);
        Log.d("FileName is ",filename);
        destination = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Test/TestTest/" + filename);
        Log.d("Destination is ", destination.toString());
        SetToFolder.setEnabled(true);
    }
}

Также я создал функцию, которую вы должны отправить source file и destination file, которые мы создали ранее, чтобы скопировать ее в новую папку.

private void copy(File source, File destination) throws IOException {

    FileChannel in = new FileInputStream(source).getChannel();
    FileChannel out = new FileOutputStream(destination).getChannel();

    try {
        in.transferTo(0, in.size(), out);
    } catch(Exception e){
        Log.d("Exception", e.toString());
    } finally {
        if (in != null)
            in.close();
        if (out != null)
            out.close();
    }
}

Также я создал функцию, которая говорит мне, если эта папка существует или нет (мне нужно отправить destination file, если она не существует, я создаю эту папку, а если нет, я ничего не делаю.

private void DirectoryExist (File destination) {

    if(!destination.isDirectory()) {
        if(destination.mkdirs()){
            Log.d("Carpeta creada","....");
        }else{
            Log.d("Carpeta no creada","....");
        }
    }

Еще раз спасибо за вашу помощь, надеюсь, вам понравится этот код, сделанный с каждым из вас, ребята:)

Ответ 1

ШАГ 1 - Используйте неявный Intent:

Чтобы выбрать файл с устройства, вы должны использовать неявный Intent

Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
chooseFile = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(chooseFile, PICKFILE_RESULT_CODE);

ШАГ 2 - Получить абсолютный путь к файлу:

Чтобы получить путь к файлу из Uri, сначала попробуйте использовать

Uri uri = data.getData();
String src = uri.getPath();

где data - это Intent, возвращенный в onActivityResult().

Если это не работает, используйте следующий метод:

public String getPath(Uri uri) {

    String path = null;
    String[] projection = { MediaStore.Files.FileColumns.DATA };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);

    if(cursor == null){
        path = uri.getPath()
    }
    else{
        cursor.moveToFirst();
        int column_index = cursor.getColumnIndexOrThrow(projection[0]);
        path = cursor.getString(column_index);
        cursor.close();
    }

    return ((path == null || path.isEmpty()) ? (uri.getPath()) : path);
}

По крайней мере один из этих двух методов должен дать вам правильный полный путь.

ШАГ 3 - Скопируйте файл:

Я считаю, что вы хотите скопировать файл из одного места в другое.

Для этого необходимо указать абсолютный путь к файлу как исходного, так и конечного местоположений.

Сначала получите абсолютный путь к файлу, используя метод getPath() или uri.getPath():

String src = getPath(uri);    /* Method defined above. */

или

Uri uri = data.getData();
String src = uri.getPath();

Затем создайте два объекта File следующим образом:

File source = new File(src);
String filename = uri.getLastPathSegment();
File destination = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/CustomFolder/" + filename);

где CustomFolder - это каталог на внешнем диске, куда вы хотите скопировать файл.

Затем используйте следующий метод для копирования файла из одного места в другое:

private void copy(File source, File destination) {

   FileChannel in = new FileInputStream(source).getChannel();
   FileChannel out = new FileOutputStream(destination).getChannel();

   try {
      in.transferTo(0, in.size(), out);
   } catch(Exception){
      // post to log
   } finally {
      if (in != null)
         in.close();
      if (out != null)
         out.close();
   }
}

Попробуй это. Это должно сработать.

Примечание: в ответ на ответ лукаса - он использовал метод openInputStream(), который возвращает содержимое Uri, независимо от того, представляет ли Uri файл или URL.

Еще один многообещающий подход - FileProvider:

Есть еще один способ, с помощью которого можно получить файл из другого приложения. Если приложение обменивается файлами через FileProvider, то можно получить объект FileDescriptor, который содержит конкретную информацию об этом файле.

Для этого используйте следующее Intent:

Intent mRequestFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
mRequestFileIntent.setType("*/*");
startActivityForResult(mRequestFileIntent, 0);

и в вашем onActivityResult():

@Override
public void onActivityResult(int requestCode, int resultCode,
        Intent returnIntent) {
    // If the selection didn't work
    if (resultCode != RESULT_OK) {
        // Exit without doing anything else
        return;
    } else {
        // Get the file content URI from the incoming Intent
        Uri returnUri = returnIntent.getData();
        /*
         * Try to open the file for "read" access using the
         * returned URI. If the file isn't found, write to the
         * error log and return.
         */
        try {
            /*
             * Get the content resolver instance for this context, and use it
             * to get a ParcelFileDescriptor for the file.
             */
            mInputPFD = getContentResolver().openFileDescriptor(returnUri, "r");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.e("MainActivity", "File not found.");
            return;
        }
        // Get a regular file descriptor for the file
        FileDescriptor fd = mInputPFD.getFileDescriptor();
        ...
    }
}

где mInputPFD - это ParcelFileDescriptor.

Ссылки:

1. Общиесведения - Хранилище файлов.

2. FileChannel.

3. FileProvider.

4. Запрособщего файла.

Ответ 2

Я сделал то же самое, чтобы позволить пользователю выбрать изображение из папки:

1) есть кнопка ОТКРЫТЬ:

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_open:
        myOpenImagePicker();
        break;
    }
}

2) функция папки с открытыми изображениями:

@SuppressLint("InlinedApi")
public void myOpenImagePicker() {

    if (Build.VERSION.SDK_INT < 19) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(
                Intent.createChooser(intent, "Select Picture"),
                SELECT_FOLDER);

    } else {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        startActivityForResult(intent, SELECT_FOLDER);
    }
}

3) результат действия, в котором я получаю путь к файлу изображения и делаю все, что захочу, с путем изображения:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case SELECT_FOLDER:
        if (resultCode == RESULT_OK && data != null) {

            Uri originalUri = data.getData();
            String id01 = W_ImgFilePathUtil.getPath(
                    getApplicationContext(), originalUri);
            Bitmap unscaledBitmap = W_ImgScalingUtil.decodeResource(id01,
                    xdrawing.getViewWidth(), xdrawing.getViewHeight(),
                    ScalingLogic.FIT);
            if (unscaledBitmap == null) {
                zprefsutil.ShowToast("IMAGE ERROR", 1);
            } else {
                setExternalScaledBitmap(W_ImgScalingUtil
                        .createScaledBitmap(unscaledBitmap,
                                xdrawing.getViewWidth(),
                                xdrawing.getViewHeight(), ScalingLogic.FIT));
                unscaledBitmap.recycle();
                xdrawing.invalidate();
            }

        }
        break;
    default:
        break;
    }
}

4) и теперь САМАЯ ВАЖНАЯ ЧАСТЬ, класс W_ImgFilePathUtil, код не от меня, но он позволяет вам получить полный путь к любому выбранному файлу, будь то на SD-карте, диске Google,...:

public class W_ImgFilePathUtil {

    /**
     * Method for return file path of Gallery image
     * 
     * @param context
     * @param uri
     * @return path of the selected image file from gallery
     */
    @SuppressLint("NewApi")
    public static String getPath(final Context context, final Uri uri) {

        // check here to KITKAT or new version
        final boolean isKitKatorUp = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKatorUp && DocumentsContract.isDocumentUri(context, uri)) {

            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/"
                            + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] { split[1] };

                return getDataColumn(context, contentUri, selection,
                        selectionArgs);
            }
        }

        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     * 
     * @param context
     *            The context.
     * @param uri
     *            The Uri to query.
     * @param selection
     *            (Optional) Filter used in the query.
     * @param selectionArgs
     *            (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri,
            String selection, String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = { column };

        try {
            cursor = context.getContentResolver().query(uri, projection,
                    selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri
                .getAuthority());
    }
}

ЗАКЛЮЧЕНИЕ: код работает с путем к изображению, но точно работает с любым типом файла.

Надеюсь, это поможет решить вашу проблему.

PEACE.

Ответ 3

Как уже отмечалось @CommonsWare, Android возвращает вам Uri, более абстрактную концепцию, чем путь к файлу.

Он также может описывать простой путь к файлу, но он также может описывать ресурс, к которому осуществляется доступ через приложение (например, content://media/external/audio/media/710).

Если вы хотите, чтобы ваш пользователь выбирал любой файл с телефона, чтобы прочитать его из вашего приложения, вы можете сделать это, запросив файл (как вы сделали правильно), а затем используйте ContentResolver, чтобы получить InputStream для Uri, который возвращается сборщиком.

Вот пример:

Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
// Ask specifically for something that can be opened:
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
chooseFile.setType("*/*");
startActivityForResult(
        Intent.createChooser(chooseFile, "Choose a file"),
        PICKFILE_REQUEST_CODE
);

// And then somewhere, in your activity:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICKFILE_REQUEST_CODE && resultCode == RESULT_OK){
        Uri content_describer = data.getData();
        BufferedReader reader = null;
        try {
            // open the user-picked file for reading:
            InputStream in = getContentResolver().openInputStream(content_describer);
            // now read the content:
            reader = new BufferedReader(new InputStreamReader(in));
            String line;
            StringBuilder builder = new StringBuilder();
            while ((line = reader.readLine()) != null){
                builder.append(line);
            }
            // Do something with the content in
            some_view.setText(builder.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Важно. Некоторые поставщики (например, Dropbox) хранят/кэшируют свои данные во внешнем хранилище. Вам нужно будет объявить android.permission.READ_EXTERNAL_STORAGE -передачу в вашем манифесте, иначе вы получите FileNotFoundException, даже если файл есть.


Обновить. Да, вы можете скопировать файл, читая его из одного потока и записывая его в другой:

// Error handling is omitted for shorter code!
Uri content_describer = data.getData();
InputStream in = null;
OutputStream out = null;
try {
    // open the user-picked file for reading:
    in = getContentResolver().openInputStream(content_describer);
    // open the output-file:
    out = new FileOutputStream(new File("some/path/to/a/writable/file"));
    // copy the content:
    byte[] buffer = new byte[1024];
    int len;
    while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
    }
    // Contents are copied!
} finally {
    if (in != null) {
        in.close();
    }
    if (out != null){
        out.close();
    }
}

Удаление файла, вероятно, невозможно, так как файл не принадлежит вам, он принадлежит к приложению, которое поделилось им с вашим. Поэтому для удаления файла ответственное приложение несет ответственность.

Ответ 4

Передайте URI, возвращенный в onActivityResult в этом методе

private String getPath(Uri contentURI) {

    String result;
    Cursor cursor = getActivity().getContentResolver().query(contentURI,
            null, null, null, null);

    if (cursor == null) {
        result = contentURI.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor
                .getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}

Ответ 5

A Uri не является файлом. A Uri ближе к URL-адресу веб-сервера. Это непрозрачный адрес, который имеет смысл только для "сервера" (или в этом случае ContentProvider).

Так же, как вы используете InputStream для чтения в байтах, представленных веб-URL, вы используете InputStream для чтения в байтах, представленных Uri. Вы получаете такой поток, вызывая openInputStream() на ContentResolver.

Ответ 6

Вот как реализовать средство выбора файлов и переместить выбранный файл в другое место (например, изображение).

Во-первых, добавьте средство выбора файлов с помощью кнопки прослушивания щелчка к своему коду следующим образом:

Кнопка выбора файла:

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_choose_file:
        showFileChooser();
        break;
    }
}

private String filePath = null;
private File sourceFile;

private static final int FILE_SELECT_CODE = 0;

    private void showFileChooser() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("*/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);

        try {
            startActivityForResult(
                    Intent.createChooser(intent, "Select a File to Copy"),
                    FILE_SELECT_CODE);
        } catch (android.content.ActivityNotFoundException ex) {
            Toast.makeText(this, "Please install a File Manager.",
                    Toast.LENGTH_SHORT).show();
        }
    }

Затем обработайте onActivityResult следующим образом:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case FILE_SELECT_CODE:
                if (resultCode == RESULT_OK) {
                    // Get the Uri of the selected file
                    Uri uri = data.getData();

                    File   file = new File(getCacheDir(), getFileName(uri));

                    int maxBufferSize = 1 * 1024 * 1024;

                    try {
                        InputStream inputStream = getContentResolver().openInputStream(uri);
                        Log.e("InputStream Size","Size " + inputStream);
                        int  bytesAvailable = inputStream.available();
                        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        final byte[] buffers = new byte[bufferSize];

                        FileOutputStream outputStream = new FileOutputStream(file);
                        int read = 0;
                        while ((read = inputStream.read(buffers)) != -1) {
                            outputStream.write(buffers, 0, read);
                        }
                        Log.e("File Size","Size " + file.length());
                        inputStream.close();
                        outputStream.close();

                        file.getPath();
                        Log.e("File Path","Path " + file.getPath());
                        file.length();
                        Log.e("File Size","Size " + file.length());

                        if(file.length() > 0){

                            sourceFile = file;
                           saveFile(sourceFile);
                        }


                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (OutOfMemoryError e) {
                        e.printStackTrace();
                    }



                } else {


                }

                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }





    private void saveFile (File sourceFile) {


                try {

                File currentFile = sourceFile;

                Bitmap myBitmap = BitmapFactory.decodeFile(currentFile.getAbsolutePath());


                String path = currentFile.getAbsolutePath();
                String idStr = path.substring(path.lastIndexOf('/') + 1);
                File filepath = Environment.getExternalStorageDirectory();
                File dir = new File(filepath.getAbsolutePath() + "/" + "yourFolderName" + "/");
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                String fileName = currentFile.getName();
                file = new File(dir, fileName);
                if (file.exists()) file.delete();
                FileOutputStream fos = new FileOutputStream(file);
                myBitmap.compress(CompressFormat.JPEG, 65, fos);
                fos.flush();
                fos.close();


            } catch (Exception e) {
                e.printStackTrace();
            }

    }

Примечание. Не забудьте добавить это разрешение в файл манифеста.

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Надеюсь, это поможет.