java - 如何将任何类型的文件从 Assets 文件移动/复制到 JAVA 中的范围存储 ANDROID Q?

标签 java android scoped-storage

我已经成功地对图像执行了此操作,但我无法对其他类型的文件执行此操作,在我的情况下,我尝试插入一个数据库。

这是图像代码的示例:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
        try {
            try {
                pictures = assetManager.list("photos/dataset1");
            } catch (IOException e) {
                Log.e("tag", "Failed to get asset file list.", e);
            }
            if (pictures != null) {
                for (String filename : pictures) {
                    InputStream in;
                    OutputStream out;
                    InputStream inputStream = assetManager.open("photos/dataset1/"+filename);
                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                    saveImageToGallery(bitmap);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

下面的方法适用于图像:

public void saveImageToGallery(Bitmap bitmap) {
    OutputStream outputStream;
    Context myContext = requireContext();
    try {
        if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.Q){
            ContentResolver contentResolver = requireContext().getContentResolver();
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME,"Image_"+".jpg");
            contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
            Uri imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            outputStream = contentResolver.openOutputStream(Objects.requireNonNull(imageUri));
            bitmap.compress(Bitmap.CompressFormat.JPEG,100, outputStream);
            Objects.requireNonNull(outputStream);

        }
    }catch (FileNotFoundException e) {

        e.printStackTrace();
    }
}

还有我对其他类型文件的尝试:

        AssetManager assetManager = Objects.requireNonNull(requireContext()).getAssets();
    Context myContext = requireContext();
    //Essential for creating the external storage directory for the first launch
    myContext.getExternalFilesDir(null);
    File databasesFolder = new File(myContext.getExternalFilesDir(null).getParent(), "com.mydb.orca/databases");
    databasesFolder.mkdirs();

 if (files!= null) {
        for (String filename : files) {
            InputStream in;
            OutputStream out;
            try {
                in = assetManager.open("database/test/" + filename);
                File outFile = new File(databasesFolder, filename);
                out = new FileOutputStream(outFile);
                copyFile(in, out);
                in.close();
                out.flush();
                out.close();
            } catch (IOException e) {
                Log.e("tag", "Failed to copy asset file: " + filename, e);
            }
        }
    } else {
        Log.e("Error NPE", "files is null");
    }



    private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while ((read = in.read(buffer)) != -1) {
        out.write(buffer, 0, read);
    }
}

上面的这段代码不起作用,我的意思是,我没有得到任何错误或期望的结果。我想要这样的东西或类似于我的图像功能但适用于任何类型文件的功能。 当我运行我的应用程序时,我没有出现任何错误,但是什么也没有发生

最佳答案

我终于找到了解决方案,我敢肯定这不是最好的方法,但它确实有效。 我通过这种方式授予我访问所有文件的权限:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
  try {
        Intent intentFiles = new Intent();
        intentFiles.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
        Uri uriFiles = Uri.fromParts("package", myContext.getPackageName(), null);
        intentFiles.setData(uriFiles);
        myContext.startActivity(intentFiles);
       } catch (Exception e)
       {
        Intent intentFiles = new Intent();
        intentFiles.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
        myContext.startActivity(intentFiles);
       }

将此行添加到您的 list 中:

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

之后,下面的代码开始工作了:

AssetManager assetManager = Objects.requireNonNull(requireContext()).getAssets();
Context myContext = requireContext();
//Essential for creating the external storage directory for the first launch
myContext.getExternalFilesDir(null);
File databasesFolder = new File(myContext.getExternalFilesDir(null).getParent(), "com.mydb.orca/databases");
databasesFolder.mkdirs();

 if (files!= null) {
    for (String filename : files) {
        InputStream in;
        OutputStream out;
        try {
            in = assetManager.open("database/test/" + filename);
            File outFile = new File(databasesFolder, filename);
            out = new FileOutputStream(outFile);
            copyFile(in, out);
            in.close();
            out.flush();
            out.close();
        } catch (IOException e) {
            Log.e("tag", "Failed to copy asset file: " + filename, e);
        }
    }
} else {
    Log.e("Error NPE", "files is null");
}



private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
    out.write(buffer, 0, read);
}

如果有人有最好的解决方案那应该很好

我在 android 11 上测试过,它可以工作

关于java - 如何将任何类型的文件从 Assets 文件移动/复制到 JAVA 中的范围存储 ANDROID Q?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72541365/

相关文章:

java - 创建进度条 - 刷新 JDialog

java - 如何在android中填充线性布局?

android - Android 30+ 中的视频捕获 Intent - 只有所有者才能与待处理项目交互

android - 为什么某些音频文件无法在具有范围存储的 API 级别 30 上访问?

java - 在 Swing/AWT GUI 中移动正弦曲线

java - Py4j 在服务器中运行应用程序时出现异常

Android NDK 应用程序 - 集成文本文件进行部署的最佳方式

android - 为什么我来自 achartengine 的图表最初显示为缩放?

android - 当我只能处理文件或文件路径时如何处理 SAF?

java - BorderLayout 和 JPanel 与 JLabel