如何使用新的 FileProvider 共享当前应用的 APK(或其他已安装的应用)? [英] How to share current app's APK (or of other installed apps) using the new FileProvider?

查看:32
本文介绍了如何使用新的 FileProvider 共享当前应用的 APK(或其他已安装的应用)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去,使用一个简单的命令就可以轻松地与您想要的任何应用共享 APK 文件:

In the past, it was easy to share an APK file with any app you wanted, using a simple command:

startActivity(new Intent(Intent.ACTION_SEND,Uri.fromFile(filePath)).setType("*/*"));

问题

如果您的应用面向 Android API 24 (Android Nougat) 或更高版本,则上述代码将导致崩溃,由 FileUriExposedException 引起(写的关于它此处,以及打开 APK 文件的示例解决方案可以在此处)找到.

这实际上对我有用,使用以下代码:

This actually worked for me fine, using below code:

    File apkFile = new File(apkFilePathFromSomewhereInExternalStorage);
    Intent intent = new Intent(Intent.ACTION_SEND);
    Uri fileUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", apkFile);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_STREAM, fileUri);
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    startActivity(intent);

然而,问题是我也希望能够共享当前应用的 APK(以及其他已安装的应用).

However, the problem is that I also wish to be able to share the current app's APK (and also other installed apps).

为了获取当前应用的 APK 路径,我们使用:

For getting the path of the current app's APK, we use this:

        final PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
        File apkFile=new File(packageInfo.applicationInfo.publicSourceDir);
        ...

所有应用无需任何许可即可访问此 APK,每个已安装应用的 APK 也是如此.

This APK is accessible to all apps without the need of any permission, and so does the APK of every installed app.

但是当我将这个文件与上面的代码一起使用 FileProvider 进行共享时,我得到了这个异常:

But when I use this file with the above code for sharing using the FileProvider, I get this exception:

IllegalArgumentException: Failed to find configured root that contains ...

当我使用符号链接文件到 APK 时也是如此:

The same goes for when I use a symlinked file to the APK, as such:

        File apkFile=new File(packageInfo.applicationInfo.publicSourceDir);
        final String fileName = "symlink.apk";
        File symLinkFile = new File(getFilesDir(), fileName);
        if (!symLinkFile.exists())
            symLinkPath = symLinkFile.getAbsolutePath();
        createSymLink(symLinkPath, apkFile.getAbsolutePath());
        Uri fileUri= FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", symLinkFile);
        ...

public static boolean createSymLink(String symLinkFilePath, String originalFilePath) {
    try {
        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
            Os.symlink(originalFilePath, symLinkFilePath);
            return true;
        }
        final Class<?> libcore = Class.forName("libcore.io.Libcore");
        final java.lang.reflect.Field fOs = libcore.getDeclaredField("os");
        fOs.setAccessible(true);
        final Object os = fOs.get(null);
        final java.lang.reflect.Method method = os.getClass().getMethod("symlink", String.class, String.class);
        method.invoke(os, originalFilePath, symLinkFilePath);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

我的尝试

我尝试使用我认为有帮助的各种组合来配置 provider_paths.xml 文件,例如任何组合:

What I've tried

I tried to configure the provider_paths.xml file with various combinations of what I thought would help, such as any of those :

<external-path name="external_files" path="."/>
<external-path path="Android/data/lb.com.myapplication/" name="files_root" />
<external-path path="." name="external_storage_root" />
<files-path name="files" path="." />
<files-path name="files" path="" />

我还尝试禁用与此机制相关的strictMode:

I also tried to disable the strictMode that's associated with this mechanism:

    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());

问题

如何从我的应用可访问的每个可能路径共享任何 APK 文件,包括使用符号链接文件?

The question

How can I share any APK file, from every possible path that's accessible to my app, including using symlinked files ?

推荐答案

但是当我使用这个文件和上面的代码使用 FileProvider 共享时,我得到这个异常

But when I use this file with the above code for sharing using the FileProvider, I get this exception

那是因为 packageInfo.applicationInfo.publicSourceDir 不在 FileProvider 的可能根目录之一之下.

That is because packageInfo.applicationInfo.publicSourceDir is not underneath one of the possible roots for FileProvider.

当我使用符号链接文件到 APK 时也是如此

The same goes for when I use a symlinked file to the APK

也许符号链接在这里不起作用.您的 元素之一 —或者你完全不使用 path 的地方 —可以从 getFilesDir() 中提供普通文件.

Perhaps symlinks don't work here. One of your <files-path> elements — or one where you leave path off entirely — can serve ordinary files out of getFilesDir().

如何从我的应用可访问的每个可能路径共享任何 APK 文件,包括使用符号链接文件?

How can I share any APK file, from every possible path that's accessible to my app, including using symlinked files ?

由于没有对符号链接的官方支持,我无法帮助您.

Since there is no official support for symlinks, I can't help you there.

否则,您有三个主要选择:

Otherwise, you have three main options:

  1. FileProvider喜欢的地方复制APK文件

  1. Make a copy of the APK file someplace that FileProvider likes

尝试使用带有一些自定义的 我的 StreamProvider教它从 packageInfo.applicationInfo.publicSourceDir

Try using my StreamProvider with some custom extensions to teach it to serve from packageInfo.applicationInfo.publicSourceDir

编写您自己的 ContentProvider,从 packageInfo.applicationInfo.publicSourceDir

这篇关于如何使用新的 FileProvider 共享当前应用的 APK(或其他已安装的应用)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆