前言: 有第三方要借我们的某软件临时一用,由于该软件只在内部使用,为了避免流出,上头要求对软件做处理,让app拷贝或者分享后不能直接使用。
要点:
- Android设备获取唯一UID(或其他数据,总之可以用来加密就行)
- AlertDialog自定义为可复制,可编辑,在没有输对序列号的情况下起到封锁app的作用
控制app进入的方法放在入口Activity中的OnCreate方法里:
(部分代码简化,只放关键代码)
//用SP作为序列号及激活状态的存储手段
SharedPreferences preferences = getSharedPreferences(SPNAME, Activity.MODE_PRIVATE);
//使用getSetUID方法获取设备UID,该方法放在下边
final String DEVICE_ID = getSetUID(MainActivity.this);
//通过一定的算法获取序列号,这个方法就不放了
final String IDKey=KeyUtils.getKey(DEVICE_ID);
if(!preferences.getString("IDKey","").equals(IDKey)) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
//自定义的Alertdialog界面
View view= LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog,null);
final TextView tv= (TextView) view.findViewById(R.id.SerialNum);
tv.setText(DEVICE_ID);
final EditText edt = (EditText) view.findViewById( R.id.Key);
builder.setTitle("请输入序列号")
.setMessage("你的ID为:" )
.setView(view)
.setPositiveButton("确定",null)
.setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
System.exit(0);
}
});
final AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.show();
//该方法放在show()后,可以防止点击positive的button后对话框消失 dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String str=edt.getText().toString().trim();
if (IDKey.equals(str)) {
SharedPreferences.Editor editor = getSharedPreferences(SPNAME, Activity.MODE_PRIVATE).edit();
editor.putString("IDKey", str);
editor.apply();
dialog.dismiss();
} else {
Toast.makeText(MainActivity.this, "输入错误,请重新输入", Toast.LENGTH_SHORT).show();
}
}
});
}
dialog的布局文件如下,一个文本框一个编辑框,TextView设置为可复制,方便获取UID;
<?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="match_parent" >
<TextView
android:id="@+id/SerialNum"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginBottom="10dp"
android:textSize="20sp"
android:textColor="@color/encode_view"
android:textIsSelectable="true"/>
<EditText
android:id="@+id/Key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/SerialNum"
android:hint="请输入序列号"
/>
</RelativeLayout>
获取设备ID的方法如下:
private String getSetUID(Context context){
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String DEVICE_ID = tm.getDeviceId();
Log.i(TAG, "getADUID: "+DEVICE_ID);
//在某些手机中无法获取该值,就自己生成一个随机序列放在sp中
//生成随机数的方法随你喜欢
if(DEVICE_ID==null){
SharedPreferences sp=getSharedPreferences(SPNAME, Activity.MODE_PRIVATE);
String s=sp.getString("uid","");
if(s.equals("")){
Random random=new Random(12);
long num=random.nextInt()+548801;
if(num<0)num=-1*num;
Log.i(TAG, "getSetUID: "+num);
SharedPreferences.Editor ed=sp.edit();
DEVICE_ID=num+"";
ed.putString("uid",DEVICE_ID);
}else{
DEVICE_ID=sp.getString("uid","");
}
}
return DEVICE_ID;
}
效果如下:
这样拿到软件的人就只能把这段数字发给你,你用你的算法获取序列号后再给他,他才可以使用你的app。
当然,这种加密方法是非常简陋也容易破解的,但是在要求不那么高的情况下可以一用。