Android分享应用程序使用FileProvider的apk

时间:2017-06-13 13:00:17

标签: android android-intent apk android-fileprovider

我已尝试通过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

的已配置根目录

请帮我弄清楚我的错误。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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();
    }
  }

答案 2 :(得分:0)

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