你的位置:首页 > 操作系统

[操作系统]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 //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   ="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;      }}

  好了结束了,内容简单,大家自行了解吧。新手学习,高手交流。