行业知识
Android 获取应用签名
Android 获取应用签名
本文主要讲下在android中如何获取应用签名. 也方便平时用来区分一个应用是不是原包应用.
1: 通过PackageManager获取签名信息
首先,通过packageManager获取到指定应用的PackageInfo. 这里需要传入的flag是PackageManager.GET_SIGNATURES
/**
- {@link PackageInfo} flag: return information about the
- signatures included in the package.
- @deprecated use {@code GET_SIGNING_CERTIFICATES} instead
*/
@Deprecated
public static final int GET_SIGNATURES = 0x00000040;
PackageManager pm = getPackageManager();
//获取已安装应用程序的信息,包括应用程序的包名、图标、名称等元数据。
List applications = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : applications) {
try {
//获取指定应用程序的包信息,其中包括应用程序的签名信息
PackageInfo packageInfo = packageManager.getPackageInfo(applicationInfo.packageName, PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
2: 获取SHA1
下面是封装的utils方法,用于根据packageInfo.signatures来获取apk的sha1值。
public class ShaUtils { public static String getSHA1(byte[] sig) { final char[] hexArray = "0123456789ABCDEF".toCharArray(); try { MessageDigest md = MessageDigest.getInstance("SHA1"); byte[] digest = md.digest(sig); char[] hexChars = new char[digest.length * 2]; for (int j = 0; j >> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); } catch (Throwable e) { e.printStackTrace(); } return ""; }}下面是整理的一个小demo,展示当前设备的应用列表以及应用签名,包名,icon信息.
3:demo
创建mainacitity,主要用GridView展示获取到的应用列表。
public class MainActivity extends AppCompatActivity { private GridView gridView; private ApkAdapter apkAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gridView = findViewById(R.id.grid_sign); PackageManager packageManager = getPackageManager(); List installedApplications = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); apkAdapter = new ApkAdapter(installedApplications, this); gridView.setAdapter(apkAdapter); }}acitivity布局如下:
ApkAdapter代码如下:
public class ApkAdapter extends BaseAdapter { private List list; private Context context; private PackageManager packageManager; public ApkAdapter(List list, Context context) { this.list = list; this.context = context; packageManager = context.getPackageManager(); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View view, ViewGroup parent) { if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.item_apk, parent, false); } ApplicationInfo applicationInfo = list.get(position); ImageView icon = (ImageView) view.findViewById(R.id.item_icon); icon.setImageDrawable(applicationInfo.loadIcon(packageManager)); TextView label = (TextView) view.findViewById(R.id.item_name); label.setText(applicationInfo.packageName); TextView sign = (TextView) view.findViewById(R.id.item_sign); StringBuilder stringBuilder = new StringBuilder(); try { PackageInfo packageInfo = packageManager.getPackageInfo(applicationInfo.packageName, PackageManager.GET_SIGNATURES); Signature[] signs = packageInfo.signatures; for (Signature sig : signs) { String sha1 = ShaUtils.getSHA1(sig.toByteArray()); stringBuilder.append("Signature: "+sha1+"\n"); Log.d("Signature", "packageName = " + packageInfo.packageName + ", signature = " + sha1); } sign.setText(stringBuilder.toString()); } catch (Throwable e) { Log.e("Signature", "getView: ", e); } return view; }}getPackageInfo根据包名返回PackageInfo 对象packageInfo.signatures获取签名applicationInfo.loadIcon用于获取应用图标applicationInfo.packageName获取应用包名
applicationInfo的其他属性还有:
- packageName:应用程序的包名。
- className:应用程序的主Activity类名。
- processName:应用程序的进程名。
- sourceDir:应用程序的APK文件路径。
- dataDir:应用程序的数据目录路径。
- targetSdkVersion:应用程序的目标SDK版本。
- uid:应用程序的用户ID。
- flags:应用程序的标志位,如FLAG_SYSTEM表示系统应用。
- enabled:应用程序是否启用。
- metaData:应用程序的元数据,可以在AndroidManifest.xml中定义。
以及item的布局:
最后展示下效果图:
下一篇:你好英语怎么写大写?