Android 獲取應(yīng)用簽名的實(shí)現(xiàn)
本文主要講下在android中如何獲取應(yīng)用簽名. 也方便平時(shí)用來區(qū)分一個(gè)應(yīng)用是不是原包應(yīng)用.
1: 通過PackageManager獲取簽名信息
首先,通過packageManager獲取到指定應(yīng)用的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();
//獲取已安裝應(yīng)用程序的信息,包括應(yīng)用程序的包名、圖標(biāo)、名稱等元數(shù)據(jù)。
List applications = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : applications) {
try {
//獲取指定應(yīng)用程序的包信息,其中包括應(yīng)用程序的簽名信息
PackageInfo packageInfo = packageManager.getPackageInfo(applicationInfo.packageName, PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}2: 獲取SHA1
下面是封裝的utils方法,用于根據(jù)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 < digest.length; j++) {
int v = digest[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
} catch (Throwable e) {
e.printStackTrace();
}
return "";
}
}
下面是整理的一個(gè)小demo,展示當(dāng)前設(shè)備的應(yīng)用列表以及應(yīng)用簽名,包名,icon信息.
3:demo
創(chuàng)建mainacitity,主要用GridView展示獲取到的應(yīng)用列表。
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<ApplicationInfo> installedApplications = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
apkAdapter = new ApkAdapter(installedApplications, this);
gridView.setAdapter(apkAdapter);
}
}
acitivity布局如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/grid_sign"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
ApkAdapter代碼如下:
public class ApkAdapter extends BaseAdapter {
private List<ApplicationInfo> list;
private Context context;
private PackageManager packageManager;
public ApkAdapter(List<ApplicationInfo> 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根據(jù)包名返回PackageInfo 對(duì)象
packageInfo.signatures獲取簽名
applicationInfo.loadIcon用于獲取應(yīng)用圖標(biāo)
applicationInfo.packageName獲取應(yīng)用包名
applicationInfo的其他屬性還有:
- packageName:應(yīng)用程序的包名。
- className:應(yīng)用程序的主Activity類名。
- processName:應(yīng)用程序的進(jìn)程名。
- sourceDir:應(yīng)用程序的APK文件路徑。
- dataDir:應(yīng)用程序的數(shù)據(jù)目錄路徑。
- targetSdkVersion:應(yīng)用程序的目標(biāo)SDK版本。
- uid:應(yīng)用程序的用戶ID。
- flags:應(yīng)用程序的標(biāo)志位,如FLAG_SYSTEM表示系統(tǒng)應(yīng)用。
- enabled:應(yīng)用程序是否啟用。
- metaData:應(yīng)用程序的元數(shù)據(jù),可以在AndroidManifest.xml中定義。
以及item的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="100dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/item_icon"
android:layout_margin="10dp"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/item_icon"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="xxx"
android:layout_alignParentTop="true"
android:textColor="@color/black"
android:id="@+id/item_name"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ff0000"
android:textSize="14sp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:text="xxxxxxxxx"
android:id="@+id/item_sign"
/>
</RelativeLayout>
</RelativeLayout>
最后展示下效果圖:

到此這篇關(guān)于Android 獲取應(yīng)用簽名的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Android 獲取應(yīng)用簽名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android布局控件DrawerLayout實(shí)現(xiàn)完美側(cè)滑效果
這篇文章主要為大家詳細(xì)介紹了Android布局控件DrawerLayout實(shí)現(xiàn)完美側(cè)滑效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
Android 動(dòng)畫實(shí)現(xiàn)幾種方案
這篇文章主要介紹了Android 動(dòng)畫實(shí)現(xiàn)幾種方案的相關(guān)資料,需要的朋友可以參考下2017-06-06
Android手勢控制實(shí)現(xiàn)縮放、移動(dòng)圖片
這篇文章主要為大家詳細(xì)介紹了Android手勢控制實(shí)現(xiàn)縮放、移動(dòng)圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02
Android基于reclyview實(shí)現(xiàn)列表回彈動(dòng)畫效果
這篇文章主要為大家詳細(xì)介紹了Android基于reclyview實(shí)現(xiàn)列表回彈動(dòng)畫效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
Flutter配置代理抓包實(shí)現(xiàn)過程詳解
這篇文章主要為大家介紹了Flutter配置代理抓包實(shí)現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Android提高之Android手機(jī)與BLE終端通信
這篇文章主要介紹了Android手機(jī)與BLE終端通信的方法,有很大的實(shí)用價(jià)值,需要的朋友可以參考下2014-08-08

