├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── chengmengzhen │ │ └── securitykeybroad │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── chengmengzhen │ │ │ └── securitykeybroad │ │ │ ├── BaseApplication.java │ │ │ ├── MainActivity.java │ │ │ ├── jninative │ │ │ └── JniEncode.java │ │ │ ├── utils │ │ │ └── DESCoding.java │ │ │ └── view │ │ │ └── SercurityDialog.java │ ├── jni │ │ ├── JniEncode.c │ │ └── com_example_chengmengzhen_securitykeybroad_jninative_JniEncode.h │ └── res │ │ ├── anim │ │ ├── input_method_enter.xml │ │ └── input_method_exit.xml │ │ ├── drawable │ │ ├── back.png │ │ ├── background_stroke.xml │ │ ├── del.png │ │ ├── dot.png │ │ ├── keybroad_btn_normal.xml │ │ ├── keybroad_btn_selected.xml │ │ └── keybroad_btn_selector.xml │ │ ├── interpolator │ │ ├── accelerate_cubic.xml │ │ ├── accelerate_quint.xml │ │ ├── anticipate.xml │ │ ├── decelerate_cubic.xml │ │ └── decelerate_quint.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── ui_keybroad.xml │ │ ├── ui_pwd_contanier.xml │ │ ├── ui_security_dialog.xml │ │ └── ui_title.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── chengmengzhen │ └── securitykeybroad │ └── ExampleUnitTest.java ├── build.gradle ├── gifres └── SecurityKeyBroad.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | SecurityKeyBroad -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.7 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SecurityKeyBroad 2 | 3 | ##效果图 4 | ![image](gifres/SecurityKeyBroad.gif) 5 | 6 | ##使用 7 | 8 | ``` 9 | SercurityDialog dialog = new SercurityDialog(this); 10 | dialog.setOnInputCompleteListener(new SercurityDialog.InputCompleteListener() { 11 | @Override 12 | public void inputComplete(String PassWord) { 13 | //加密 14 | //作者这里使用jni加密,需要了解的可以查看源码 15 | } 16 | }); 17 | dialog.show(); 18 | ``` 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.0" 6 | 7 | defaultConfig { 8 | applicationId "com.example.chengmengzhen.securitykeybroad" 9 | minSdkVersion 15 10 | targetSdkVersion 24 11 | versionCode 1 12 | versionName "1.0" 13 | ndk { 14 | moduleName "encryp" 15 | ldLibs "dl", "log" 16 | abiFilters "armeabi-v7a","x86" 17 | 18 | } 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | } 27 | 28 | dependencies { 29 | compile fileTree(dir: 'libs', include: ['*.jar']) 30 | testCompile 'junit:junit:4.12' 31 | compile 'com.android.support:appcompat-v7:24.0.0' 32 | } 33 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/chengmengzhen/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/chengmengzhen/securitykeybroad/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.example.chengmengzhen.securitykeybroad; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chengmengzhen/securitykeybroad/BaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.chengmengzhen.securitykeybroad; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.os.Handler; 6 | import android.os.Looper; 7 | 8 | 9 | public class BaseApplication extends Application 10 | { 11 | 12 | private static Context mContext; 13 | private static Handler mHandler; 14 | private static Thread mMainThread; 15 | private static long mMainThreadId; 16 | private static Looper mMainThreadLooper; 17 | 18 | @Override 19 | public void onCreate() 20 | { 21 | super.onCreate(); 22 | 23 | // 程序的入口 24 | mContext = this; 25 | 26 | // handler,用来子线程和主线程通讯 27 | mHandler = new Handler(); 28 | 29 | // 主线程 30 | mMainThread = Thread.currentThread(); 31 | // id 32 | // mMainThreadId = mMainThread.getId(); 33 | mMainThreadId = android.os.Process.myTid(); 34 | 35 | // looper 36 | mMainThreadLooper = getMainLooper(); 37 | } 38 | 39 | public static Context getContext() 40 | { 41 | return mContext; 42 | } 43 | 44 | public static Handler getHandler() 45 | { 46 | return mHandler; 47 | } 48 | 49 | public static Thread getMainThread() 50 | { 51 | return mMainThread; 52 | } 53 | 54 | public static long getMainThreadId() 55 | { 56 | return mMainThreadId; 57 | } 58 | 59 | public static Looper getMainThreadLooper() 60 | { 61 | return mMainThreadLooper; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chengmengzhen/securitykeybroad/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.chengmengzhen.securitykeybroad; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.Toast; 8 | 9 | import com.example.chengmengzhen.securitykeybroad.jninative.JniEncode; 10 | import com.example.chengmengzhen.securitykeybroad.utils.DESCoding; 11 | import com.example.chengmengzhen.securitykeybroad.view.SercurityDialog; 12 | 13 | import java.util.Arrays; 14 | 15 | public class MainActivity extends AppCompatActivity { 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_main); 21 | } 22 | 23 | /** 24 | * 这个click函数在activity_main中有指定,相当于重写了onClick()方法。 25 | * 26 | * @param view 27 | */ 28 | public void click(View view) { 29 | // 创建显示SercurityDialog对话框,也就是输入密码对话框 30 | SercurityDialog dialog = new SercurityDialog(this); 31 | dialog.setOnInputCompleteListener(new SercurityDialog.InputCompleteListener() { 32 | 33 | /** 34 | * 当密码输入完成的时候,这个函数会被回调 35 | * 36 | * @param PassWord 37 | */ 38 | @Override 39 | public void inputComplete(String PassWord) { 40 | 41 | //把password转为byte数组 42 | String[] pwdStrings = PassWord.replace("[", "").replace("]", "").split(","); 43 | byte[] PwdBytes = new byte[pwdStrings.length]; 44 | for (int i = 0; i < PwdBytes.length; i++) { 45 | PwdBytes[i] = Byte.valueOf(pwdStrings[i]); 46 | } 47 | 48 | //jni加密 49 | String enPwd = JniEncode.encryption(PwdBytes); 50 | 51 | //加密后转为byte数组 52 | String[] split = enPwd.replace("[", "").replace("]", "").split(","); 53 | byte[] enPwdBytes = new byte[split.length]; 54 | for (int i = 0; i < enPwdBytes.length; i++) { 55 | enPwdBytes[i] = Byte.valueOf(split[i].trim()); 56 | } 57 | 58 | byte[] key = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 59 | 60 | //解密 61 | final byte[] deSedes = new DESCoding().decode(enPwdBytes, key, "DESede"); 62 | Toast.makeText(MainActivity.this, "你输入的密码是:" + Arrays.toString(deSedes), Toast.LENGTH_LONG).show(); 63 | } 64 | }); 65 | dialog.show(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chengmengzhen/securitykeybroad/jninative/JniEncode.java: -------------------------------------------------------------------------------- 1 | package com.example.chengmengzhen.securitykeybroad.jninative; 2 | 3 | /** 4 | * Created by chengmengzhen on 16/7/1. 5 | */ 6 | public class JniEncode { 7 | public native static String encryption(byte[] pwd); 8 | public native static byte[] decryption(byte[] pwd); 9 | static { 10 | System.loadLibrary("encryp"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chengmengzhen/securitykeybroad/utils/DESCoding.java: -------------------------------------------------------------------------------- 1 | package com.example.chengmengzhen.securitykeybroad.utils; 2 | 3 | 4 | import android.text.LoginFilter; 5 | import android.util.Log; 6 | 7 | import java.util.Arrays; 8 | 9 | import javax.crypto.Cipher; 10 | import javax.crypto.SecretKey; 11 | import javax.crypto.spec.SecretKeySpec; 12 | 13 | /** 14 | * 加密算法 15 | * 16 | * @author 17 | */ 18 | public class DESCoding { 19 | 20 | private static String mAlgorithm = "DESede"; //定义 加密算法,默认为DESede 21 | private byte[] keyBytes = null; 22 | 23 | private static String trimAlgorithm(String alg) { 24 | int p = alg.indexOf('/'); 25 | if (p == -1) 26 | return alg; 27 | return alg.substring(0, p); 28 | } 29 | 30 | /** 31 | * 对指定的字节数组进行加密 32 | * 33 | * @param src 需要进行加密的字节数组 34 | * @return byte[] 加密后的字节数组,若加密失败,则返回null 35 | */ 36 | public static String encode(byte[] src) { 37 | try { 38 | // 生成密钥 39 | byte[] keyBytes = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 40 | Log.e("11", "11"); 41 | SecretKey deskey = new SecretKeySpec(keyBytes, trimAlgorithm("DESede")); 42 | //加密 43 | Cipher c1 = Cipher.getInstance("DESede"); 44 | c1.init(Cipher.ENCRYPT_MODE, deskey); 45 | return Arrays.toString(c1.doFinal(src)); 46 | } catch (java.security.NoSuchAlgorithmException e1) { 47 | // logger.error("DESCoding.encode error in java.security.NoSuchAlgorithmException:" + e1); 48 | return null; 49 | } catch (javax.crypto.NoSuchPaddingException e2) { 50 | // logger.error("DESCoding.encode error in javax.crypto.NoSuchPaddingException:" + e2); 51 | return null; 52 | } catch (Exception e3) { 53 | // logger.error("DESCoding.encode error in Exception:" + e3); 54 | return null; 55 | } 56 | } 57 | 58 | /** 59 | * 解密 60 | * 61 | * @param src 用3DES加密后的字节数组 62 | * @return byte[] 解密后的字节数组 63 | */ 64 | public byte[] decode(byte[] src, byte[] keyBytes, String Algorithm) { 65 | try { 66 | // 生成密钥 67 | SecretKey deskey = new SecretKeySpec(keyBytes, trimAlgorithm(Algorithm)); 68 | 69 | // 解密 70 | Cipher c1 = Cipher.getInstance(Algorithm); 71 | c1.init(Cipher.DECRYPT_MODE, deskey); 72 | return c1.doFinal(src); 73 | } catch (java.security.NoSuchAlgorithmException e1) { 74 | // logger.error("DESCoding.decode error in java.security.NoSuchAlgorithmException:" + e1); 75 | return null; 76 | } catch (javax.crypto.NoSuchPaddingException e2) { 77 | // logger.error("DESCoding.decode error in javax.crypto.NoSuchPaddingException:" + e2); 78 | return null; 79 | } catch (Exception e3) { 80 | // logger.error("DESCoding.decode error in Exception:" + e3); 81 | return null; 82 | } 83 | } 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chengmengzhen/securitykeybroad/view/SercurityDialog.java: -------------------------------------------------------------------------------- 1 | package com.example.chengmengzhen.securitykeybroad.view; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.os.SystemClock; 7 | import android.util.DisplayMetrics; 8 | import android.view.Gravity; 9 | import android.view.View; 10 | import android.view.Window; 11 | import android.view.WindowManager; 12 | import android.widget.Button; 13 | import android.widget.ImageView; 14 | import android.widget.LinearLayout; 15 | import android.widget.TextView; 16 | 17 | import com.example.chengmengzhen.securitykeybroad.BaseApplication; 18 | import com.example.chengmengzhen.securitykeybroad.R; 19 | 20 | import java.util.ArrayList; 21 | 22 | /** 23 | * Created by chengmengzhen on 16/6/30. 24 | */ 25 | public class SercurityDialog extends Dialog implements View.OnClickListener { 26 | /** 27 | * 0-9,数字按钮 28 | */ 29 | private Button mNum1; 30 | private Button mNum2; 31 | private Button mNum3; 32 | private Button mNum4; 33 | private Button mNum5; 34 | private Button mNum6; 35 | private Button mNum7; 36 | private Button mNum8; 37 | private Button mNum9; 38 | private Button mNum0; 39 | private LinearLayout mDelPwd; 40 | 41 | private ArrayList mPwdImgs = new ArrayList(); 42 | private ImageView mPwdImg1; 43 | private ImageView mPwdImg2; 44 | private ImageView mPwdImg3; 45 | private ImageView mPwdImg4; 46 | private ImageView mPwdImg5; 47 | private ImageView mPwdImg6; 48 | 49 | private TextView mTv; 50 | 51 | private int mPwdCountNum; 52 | private InputCompleteListener mInputCompleteListener; 53 | 54 | public interface InputCompleteListener { 55 | public void inputComplete(String passWord); 56 | } 57 | 58 | public void setOnInputCompleteListener(InputCompleteListener inputCompleteListener) { 59 | this.mInputCompleteListener = inputCompleteListener; 60 | } 61 | 62 | public SercurityDialog(Context context) { 63 | super(context, R.style.SercurityDialogTheme); 64 | } 65 | 66 | @Override 67 | protected void onCreate(Bundle savedInstanceState) { 68 | super.onCreate(savedInstanceState); 69 | //给dialog设置布局 70 | setContentView(R.layout.ui_security_dialog); 71 | //通过window设置获取dialog参数 72 | Window window = getWindow(); 73 | WindowManager.LayoutParams params = window.getAttributes(); 74 | 75 | //获取屏幕的宽高 76 | WindowManager manager = (WindowManager) getContext() 77 | .getSystemService(Context.WINDOW_SERVICE); 78 | DisplayMetrics outMetrics = new DisplayMetrics(); 79 | manager.getDefaultDisplay().getMetrics(outMetrics); 80 | int width = outMetrics.widthPixels; 81 | int height = outMetrics.heightPixels; 82 | 83 | //设置dialog的宽 84 | params.width = width; 85 | //设置dialog在屏幕中的位置 86 | params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; 87 | //设置dialog属性 88 | window.setAttributes(params); 89 | 90 | initView(); 91 | initListener(); 92 | } 93 | 94 | private void initListener() { 95 | mNum0.setOnClickListener(this); 96 | mNum1.setOnClickListener(this); 97 | mNum2.setOnClickListener(this); 98 | mNum3.setOnClickListener(this); 99 | mNum4.setOnClickListener(this); 100 | mNum5.setOnClickListener(this); 101 | mNum6.setOnClickListener(this); 102 | mNum7.setOnClickListener(this); 103 | mNum8.setOnClickListener(this); 104 | mNum9.setOnClickListener(this); 105 | mDelPwd.setOnClickListener(this); 106 | } 107 | 108 | 109 | private void initView() { 110 | mNum0 = (Button) findViewById(R.id.button0); 111 | mNum1 = (Button) findViewById(R.id.button1); 112 | mNum2 = (Button) findViewById(R.id.button2); 113 | mNum3 = (Button) findViewById(R.id.button3); 114 | mNum4 = (Button) findViewById(R.id.button4); 115 | mNum5 = (Button) findViewById(R.id.button5); 116 | mNum6 = (Button) findViewById(R.id.button6); 117 | mNum7 = (Button) findViewById(R.id.button7); 118 | mNum8 = (Button) findViewById(R.id.button8); 119 | mNum9 = (Button) findViewById(R.id.button9); 120 | //洗牌 121 | int[] num = new int[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 122 | shuffleSort(num); 123 | mNum0.setText(String.valueOf(num[0])); 124 | mNum1.setText(String.valueOf(num[1])); 125 | mNum2.setText(String.valueOf(num[2])); 126 | mNum3.setText(String.valueOf(num[3])); 127 | mNum4.setText(String.valueOf(num[4])); 128 | mNum5.setText(String.valueOf(num[5])); 129 | mNum6.setText(String.valueOf(num[6])); 130 | mNum7.setText(String.valueOf(num[7])); 131 | mNum8.setText(String.valueOf(num[8])); 132 | mNum9.setText(String.valueOf(num[9])); 133 | 134 | mDelPwd = (LinearLayout) findViewById(R.id.button_del); 135 | 136 | mPwdImg1 = (ImageView) findViewById(R.id.pwd_1); 137 | mPwdImg2 = (ImageView) findViewById(R.id.pwd_2); 138 | mPwdImg3 = (ImageView) findViewById(R.id.pwd_3); 139 | mPwdImg4 = (ImageView) findViewById(R.id.pwd_4); 140 | mPwdImg5 = (ImageView) findViewById(R.id.pwd_5); 141 | mPwdImg6 = (ImageView) findViewById(R.id.pwd_6); 142 | mPwdImgs.add(mPwdImg1); 143 | mPwdImgs.add(mPwdImg2); 144 | mPwdImgs.add(mPwdImg3); 145 | mPwdImgs.add(mPwdImg4); 146 | mPwdImgs.add(mPwdImg5); 147 | mPwdImgs.add(mPwdImg6); 148 | 149 | } 150 | 151 | //洗牌算法 152 | private void shuffleSort(int[] data) { 153 | for (int i = 0; i < data.length - 1; i++) { 154 | int j = (int) (data.length * Math.random()); 155 | swap(data, i, j); 156 | } 157 | } 158 | 159 | private void swap(int[] data, int i, int j) { 160 | if (i == j) { 161 | return; 162 | } 163 | data[i] = data[i] + data[j]; 164 | data[j] = data[i] - data[j]; 165 | data[i] = data[i] - data[j]; 166 | } 167 | 168 | private String mPassWord = ""; 169 | 170 | @Override 171 | public void onClick(View view) { 172 | 173 | //删除 如果输入密码个数是0 return ,要不就mPwdCountNum 减1 174 | if (view.getId() == R.id.button_del) { 175 | if (mPwdCountNum == 0) { 176 | return; 177 | } else { 178 | mPwdCountNum = mPwdCountNum - 1; 179 | 180 | if (mPwdCountNum == 0){ 181 | mPassWord = mPassWord.substring(0,0); 182 | }else { 183 | // 这里-2的原因是因为数字之间有一个逗号,逗号+数字=2 184 | mPassWord = mPassWord.substring(0,mPassWord.length()-2); 185 | } 186 | 187 | showPwdImages(mPwdCountNum); 188 | } 189 | } 190 | // 191 | else { 192 | mPwdCountNum++; 193 | showPwdImages(mPwdCountNum); 194 | inputPwd(view); 195 | } 196 | 197 | /** 198 | * 当统计的当前输入的密码位数大于等于6,表示输入完成,数据处理在UI线程中处理 199 | */ 200 | if (mPwdCountNum >= 6) { 201 | /** 202 | * 开启一个线程,将密码数字传送给UI线程去加密 203 | */ 204 | new Thread() { 205 | @Override 206 | public void run() { 207 | SystemClock.sleep(100); 208 | dismiss(); // 关闭对话框 209 | 210 | // 让BaseApplication中的Handler来处理密码加密 211 | if (mInputCompleteListener != null) { 212 | BaseApplication.getHandler().post(new Runnable() { 213 | @Override 214 | public void run() { 215 | mInputCompleteListener.inputComplete(mPassWord); 216 | } 217 | }); 218 | } 219 | } 220 | }.start(); 221 | 222 | } 223 | } 224 | 225 | /** 226 | * 通过获取Button上的数字字符来合成字符串 227 | * 228 | * @param view 229 | */ 230 | private void inputPwd(View view) { 231 | if (mPwdCountNum > 1) { 232 | mPassWord = mPassWord + ","; 233 | } 234 | 235 | mPassWord += ((Button)view).getText(); 236 | } 237 | 238 | /** 239 | * 根据传入的参数来设置显示的密码的图片张数 240 | * 241 | * @param pwdCountNum 242 | */ 243 | private void showPwdImages(int pwdCountNum) { 244 | 245 | for(int i = 0; i < mPwdImgs.size(); i++) { 246 | if(i < pwdCountNum) { 247 | mPwdImgs.get(i).setVisibility(View.VISIBLE); 248 | } else { 249 | mPwdImgs.get(i).setVisibility(View.GONE); 250 | } 251 | } 252 | } 253 | 254 | } 255 | -------------------------------------------------------------------------------- /app/src/main/jni/JniEncode.c: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #define LOG_TAG "JNILOG" // 这个是自定义的LOG的标识 8 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__) 9 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__) 10 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__) 11 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__) 12 | #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG, __VA_ARGS__) 13 | //#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 14 | 15 | /* Header for class com_example_chengmengzhen_securitykeybroad_jninative_JniEncode */ 16 | 17 | #ifndef _Included_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode 18 | #define _Included_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | /* 23 | * Class: com_example_chengmengzhen_securitykeybroad_jninative_JniEncode 24 | * Method: encryption 25 | * Signature: (Ljava/lang/String;)Ljava/lang/String; 26 | */ 27 | JNIEXPORT jstring JNICALL Java_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode_encryption 28 | (JNIEnv *env, jobject obj, jbyteArray pwd) { 29 | 30 | //1 . 找到java代码的 class文件 31 | ///Users/chengmengzhen/AndroidStudioProjects/SecurityKeyBroad/app/src/main/java/.java 32 | jclass clazz = (*env)->FindClass(env, "com/example/chengmengzhen/securitykeybroad/utils/DESCoding"); 33 | if(clazz == NULL){ 34 | LOGE("find class error"); 35 | } 36 | jmethodID method4 = (*env)->GetStaticMethodID(env, clazz, "encode","([B)Ljava/lang/String;"); 37 | if(method4== NULL){ 38 | LOGE("find method error"); 39 | } 40 | 41 | return (jstring)(*env)->CallStaticObjectMethod(env, clazz, method4,pwd); 42 | } 43 | 44 | JNIEXPORT jstring JNICALL Java_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode_decryption 45 | (JNIEnv *env, jobject obj, jbyteArray pwd) { 46 | 47 | 48 | } 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | #endif 54 | -------------------------------------------------------------------------------- /app/src/main/jni/com_example_chengmengzhen_securitykeybroad_jninative_JniEncode.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | #include "cap_des2.h" 4 | /* Header for class com_example_chengmengzhen_securitykeybroad_jninative_JniEncode */ 5 | 6 | #ifndef _Included_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode 7 | #define _Included_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | /* 12 | * Class: com_example_chengmengzhen_securitykeybroad_jninative_JniEncode 13 | * Method: encryption 14 | * Signature: (Ljava/lang/String;)Ljava/lang/String; 15 | */ 16 | JNIEXPORT jstring JNICALL Java_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode_encryption 17 | (JNIEnv *, jobject, jbyteArray); 18 | 19 | JNIEXPORT jstring JNICALL Java_com_example_chengmengzhen_securitykeybroad_jninative_JniEncode_decryption 20 | (JNIEnv *, jobject, jbyteArray); 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | #endif 25 | -------------------------------------------------------------------------------- /app/src/main/res/anim/input_method_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 23 | 26 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/anim/input_method_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengcnaplex/SecurityKeyBroad/49d3217667635f6acc3366177049d8cdde47a0a8/app/src/main/res/drawable/back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 12 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengcnaplex/SecurityKeyBroad/49d3217667635f6acc3366177049d8cdde47a0a8/app/src/main/res/drawable/del.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengcnaplex/SecurityKeyBroad/49d3217667635f6acc3366177049d8cdde47a0a8/app/src/main/res/drawable/dot.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/keybroad_btn_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/keybroad_btn_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/keybroad_btn_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/accelerate_cubic.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/accelerate_quint.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/anticipate.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/decelerate_cubic.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/decelerate_quint.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 |