【问题标题】:how to find my android application's storing path of apk file如何找到我的android应用程序的apk文件存储路径
【发布时间】:2026-01-12 15:40:01
【问题描述】:

我想制作一个可以通过蓝牙发送自身(apk 文件)的应用程序。但我无法找到 apk 文件路径。我试过这段代码:

final PackageManager pm = this.getPackageManager();
    List<PackageInfo> packages =  pm.getInstalledPackages(PackageManager.GET_META_DATA);
    String st = null;
    for (PackageInfo packageInfo : packages) {
        if(packageInfo.packageName.contains("testbutton"))
        st=packageInfo.packageName;
    }

    Intent intent = new Intent();  
    intent.setAction(Intent.ACTION_SEND);  
    intent.setType("image/*");

    String uri = "/data/app/";
    uri+=st;
    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(uri)));
    startActivity(intent);

但 st 返回空值。 请帮我解决一下这个。提前致谢

【问题讨论】:

    标签: android package-managers


    【解决方案1】:

    无需迭代。获取应用程序本身的 APK 文件 uri 就这么简单:

    String appUri = getApplicationInfo().publicSourceDir;
    

    另请注意,文档中提到了publicSourceDir

    sourceDir 的公开可用部分的完整路径, 包括资源和清单。这可能不同于 sourceDir 如果应用程序被前向锁定。

    还要注意,要发送 APK 文件,您需要将类型设置为 application/vnd.android.package-archive 而不是 image/*

    所以完整的 sn-p 将是:

    String appUri = getApplicationInfo().publicSourceDir;
    Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
    sharingIntent.setType("application/vnd.android.package-archive");
    sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(appUri)));
    startActivity(Intent.createChooser(sharingIntent, "Share via"));
    

    【讨论】:

    • publicSourceDir 和 sourceDir 有什么区别?两者似乎具有相同的价值......
    • @androiddeveloper 正如文档所述,它在 Forward Locked 应用程序中不同。有关前向锁定应用程序的更多信息,您可以在pm install 选项下查看adb documentation
    • 你的意思是“-l:安装带有前向锁的包”。 ?但是这是什么意思?什么是“前向锁定应用程序”?假设我想分享应用的 APK,我应该使用 publicSourceDir 还是应该使用 sourceDir ?
    • @androiddeveloper 前向锁定应用程序是安装程序不希望用户共享应用程序包的应用程序。因此,即使您愿意,您也无法访问前向锁定应用程序的 sourceDir(至少没有 root 访问权限)。因此,对于正常使用,请始终使用publicSourceDir
    • 我认为“-l”不起作用。 “adb”工具说这是一个未知参数......这里:issuetracker.google.com/issues/139965909。此外,在我的所有应用程序(包括系统应用程序)中,两个文件都具有相同的路径。
    【解决方案2】:

    感谢@Kanak 的帮助,我终于找到了适合此目的的正确答案:)

    PackageManager pm = getPackageManager();
        String uri = null;
        for (ApplicationInfo app : pm.getInstalledApplications(0)) {
            if(!((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1))
                if(!((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1)){
                    uri=app.sourceDir;
                      if(uri.contains("com.example.test"))
                      break;
                }
        }
    
        Intent intent = new Intent();  
        intent.setAction(Intent.ACTION_SEND);  
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(uri)));
        startActivity(intent);
    

    【讨论】:

    • 嘿,我的 apk 以 base.apk 的形式出现,而不是 appname.apk。有没有办法在出去的时候改名字?
    • @Visionwriter 我没有尝试过,但我认为你可以通过复制文件并重命名它然后发送重命名的文件来做到这一点。 here's 复制和重命名的例子,希望对你有帮助。
    • Uri.fromFile 在您使用 targetSdk 24 或更高版本时不再起作用。
    【解决方案3】:
    List<ApplicationInfo> PackageManager.getInstalledApplications() // will give you a list of the installed applications, and 
    ApplicationInfo.sourceDir  //is the path to the .apk file.
    
    PackageManager pm = getPackageManager();
    
    for (ApplicationInfo app : pm.getInstalledApplications(0)) {
      Log.d("PackageList", "package: " + app.packageName + ", sourceDir: " + app.sourceDir);
    }
    

    输出如下:

    package: com.tmobile.themechooser, sourceDir: /system/app/ThemeChooser.apk
    package: com.tmobile.thememanager, sourceDir: /system/app/ThemeManager.apk
    package: com.touchtype.swiftkey, sourceDir: /data/app/com.touchtype.swiftkey-1.apk
    package: com.twitter.android, sourceDir: /data/app/com.twitter.android-2.apk
    package: fm.last.android, sourceDir: /data/app/fm.last.android-1.apk
    

    所以,这样你就可以找到所有应用 apk 的路径。

    【讨论】:

    • 谢谢,sourceDir 很有用,但我仍然无法从列表中选择我自己的应用程序。 if((app.packageName).contains("testbuttun")) 不起作用
    • publicSourceDir 和 sourceDir 有什么区别?两者似乎具有相同的价值......
    最近更新 更多