为什么读取内部存储中的文件需要许可?

时间:2018-09-21 06:42:09

标签: android

这里是读取的代码:

        try {
          FileInputStream fis = openFileInput("img.png"); 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

从设备资源管理器中,我确保img.png文件确实存在: enter image description here

但发生错误,这是logcat:

/data/data/xxx.xxx.xxx/files/img.png: open failed: EACCES (Permission denied)

如官方文档所述,

  

与外部存储目录不同,您的应用不需要   读取和写入内部目录的任何系统权限   这些方法返回的

那为什么会这样呢?

2 个答案:

答案 0 :(得分:1)

我明白了,您正在尝试从应用程序的内部目录添加文件。 我创建了一个在文件目录和共享中生成随机位图图像的应用程序。您可以使用此代码解决您的问题。

最初,您需要在'res'文件夹下的XML目录中创建一个XML文件。这是我项目的完整结构。

directories

将此代码粘贴到file_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="files"
        path="." />
</paths>

现在在标记之间的AndroidManifest.xml中添加提供程序。

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.myfileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider" />
    </provider>

此后,移至MainActivity.java文件。我还使用了一个Java类位图工厂来创建随机位图。我认为您不需要。

public class MainActivity extends Activity {

    private static final String SHARED_PROVIDER_AUTHORITY = BuildConfig.APPLICATION_ID + ".myfileprovider";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void share(final View view) throws IOException {
        // Create a random image and save it in private app folder
        final File sharedFile = createFile();

        // Get the shared file's Uri
        final Uri uri = FileProvider.getUriForFile(this, SHARED_PROVIDER_AUTHORITY, sharedFile);

        // Create a intent
        final ShareCompat.IntentBuilder intentBuilder = ShareCompat.IntentBuilder.from(this)
            .setType("image/*")
            .addStream(uri);

        // Start the intent
        final Intent chooserIntent = intentBuilder.createChooserIntent();
        startActivity(chooserIntent);
    }

    @NonNull
    private File createFile() throws IOException {
        final RandomBitmapFactory bitmapFactory = new RandomBitmapFactory();
        final Bitmap randomBitmap = bitmapFactory.createRandomBitmap();

        final File sharedFile = File.createTempFile("picture", ".png", getFilesDir());
        sharedFile.createNewFile();

        writeBitmap(sharedFile, randomBitmap);
        return sharedFile;
    }

    private static void writeBitmap(final File destination,
                                final Bitmap bitmap) {
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(destination);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            close(outputStream);
        }
    }

    private static void close(final Closeable closeable) {
        if (closeable == null) return;
        try {
            closeable.close();
        } catch (IOException ignored) {
        }
    }
}

这是一个完整的程序,无需任何许可即可将图像文件读写到内部目录。

Image saved in internal

希望这可以解决您的问题。

答案 1 :(得分:-2)

以编程方式检查权限。当您要访问该文件时。

int permissionCheck = ContextCompat.checkSelfPermission(ctx,READ_EXTERNAL_STORAGE);
if (permissionCheck== PackageManager.PERMISSION_GRANTED){
 //this means permission is granted and you can do read and write
}else{
ActivityCompat.requestPermissions((Activity) ctx, 

新字符串[{Manifest.permission.READ_EXTERNAL_STORAGE},1);     }

相关问题