【问题标题】:Android share app's apk using FileProviderAndroid 使用 FileProvider 共享应用程序的 apk
【发布时间】:2017-06-13 13:00:16
【问题描述】:

我尝试通过 Intent 共享应用的 apk 文件。我的清单文件中的提供程序:

`<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="package name"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/mypaths" />

mypaths 文件是:

<paths>
    <external-path name="apk_folder"/>
</paths>

我将意图和文件路径设置如下:

String packageName = getContext().getPackageName();
                PackageManager pm = getContext().getPackageManager();
        String apk = null;
                try {
                    ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
                     apk = ai.publicSourceDir;

                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                } 
                File apkFile = new File(apk);

                Uri uri = FileProvider.getUriForFile(getContext(), "package name", apkFile);

                Intent intent = ShareCompat.IntentBuilder.from(getActivity())
                        .setType("*/*")
                        .setStream(uri)
                        .setChooserTitle("Share via")
                        .createChooserIntent()
                        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                startActivity(intent);

我得到 IllegalArgumentException :

未能找到包含 /data/app/package name.edu-1/base.apk 的已配置根

请帮我找出我的错误。

【问题讨论】:

    标签: android android-intent apk android-fileprovider


    【解决方案1】:

    将代码中的 “包名称” 更改为 activity.getPackageName() 并将路径更改为 root-path

    或试试这个代码:

    清单

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

    res/xml/file_paths.xml

    <paths>
        <root-path
            name="app"
            path="/"/>
    </paths>
    

    代码

    public static void sendApkFile(Activity activity) {
        try {
    
          PackageManager pm = activity.getPackageManager();
          ApplicationInfo ai = pm.getApplicationInfo(activity.getPackageName(), 0);
          File srcFile = new File(ai.publicSourceDir);
    
          Intent intent = new Intent(Intent.ACTION_SEND);
          intent.setType("*/*");
          Uri uri = FileProvider.getUriForFile(context, activity.getPackageName(), srcFile);
          intent.putExtra(Intent.EXTRA_STREAM, uri);
          activity.grantUriPermission(activity.getPackageManager().toString(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
          activity.startActivity(intent);
    
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    

    如果你想要 APK 文件有其他名称,而不仅仅是 base.APK,试试这个

    public static void sendApplication(Activity activity) {
        ApplicationInfo app = activity.getApplicationContext().getApplicationInfo();
        String filePath = app.sourceDir;
    
        Intent intent = new Intent(Intent.ACTION_SEND);
    
        // MIME of .apk is "application/vnd.android.package-archive".
        // but Bluetooth does not accept this. Let's use "*/*" instead.
        intent.setType("*/*");
    
        // Append file and send Intent
        File originalApk = new File(filePath);
    
        try {
          //Make new directory in new location
          File tempFile = new File(activity.getExternalCacheDir() + "/ExtractedApk");
          //If directory doesn't exists create new
          if (!tempFile.isDirectory()) {
            if (!tempFile.mkdirs()) {
              return;
            }
          }
          //Get application's name and convert to lowercase
          tempFile = new File(tempFile.getPath() + "/" + activity.getString(app.labelRes).replace(" ", "").toLowerCase() + ".apk");
          //If file doesn't exists create new
          if (!tempFile.exists()) {
            if (!tempFile.createNewFile()) {
              return;
            }
          }
          //Copy file to new location
          InputStream in = new FileInputStream(originalApk);
          OutputStream out = new FileOutputStream(tempFile);
    
          byte[] buf = new byte[1024];
          int len;
          while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
          }
          in.close();
          out.close();
          System.out.println("File copied.");
          //Open share dialog
    
          Uri uri = FileProvider.getUriForFile(context, activity.getPackageName(), tempFile);
          intent.putExtra(Intent.EXTRA_STREAM, uri);
          activity.grantUriPermission(activity.getPackageManager().toString(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
          activity.startActivity(intent);
    
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    

    【讨论】:

    • 完美。谢谢@Criss
    【解决方案2】:

    我可以解决这个问题,只使用: <?xml version="1.0" encoding="utf-8"?> <resources> <root-path path="data/app/" name="external_files"/> </resources>

    【讨论】:

      【解决方案3】:

      FileProvider 中没有可以处理您指定位置的可用根。您需要为此创建自己的ContentProvider

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-17
        • 1970-01-01
        • 1970-01-01
        • 2013-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多