我如何在我的应用程序中共享apk文件(发送应用程序本身)

时间:2016-09-14 08:38:49

标签: java android apk share filenames

我正在尝试使用此代码将我的应用程序apk文件发送到另一台设备:

public static void sendAppItself(Activity paramActivity) throws IOException {
    PackageManager pm = paramActivity.getPackageManager();
    ApplicationInfo appInfo;
    try {
        appInfo = pm.getApplicationInfo(paramActivity.getPackageName(),
                PackageManager.GET_META_DATA);
        Intent sendBt = new Intent(Intent.ACTION_SEND);
        sendBt.setType("*/*");
        sendBt.putExtra(Intent.EXTRA_STREAM,
                Uri.parse("file://" + appInfo.publicSourceDir));

        paramActivity.startActivity(Intent.createChooser(sendBt,
                "Share it using"));
    } catch (PackageManager.NameNotFoundException e1) {
        e1.printStackTrace();
    }
}

此代码效果很好。

但是与此代码共享的apk文件的名称是 base.apk

如何更改?

4 个答案:

答案 0 :(得分:13)

将文件从源目录复制到新目录。 复制时重命名文件并共享复制的文件。 共享完成后删除临时文件。

 private void shareApplication() {
    ApplicationInfo app = 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(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() + "/" + 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
        intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
        startActivity(Intent.createChooser(intent, "Share app via"));

    } catch (IOException e) {
        e.printStackTrace();
    }
}

答案 1 :(得分:2)

这只会发生,因为它是由base.apk名称保存的。 要根据需要共享它,您只需将此文件复制到另一个目录路径并在那里重命名。然后使用新文件进行分享。

数据文件夹中的此文件路径[file:///data/app/com.yourapppackagename/base.apk]仅具有读取权限,因此您无法在那里重命名.apk文件。

答案 2 :(得分:1)

您可以使用此功能,在api 22和27上进行测试

    private void shareApplication() {
        ApplicationInfo app = 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(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() + "/" + 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
//          intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
            Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", tempFile);
//          intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
            intent.putExtra(Intent.EXTRA_STREAM, photoURI);
            startActivity(Intent.createChooser(intent, "Share app via"));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

答案 3 :(得分:0)

如果有人试图从片段生成 apk,他们可能需要更改@sajad 的回答中的几行,如下所示

  1. 替换

    文件 tempFile = new File(getExternalCacheDir() + "/ExtractedApk");

File tempFile = new File(getActivity().getExternalCacheDir() + "/ExtractedApk");

2.同时为下面一行导入BuildConfig

import androidx.multidex.BuildConfig // 不要这样做!!! ,使用您的应用 BuildConfig。

如果你低于例外

<块引用>

无法找到具有权限的提供者的元数据

  1. 在清单文件中查找提供者信息

Manifest

然后在您的清单文件中查找“provider”的名称和权限,如果它是 androidx.core.content.FileProvider 则 替换

Uri photoURI = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", tempFile);

Uri photoURI = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".fileprovider", tempFile);