android - 如何使用 Intent.ACTION_VIEW 打开保存到内部存储的私有(private)文件?

标签 android android-intent

我正在尝试使用示例程序将文件存储在内部存储器中并使用 Intent.ACTION_VIEW。

为了以私有(private)模式存储文件,我按照提供的步骤 here.

我能够在/data/data/com.storeInternal.poc/files 的内部存储中找到创建的文件。*

But when I tried to open file,it does not open.

请在下面找到我使用的代码。

public class InternalStoragePOCActivity extends Activity {
    /** Called when the activity is first created. */
    String FILENAME = "hello_file.txt";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        createFile();
        openFile(FILENAME);
    }

    public FileOutputStream getStream(String path) throws FileNotFoundException {
        return openFileOutput(path, Context.MODE_PRIVATE);
    }

    public void createFile(){

        String string = "hello world!";
        FileOutputStream fout = null;
        try {
            //getting output stream
            fout = getStream(FILENAME);
            //writng data
            fout.write(string.getBytes());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fout!=null){
                //closing the output stream
                try {
                    fout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }

    public void openFile(String filePath) {
        try {
            File temp_file = new File(filePath);

            Uri data = Uri.fromFile(temp_file);
            String type = getMimeType(data.toString());

            Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
            intent.setDataAndType(data, type);
            startActivity(intent);

        } catch (Exception e) {
            Log.d("Internal Storage POC ", "No Supported Application found to open this file");
            e.printStackTrace();

        }
    }

    public static String getMimeType(String url) {
        String type = null;
        String extension = MimeTypeMap.getFileExtensionFromUrl(url);

        if (extension != null) {
            MimeTypeMap mime = MimeTypeMap.getSingleton();
            type = mime.getMimeTypeFromExtension(extension);
        }

        return type;
    }
}

我如何打开任何其他现有/适当应用程序使用 Context.MODE_PRIVATE 存储的文件。例如:file.pdf 应该由 PDF 阅读器打开,视频由视频播放器等打开。

最佳答案

您无法通过 Intent 将内部存储中的文件(如 URI 引用)共享/发送到另一个应用程序。一个应用程序不能读取另一个应用程序的私有(private)数据(除非它是通过内容提供者)。您在 Intent 中传递文件的 URI(而不是实际文件本身),并且接收该 Intent 的应用程序需要能够从该 URI 中读取。

最简单的解决方案是先将文件复制到外部存储并从那里共享。如果您不想这样做,请创建一个 Content Provider 来公开您的文件。可以在此处找到示例:Create and Share a File from Internal Storage

编辑:使用内容提供者:

首先创建您的内容提供者类,如下所示。这里重要的覆盖是'openFile'。当使用文件 URI 调用您的内容提供程序时,此方法将运行并为其返回 ParcelFileDescriptor。其他方法也需要存在,因为它们在 ContentProvider 中是抽象的。

public class MyProvider extends ContentProvider {

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    File privateFile = new File(getContext().getFilesDir(), uri.getPath());
    return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
}

@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
    return 0;
}

@Override
public String getType(Uri arg0) {
    return null;
}

@Override
public Uri insert(Uri arg0, ContentValues arg1) {
    return null;
}

@Override
public boolean onCreate() {
    return false;
}

@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
        String arg4) {
    return null;
}

@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
    return 0;
}
}

在应用程序标签内的 list 中定义您的提供程序,并使用exported=true 以允许其他应用程序使用它:

<provider android:name=".MyProvider" android:authorities="your.package.name" android:exported="true" />

在您的 Activity 中的 openFile() 方法中,设置一个 URI,如下所示。此 URI 与文件名一起指向包中的内容提供程序:

Uri uri = Uri.parse("content://your.package.name/" + filePath);

最后,在 Intent 中设置这个 uri:

intent.setDataAndType(uri, type);

记得在我上面使用“your.package.name”的地方插入你自己的包名。

关于android - 如何使用 Intent.ACTION_VIEW 打开保存到内部存储的私有(private)文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21304489/

相关文章:

android - android中通过fragment访问Database类

android - Notification、PendingIntent 和 Intent Flags 问题

安卓:AdMob 不工作

android - "Location of the Android SDK has not been set up in the preferences"错误

android - ListView 内的按钮不可点击

android - 如何获取发送 Intent Activity 的名称?

Android调用 Intent 多号码选择

android - 如何传递 Intent 要求用户选择任何应用程序扫描二维码?

android - 使用 ADB 发送 Intent

android - vold和udevd的区别