详解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; } }

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

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

时间: 2024-11-14 11:59:28

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

详解Android的登录那点事_Android

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

详解Android中Handler的内部实现原理_Android

本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文<详解Android中Handler的使用方法>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功

详解Android中图片的三级缓存及实例

详解Android中图片的三级缓存及实例 为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响 特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知 所以提出三级缓存策略,通过网络.本地.内存三级缓存图片,来减少不必要的网络交互,避免浪费流量

基于 SurfaceView 详解 android 幸运大转盘,附带实例app

基于 SurfaceView 详解 android 幸运大转盘,附带实例app       首先说一下,幸运大转盘,以及SurfaceView是在看了也为大神的博客,才有了比较深刻的理解,当然这里附上这位大神的博客地址:博客地址,有兴趣的话你可以去看看,里面有很多的例子.至于我为什么要写这篇博客?,原因之一:加强自己的理解,原因之二:大神的博客就是大神的博客,跳转的太快,基础不好的,很难理解.还有就是一天在实验室太无聊了,没事写写东西.这里我再来更加基础的分析一下.写的不好,原谅.有什么写的不对

详解Android中Intent对象与Intent Filter过滤匹配过程_Android

如果对Intent不是特别了解,可以参见博文<详解Android中Intent的使用方法>,该文对本文要使用的action.category以及data都进行了详细介绍.如果想了解在开发中常见Intent的使用,可以参见<Android中Intent习惯用法>. 本文内容有点长,希望大家可以耐心读完. 本文在描述组件在manifest中注册的Intent Filter过滤器时,统一用intent-filter表示. 一.概述 我们知道,Intent是分两种的:显式Intent和隐式

详解Android主流框架不可或缺的基石

探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View

实例详解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更改APP语言模式的实现过程_Android

一.效果图 二.描述 更改Android项目中的语言,这个作用于只用于此APP,不会作用于整个系统 三.解决方案 (一)布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" a

实例详解Android文件存储数据方式_Android

总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.下面通过本文给大家介绍Android文件存储数据方式. 1.文件存储数据使用了Java中的IO操作来进行文件的保存和读取,只不过Android在Context类中封装好了输入流和输出流的获取方法. 创建的存储文件保存在/data/data/<package name>/files文件夹下. 2.操作. 保存文件内容:通过Context.openFileOutput获取输出流,参数分别为文件名和存储模式. 读取文件内容:通