編輯:關於android開發
隨著互聯網的高速發展,一個應用為了保護用戶的隱私,通常會通過設置用戶名+密碼的驗證方式保證用戶隱私的相對安全,我知道一般網站的登錄驗證,通常會設置一個二維碼,通過驗證二維碼,防止惡意軟件通過機械程序,對用戶密碼進行破解,那麼Android設備如何實現這個功能呢?相信很多開發者對此不屑一顧,因為這樣增加了用戶使用的復雜性,很多軟件是不會這樣設計的,現在我們暫且不談它是不是有用,今天我們重點探討一下,如何在Android的設備上實現這個功能。本篇為大家介紹的內容包括:1、用戶連續多次輸錯密碼,增加驗證碼驗證;2、Android如何通過http請求達到與服務器之間的通訊。好了下面開始我們今天內容的介紹,首先我們先一起來學習一下如何實現用戶連續多次輸錯密碼,增加驗證碼功能。
既然用的到二維碼,那麼Android如何生成二維碼呢?為大家提供一個生成二維碼的類:
//生成二維碼的類 public class BPUtil { /** * 用於生成二維碼的字符 */ private static final char[] CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a','b','c','d','e','f','g','h','i','j','k','m','l','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J','K','M','L','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' }; private static BPUtil bpUtil; public static BPUtil getInstance() { if(bpUtil == null) bpUtil = new BPUtil(); return bpUtil; } // width="60" height="30" // base_padding_left="5" // range_padding_left="10" // base_padding_top="15" // range_padding_top="10" // codeLength="4" // line_number="3" // font_size="20" //default settings private static final int DEFAULT_CODE_LENGTH = 4; private static final int DEFAULT_FONT_SIZE = 20; private static final int DEFAULT_LINE_NUMBER = 3; private static final int BASE_PADDING_LEFT = 5, RANGE_PADDING_LEFT = 10, BASE_PADDING_TOP = 15, RANGE_PADDING_TOP = 10; private static final int DEFAULT_WIDTH = 60, DEFAULT_HEIGHT = 30; //settings decided by the layout xml //canvas width and height private int width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT; //random word space and pading_top private int base_padding_left = BASE_PADDING_LEFT, range_padding_left = RANGE_PADDING_LEFT, base_padding_top = BASE_PADDING_TOP, range_padding_top = RANGE_PADDING_TOP; //number of chars, lines; font size private int codeLength = DEFAULT_CODE_LENGTH, line_number = DEFAULT_LINE_NUMBER, font_size = DEFAULT_FONT_SIZE; //variables private String code; private int padding_left, padding_top; private Random random = new Random(); public Bitmap createBitmap() { padding_left = 0; Bitmap bp = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas c = new Canvas(bp); code = createCode(); c.drawColor(Color.WHITE); Paint paint = new Paint(); paint.setTextSize(font_size); for (int i = 0; i < code.length(); i++) { randomTextStyle(paint); randomPadding(); c.drawText(code.charAt(i) + "", padding_left, padding_top, paint); } for (int i = 0; i < line_number; i++) { drawLine(c, paint); } c.save( Canvas.ALL_SAVE_FLAG );//保存 c.restore();// return bp; } public String getCode() { return bpUtil.createCode(); } private String createCode() { StringBuilder buffer = new StringBuilder(); for (int i = 0; i < codeLength; i++) { buffer.append(CHARS[random.nextInt(CHARS.length)]); } return buffer.toString(); } private void drawLine(Canvas canvas, Paint paint) { int color = randomColor(); int startX = random.nextInt(width); int startY = random.nextInt(height); int stopX = random.nextInt(width); int stopY = random.nextInt(height); paint.setStrokeWidth(1); paint.setColor(color); canvas.drawLine(startX, startY, stopX, stopY, paint); } private int randomColor() { return randomColor(1); } private int randomColor(int rate) { int red = random.nextInt(256) / rate; int green = random.nextInt(256) / rate; int blue = random.nextInt(256) / rate; return Color.rgb(red, green, blue); } private void randomTextStyle(Paint paint) { int color = randomColor(); paint.setColor(color); paint.setFakeBoldText(random.nextBoolean()); //true為粗體,false為非粗體 float skewX = random.nextInt(11) / 10; skewX = random.nextBoolean() ? skewX : -skewX; paint.setTextSkewX(skewX); //float類型參數,負數表示右斜,整數左斜 // paint.setUnderlineText(true); //true為下劃線,false為非下劃 // paint.setStrikeThruText(true); //true為刪除線,false為非刪除 } private void randomPadding() { padding_left += base_padding_left + random.nextInt(range_padding_left); padding_top = base_padding_top + random.nextInt(range_padding_top); } }
有了二維碼,下面我們開始設計我們的功能,這裡先簡單說一下,我們最終要實現的功能:1、用戶正常輸入用戶名+密碼登錄;2、當用戶連續3次輸錯密碼,要求用戶之後必須增加驗證碼輸入驗證。下面我們開始功能設計實現,首先是我們的布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${relativePackage}.${activityClass}" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="@string/yanzheng" /> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/name" /> <EditText android:id="@+id/name" android:layout_width="wrap_content" android:layout_weight="6" android:layout_height="wrap_content" android:hint="@string/name_new" android:singleLine="true" /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/password" /> <EditText android:id="@+id/pass" android:layout_weight="6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/pass_new" android:singleLine="true" /> </LinearLayout> <LinearLayout android:id="@+id/layout_yanzhengma" android:visibility="gone" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/yanzhengma" /> <TextView android:id="@+id/rander" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <EditText android:id="@+id/rander_input" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:id="@+id/get" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/get" /> <Button android:id="@+id/post" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/post" /> </LinearLayout> </LinearLayout> </RelativeLayout>
重點的內容來了,我們主Activity代碼,大家先看一下吧:
public class MainActivity extends Activity { private TextView mytext = null; private EditText myname = null;//用戶名 private EditText mypass = null;//密碼 private EditText myrander = null;//驗證碼 private Button mygetbutton = null;//Get方式發送Http請求 private Button mypostbutton = null;//Post方式發送Http請求 private LinearLayout myline = null;//控制二維碼的顯示 private static int n = 0;//用戶輸錯密碼次數統計 static String name = null;//用戶輸入的用戶名 static String password = null;//用戶輸入的密碼 private String edit;//用戶輸入用戶輸入的驗證碼 private String code;//驗證碼 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mytext = (TextView)findViewById(R.id.rander); myname = (EditText)findViewById(R.id.name); mypass = (EditText)findViewById(R.id.pass); myrander = (EditText)findViewById(R.id.rander_input); mygetbutton = (Button)findViewById(R.id.get); mypostbutton = (Button)findViewById(R.id.post); myline = (LinearLayout)findViewById(R.id.layout_yanzhengma); mygetbutton.setOnClickListener(new mygetbutton()); mypostbutton.setOnClickListener(new mypostbutton()); } class mygetbutton implements OnClickListener{ public void onClick(View v) { name = myname.getText().toString(); password = mypass.getText().toString(); if(n>=3){//連續三次輸錯密碼 edit = myrander.getText().toString(); boolean boo = captcha (code , edit); if(boo){ new Thread(new Runnable() { public void run() { final boolean flag = SendServer.getsave(name, password); runOnUiThread(new Runnable() { public void run() { if(flag){ Toast.makeText(MainActivity.this, "登錄成功", Toast.LENGTH_SHORT).show(); n=0; }else{ Toast.makeText(MainActivity.this, "登錄失敗", Toast.LENGTH_SHORT).show(); n++; if(n>=3){ myline.setVisibility(View.VISIBLE); } } } }); } }).start(); }else{ code = BPUtil.getInstance().getCode().toLowerCase();//生成新的二維碼 mytext.setText(code);//展示在用戶面前 } }else{ new Thread(new Runnable() { public void run() { final boolean flag = SendServer.getsave(name, password); runOnUiThread(new Runnable() { public void run() { if(flag){ Toast.makeText(MainActivity.this, "登錄成功", Toast.LENGTH_SHORT).show(); n=0; }else{ Toast.makeText(MainActivity.this, "登錄失敗", Toast.LENGTH_SHORT).show(); n++; if(n>=3){ myline.setVisibility(1); code = BPUtil.getInstance().getCode().toLowerCase(); mytext.setText(code); } } } }); } }).start(); } } } class mypostbutton implements OnClickListener{ public void onClick(View v) { name = myname.getText().toString(); password = mypass.getText().toString(); new Thread(new Runnable() { public void run() { final boolean flag = SendServer.postsave(name, password); runOnUiThread(new Runnable() { @Override public void run() { if(flag){ Toast.makeText(MainActivity.this, "登錄成功", Toast.LENGTH_SHORT).show(); n=0; }else{ Toast.makeText(MainActivity.this, "登錄失敗", Toast.LENGTH_SHORT).show(); n++; if(n>=3){ myline.setVisibility(1); } } } }); } }).start(); } } @SuppressLint("ShowToast") private boolean captcha (String code , String edit) { boolean flag = false; if (code.equals(edit)) { flag = true; }else { flag = false; Toast.makeText(MainActivity.this, " 驗證碼錯誤", 0).show(); // imageview.setImageBitmap(bitmap); } return flag; } protected void onRestart() { super.onRestart(); n=0; } protected void onDestroy() { super.onDestroy(); n=0; } }
在這裡簡單介紹一下代碼,因為本篇接下來要為大家分享關於Android發送GET、POST請求的知識,這裡我寫了兩個按鈕,一個用來通過使用GET方式驗證,一個通過使用POST方式驗證,功能上是一致的。最後請大家注意一下:紅色字體部分,紅色字體部分就是我們通過調用上部二維碼生成類,生成二維碼,然後展示在用戶界面。還有就是:onRestart、onDestroy都是Activity的生命周期函數,這裡將n歸零,方便我們的再次登錄體驗。好了到這裡我們的第一部分就完成了,下面我們開始進入我們本篇的下半部分。
關於Android服務器請求,一般有兩種方式:GET、POST兩種方式,接下來我們就開始一起學習吧。
public class SendServer { //GET方式請求 public static boolean getsave(String name, String password) { boolean flag = false; HttpURLConnection conn = null; try { //防止中文亂碼 String username = URLEncoder.encode(name, "UTF-8"); String userpassword = URLEncoder.encode(password, "UTF-8"); URL url = new URL("http://10.20.90.3:8080/Register/ManageServlet?"+"name="+username+"&password="+userpassword); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); int responseCode = conn.getResponseCode(); if(responseCode == 200){ InputStream is = conn.getInputStream(); String stu = getStringFromInputStream(is); if(stu.equals("登錄成功")){ flag = true; } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally{ if(conn != null){ conn.disconnect(); //關閉連接 } } return flag; } //POST請求 public static boolean postsave(String name, String password) { boolean flag = false; HttpURLConnection conn = null; try { URL url = new URL("http://10.20.90.3:8080/Register/ManageServlet?"); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); //post請求參數 String data = "name="+name+"&password="+password; OutputStream out = conn.getOutputStream(); out.write(data.getBytes()); out.flush(); out.close(); // conn.setRequestProperty("Content-Length", 500);// 內容長度設置為500;請求頭消息格式設置 int respon = conn.getResponseCode(); if(respon == 200){ InputStream is = conn.getInputStream(); String stu = getStringFromInputStream(is); if(stu.equals("登錄成功")){ flag = true; } } } catch (Exception e) { e.printStackTrace(); }finally{ if(conn != null){ conn.disconnect(); } } return flag; } //解析服務返回的請求 private static String getStringFromInputStream(InputStream is) throws Exception{ ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024*8]; int len = -1; while((len = is.read(buffer)) != -1){ baos.write(buffer, 0, len); } is.close(); String html = new String(baos.toByteArray(), "GBK");//接收服務器端的數據時,防止出現中文亂碼。 //String html = baos.toString(); baos.close(); return html; } }
好了結束了,內容簡單,大家自行了解吧。新手學習,高手交流。
使用Vitamio打造自己的Android萬能播放器—— 手勢控制亮度、音量、縮放 使用Vitamio打造自己的Android萬能播放器(1)——
Anroid之意圖的使用,Anroid之意圖使用inten常見動作:MAIN_ACTION(主視圖)、 VIEW_ACTION(查看)、 EDIT_ACTION(修改)、
上次介紹了如何使用JAVA的反射機制來調用藍牙的隱藏API,這次繼續練習JAVA的反射機制,探秘T
android加固—2.加固前先要學會破解,調試內存值修改程序走向,【版權所有,轉載請注明出處。】 因公司項目需要對app加固,經過本人數月的研究,實現了一套完整的仿第三