详解Android的登录那点事_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;
 }
}

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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
登录
android事件机制详解、android service详解、android.mk详解、android布局详解、android adapter详解,以便于您获取更多的相关知识。

时间: 2024-10-09 03:56:28

详解Android的登录那点事_Android的相关文章

详解Android的登录那点事

随着互联网的高速发展,一个应用为了保护用户的隐私,通常会通过设置用户名+密码的验证方式保证用户隐私的相对安全,我知道一般网站的登录验证,通常会设置一个二维码,通过验证二维码,防止恶意软件通过机械程序,对用户密码进行破解,那么Android设备如何实现这个功能呢?相信很多开发者对此不屑一顾,因为这样增加了用户使用的复杂性,很多软件是不会这样设计的,现在我们暂且不谈它是不是有用,今天我们重点探讨一下,如何在Android的设备上实现这个功能.本篇为大家介绍的内容包括:1.用户连续多次输错密码,增加验

实例详解Android Selector和Shape的用法_Android

shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和selector在美化控件中的作用是至关重要的. 1:Selector drawable的item中可以有以下属性: android:drawable="@[package:]drawable/drawable_resource" android:state_pressed=["

详解android环境下的即时通讯_Android

首先了解一下即时通信的概念.通过消息通道 传输消息对象,一个账号发往另外一账号,只要账号在线,可以即时获取到消息,这就是最简单的即使通讯.消息通道可由TCP/IP UDP实现.通俗讲就是把一个人要发送给另外一个人的消息对象(文字,音视频,文件)通过消息通道(C/S实时通信)进行传输的服务.即时通讯应该包括四种形式,在线直传.在线代理.离线代理.离线扩展.在线直传指不经过服务器,直接实现点对点传输.在线代理指消息经过服务器,在服务器实现中转,最后到达目标账号.离线代理指消息经过服务器中转到达目标账

详解Android中Intent的使用方法_Android

一.Intent的用途 Intent主要有以下几种重要用途: 1. 启动Activity:可以将Intent对象传递给startActivity()方法或startActivityForResult()方法以启动一个Activity,该Intent对象包含了要启动的Activity的信息及其他必要的数据. 2. 启动Service:可以将Intent对象传递给startService()方法或bindService()方法以启动一个Service,该Intent对象包含了要启动的Service的

详解Android中IntentService的使用方法_Android

为什么我们需要IntentService ? Android中的IntentService是继承自Service类的,在我们讨论IntentService之前,我们先想一下Service的特点: Service的回调方法(onCreate.onStartCommand.onBind.onDestroy)都是运行在主线程中的.当我们通过startService启动Service之后,我们就需要在Service的onStartCommand方法中写代码完成工作,但是onStartCommand是运行

详解Android中Handler的使用方法_Android

在Android开发中,我们经常会遇到这样一种情况:在UI界面上进行某项操作后要执行一段很耗时的代码,比如我们在界面上点击了一个"下载"按钮,那么我们需要执行网络请求,这是一个耗时操作,因为不知道什么时候才能完成.为了保证不影响UI线程,所以我们会创建一个新的线程去执行我们的耗时的代码.当我们的耗时操作完成时,我们需要更新UI界面以告知用户操作完成了.所以我们可能会写出如下的代码: package ispring.com.testhandler; import android.app.

详解Android中Notification的使用方法_Android

      在消息通知的时候,我们经常用到两个控件Notification和Toast.特别是重要的和需要长时间显示的信息,用Notification最合适不过了.他可以在顶部显示一个图标以标示有了新的通知,当我们拉下通知栏的时候,可以看到详细的通知内容.       最典型的应用就是未看短信和未接来电的显示,还有QQ微信,我们一看就知道有一个未接来电或者未看短信,收到QQ离线信息.同样,我们也可以自定义一个Notification来定义我们自己的程序想要传达的信息. Notification我

详解android使用SAX解析XML文件_Android

解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析. DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了. 优点:整个文档读入内存,方便操作:支持修改.删除和重现排列等多种功能. 缺点:将整个文档读入内存中,保留了过多的不需要的节点,浪费内存和空间. 使用场合:一旦读入文档,还需要多次对文档进行操作,并且在硬件资源充足的情况下(内存,CPU). 为了解决DOM解析存在的问题,就出现了SAX解析.其特点为: 优点:不

详解Android中解析XML的方法_Android

XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能.今天就由我向大家介绍一下在Android平台下几种常见的XML解析和创建的方法. 在Android中,常见的XML解析器分别为SAX解析器.DOM解析器和PULL解析器,下面,我将一一向大家详细介绍. SAX解析器: SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的.当事