詳解Android的登錄那點(diǎn)事
隨著互聯(lián)網(wǎng)的高速發(fā)展,一個(gè)應(yīng)用為了保護(hù)用戶的隱私,通常會(huì)通過設(shè)置用戶名+密碼的驗(yàn)證方式保證用戶隱私的相對(duì)安全,我知道一般網(wǎng)站的登錄驗(yàn)證,通常會(huì)設(shè)置一個(gè)二維碼,通過驗(yàn)證二維碼,防止惡意軟件通過機(jī)械程序,對(duì)用戶密碼進(jìn)行破解,那么Android設(shè)備如何實(shí)現(xiàn)這個(gè)功能呢?相信很多開發(fā)者對(duì)此不屑一顧,因?yàn)檫@樣增加了用戶使用的復(fù)雜性,很多軟件是不會(huì)這樣設(shè)計(jì)的,現(xiàn)在我們暫且不談它是不是有用,今天我們重點(diǎn)探討一下,如何在Android的設(shè)備上實(shí)現(xiàn)這個(gè)功能。本篇為大家介紹的內(nèi)容包括:1、用戶連續(xù)多次輸錯(cuò)密碼,增加驗(yàn)證碼驗(yàn)證;2、Android如何通過http請(qǐng)求達(dá)到與服務(wù)器之間的通訊。好了下面開始我們今天內(nèi)容的介紹,首先我們先一起來學(xué)習(xí)一下如何實(shí)現(xiàn)用戶連續(xù)多次輸錯(cuò)密碼,增加驗(yàn)證碼功能。
既然用的到二維碼,那么Android如何生成二維碼呢?為大家提供一個(gè)生成二維碼的類:
//生成二維碼的類 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類型參數(shù),負(fù)數(shù)表示右斜,整數(shù)左斜 // 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); } }
有了二維碼,下面我們開始設(shè)計(jì)我們的功能,這里先簡(jiǎn)單說一下,我們最終要實(shí)現(xiàn)的功能:1、用戶正常輸入用戶名+密碼登錄;2、當(dāng)用戶連續(xù)3次輸錯(cuò)密碼,要求用戶之后必須增加驗(yàn)證碼輸入驗(yàn)證。下面我們開始功能設(shè)計(jì)實(shí)現(xiàn),首先是我們的布局文件:
<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>
重點(diǎn)的內(nèi)容來了,我們主Activity代碼,大家先看一下吧:
public class MainActivity extends Activity { private TextView mytext = null; private EditText myname = null;//用戶名 private EditText mypass = null;//密碼 private EditText myrander = null;//驗(yàn)證碼 private Button mygetbutton = null;//Get方式發(fā)送Http請(qǐng)求 private Button mypostbutton = null;//Post方式發(fā)送Http請(qǐng)求 private LinearLayout myline = null;//控制二維碼的顯示 private static int n = 0;//用戶輸錯(cuò)密碼次數(shù)統(tǒng)計(jì) static String name = null;//用戶輸入的用戶名 static String password = null;//用戶輸入的密碼 private String edit;//用戶輸入用戶輸入的驗(yàn)證碼 private String code;//驗(yàn)證碼 @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){//連續(xù)三次輸錯(cuò)密碼 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, " 驗(yàn)證碼錯(cuò)誤", 0).show(); // imageview.setImageBitmap(bitmap); } return flag; } protected void onRestart() { super.onRestart(); n=0; } protected void onDestroy() { super.onDestroy(); n=0; } }
在這里簡(jiǎn)單介紹一下代碼,因?yàn)楸酒酉聛硪獮榇蠹曳窒黻P(guān)于Android發(fā)送GET、POST請(qǐng)求的知識(shí),這里我寫了兩個(gè)按鈕,一個(gè)用來通過使用GET方式驗(yàn)證,一個(gè)通過使用POST方式驗(yàn)證,功能上是一致的。最后請(qǐng)大家注意一下:紅色字體部分,紅色字體部分就是我們通過調(diào)用上部二維碼生成類,生成二維碼,然后展示在用戶界面。還有就是:onRestart、onDestroy都是Activity的生命周期函數(shù),這里將n歸零,方便我們的再次登錄體驗(yàn)。好了到這里我們的第一部分就完成了,下面我們開始進(jìn)入我們本篇的下半部分。
關(guān)于Android服務(wù)器請(qǐng)求,一般有兩種方式:GET、POST兩種方式,接下來我們就開始一起學(xué)習(xí)吧。
public class SendServer { //GET方式請(qǐng)求 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(); //關(guān)閉連接 } } return flag; } //POST請(qǐng)求 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請(qǐng)求參數(shù) String data = "name="+name+"&password="+password; OutputStream out = conn.getOutputStream(); out.write(data.getBytes()); out.flush(); out.close(); // conn.setRequestProperty("Content-Length", 500);// 內(nèi)容長(zhǎng)度設(shè)置為500;請(qǐng)求頭消息格式設(shè)置 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; } //解析服務(wù)返回的請(qǐng)求 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");//接收服務(wù)器端的數(shù)據(jù)時(shí),防止出現(xiàn)中文亂碼。 //String html = baos.toString(); baos.close(); return html; } }
好了結(jié)束了,內(nèi)容簡(jiǎn)單,大家自行了解吧。新手學(xué)習(xí),高手交流。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
- Android實(shí)現(xiàn)使用微信登錄第三方APP的方法
- Android端實(shí)現(xiàn)單點(diǎn)登錄的方法詳解
- Android 第三方登錄、分享(ShareSDK、友盟)
- Android集成微信登錄的步驟詳解
- Android QQ登錄界面繪制代碼
- Android開發(fā)實(shí)例之登錄界面的實(shí)現(xiàn)
- Android屬性動(dòng)畫實(shí)現(xiàn)炫酷的登錄界面
- Android調(diào)用第三方QQ登錄代碼分享
- Android設(shè)計(jì)登錄界面、找回密碼、注冊(cè)功能
- Android集成新浪微博第三方登錄的方法
- Android開發(fā)之登錄驗(yàn)證實(shí)例教程
相關(guān)文章
Android Studio 創(chuàng)建自定義控件的方法
這篇文章主要介紹了Android Studio 創(chuàng)建自定義控件的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Android編程實(shí)現(xiàn)自定義toast示例
這篇文章主要介紹了Android編程實(shí)現(xiàn)自定義toast,結(jié)合簡(jiǎn)單實(shí)例形式分析了自定義布局toast核心實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01Android中oncreate中獲得控件高度或?qū)挾鹊膶?shí)現(xiàn)方法
這篇文章主要介紹了Android中oncreate中獲得控件高度或?qū)挾鹊膶?shí)現(xiàn)方法的相關(guān)資料,希望通過本文大家能實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-09-09Android實(shí)現(xiàn)登錄注冊(cè)頁面(下)
這篇文章主要介紹了Android實(shí)現(xiàn)登錄注冊(cè)頁面的第二篇,實(shí)現(xiàn)驗(yàn)證登錄和記住密碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Android 圖片切換器(dp、sp、px) 的單位轉(zhuǎn)換器
這篇文章主要介紹了Android 圖片切換器(dp、sp、px) 的單位轉(zhuǎn)換器的相關(guān)資料,需要的朋友可以參考下2017-03-03Android布局之絕對(duì)布局AbsoluteLayout詳解
這篇文章主要為大家詳細(xì)介紹了Android布局之絕對(duì)布局AbsoluteLayout的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Android加載loading對(duì)話框的功能及實(shí)例代碼(不退出沉浸式效果)
這篇文章主要介紹了Android加載loading對(duì)話框的功能及實(shí)例代碼,不退出沉浸式效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12