如何在Java中判断APK是否已签名?Android Studio开发中签名信息无法获取问题排查
解决Android应用无法获取签名证书信息的问题
嘿,我一眼就发现问题所在了——你用错方法啦!getPackageArchiveInfo是用来读取未安装的APK文件的信息,而你要获取的是当前正在运行的已安装应用的签名,这个方法完全不适用,这就是为什么你拿到的PackageInfo为空,最后得到长度为0的签名数组。
下面是修正后的完整代码,我会把关键修改点逐一说明:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Signature[] sigs = new Signature[0]; try { PackageManager pm = getPackageManager(); String packageName = getPackageName(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { // 针对Android P及以上版本,使用getPackageInfo获取已安装应用信息 PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES); if (packageInfo != null && packageInfo.signingInfo != null) { // 获取APK内容签名者 sigs = packageInfo.signingInfo.getApkContentsSigners(); } } else { // 针对Android P以下版本,使用GET_SIGNATURES标记 PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); if (packageInfo != null) { sigs = packageInfo.signatures; } } // 优化字符串拼接:用StringBuilder比concat高效,因为String是不可变对象 StringBuilder sigStringBuilder = new StringBuilder(); for (Signature sig : sigs) { sigStringBuilder.append(sig.toCharsString()).append("; "); } String sigstring = sigStringBuilder.toString(); Log.i("SignatureLog", "SigString: " + sigstring); Log.i("SignatureLog", "NumberOfSignatures: " + sigs.length); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); Log.e("SignatureLog", "获取包信息失败:" + e.getMessage()); } }
关键修改说明:
- 替换核心方法:把
getPackageArchiveInfo换成getPackageInfo,后者专门用于获取当前已安装应用的包信息 - 异常处理:添加
PackageManager.NameNotFoundException的捕获,避免因包名错误等情况崩溃 - 字符串拼接优化:原代码中
sigstring.concat(...)不会改变原字符串(String是不可变对象),改用StringBuilder更高效且能正确拼接内容 - 空值安全判断:增加对
packageInfo和signingInfo的空值判断,避免空指针异常
运行这段代码后,你应该就能看到正确的签名字符串和签名数量了。
内容的提问来源于stack exchange,提问作者cagcoach
相关产品推荐
相关产品推荐

