@gamess431

Как сохранить Uri в директории приложение?

Ко мне поступает изображение в виде Uri из Cloud Firebase нужно сохранить его в памяти телефона, желательно по пути
/android/data/com.example.app/user/

Coud Firebase sdk код
StorageReference storageReference;
        storageReference = FirebaseStorage.getInstance().getReference();

        storageReference.child("users").child("images")
                .getDownloadUrl()
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful() && task.getResult() != null) {
                        Uri uri = task.getResult();
                        listenerUri.OnSuccessListener(uri);

                        saveUri(context, uri);
                        Log.w("SUCCESS", "Image Loaded-> " +task.getResult().getPath());
                    }else {
                        listenerUri.OnFailureListener(task.getException());
                    }
                });

Метод saveUri которые принимает Uri чтобы сохранить его в памяти устройство
public void saveUri(Context context, Uri uri){

        try {

            InputStream inputStream = context.getContentResolver().openInputStream(uri);

            // Get application directory
            String appPath = context.getApplicationInfo().dataDir;

            // Create new file in application directory
            FileOutputStream outputStream = new FileOutputStream(appPath+"/user/simple.jpg");

            // Break progress
            if (inputStream == null){
                Log.w("SaveUri", "Error: inputStream is null");
                return;
            }

            // Initialize the conversion buffer byte array.
            byte[] conversionBufferByteArray = new byte[1024];

            // Initialize loading counter.
            long load = 0;

            // Define the buffer length variable.
            int bufferLength;

            // Attempt to read data from the input stream and store it in the output stream.  Also store the amount of data read in the buffer length variable.
            while ((bufferLength = inputStream.read(conversionBufferByteArray)) > 0) {  // Proceed while the amount of data stored in the buffer in > 0.

                // Write the contents of the conversion buffer to the file output stream.
                outputStream.write(conversionBufferByteArray, 0, bufferLength);

                // Update the downloaded kilobytes counter.
                load = load + bufferLength;

                // Update the file download progress.
                Log.d(TAG, "Loading: "+load+"%");
            }

            // Close the input stream.
            inputStream.close();
            // Close the output stream.
            outputStream.close();

        }catch (IOException exception) {
            Log.e("SaveUri", "Error: "+exception.getMessage());
        }

    }

разрешения на запись и считывания данные имеется !
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

Рузультат ...
E/SaveUri: Error: No content provider: https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/items%2F1653978775982_0.jpg?alt=media&token=881afe12-46fa-4a97-90ed-cbc28d2d9fd3
W/SUCCESS: Image Loaded-> /v0/b/example.appspot.com/o/items/1653978775982_0.jpg

Изображенте загружается успешно но не сохраняется !
Что не так с моим кодом, почему пишет что провайдер не найдено? хотя я не взаимодействую с другими приложениями Thank you
  • Вопрос задан
  • 281 просмотр
Решения вопроса 1
402d
@402d
начинал с бейсика на УКНЦ в 1988
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

сразу советую . Ищите решение не требующее этого (MANAGE_EXTERNAL_STORAGE") разрешения.
Только на прошлой неделе ругался с модерацией из-за reject по этой причине.

Лучше сохраните в галерею.
mContext.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);

В этом случае пермишен нужен только для младших версий
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />

11 и 12 разрешат сохранить молча. Ниже придется просить сперва пермишен.

И еще раз подумайте почему нельзя сохранять в папке самого приложения ?
Вы потом их другим программам должны дать ?

Если для целей кеширования, то у меня вот так сделано
static public @Nullable
    Uri cacheUri(Uri uri, Context context) throws IOException {


            InputStream inputStream = context.getContentResolver().openInputStream(uri);
            if (inputStream != null) {


                java.io.File outputDir = Objects.requireNonNull(context).getCacheDir(); // context being the Activity pointer
                java.io.File outputFile = java.io.File.createTempFile("spool_job_", "",outputDir);

                BufferedInputStream input = new BufferedInputStream(inputStream);
                BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(outputFile));

                // read and write into the cache directory
                byte[] bArr = new byte[8192];
                while (true) {
                    int read = input.read(bArr);
                    if (read < 0) {
                        break;
                    } else {
                        output.write(bArr, 0, read);
                    }
                }
                // close the streams
                input.close();
                output.close();
                return Uri.fromFile(outputFile);
            }

        return null;
    }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы