Android之登录那点事
随着互联网的高速发展,一个应用为了保护用户的隐私,通常会通过设置用户名+密码的验证方式保证用户隐私的相对安全,我知道一般网站的登录验证,通常会设置一个二维码,通过验证二维码,防止恶意软件通过机械程序,对用户密码进行破解,那么Android设备如何实现这个功能呢?相信很多开发者对此不屑一顾,因为这样增加了用户使用的复杂性,很多软件是不会这样设计的,现在我们暂且不谈它是不是有用,今天我们重点探讨一下,如何在Android的设备上实现这个功能。本篇为大家介绍的内容包括:1、用户连续多次输错密码,增加验证码验证;2、Android如何通过http请求达到与服务器之间的通讯。好了下面开始我们今天内容的介绍,首先我们先一起来学习一下如何实现用户连续多次输错密码,增加验证码功能。
既然用的到二维码,那么Android如何生成二维码呢?为大家提供一个生成二维码的类:
//生成二维码的类
public class BPUtil { /**
* 用于生成二维码的字符
*/
private static final char[] CHARS = {
'', '', '', '', '', '', '', '', '', '',
'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 = ;
private static final int DEFAULT_FONT_SIZE = ;
private static final int DEFAULT_LINE_NUMBER = ;
private static final int BASE_PADDING_LEFT = , RANGE_PADDING_LEFT = , BASE_PADDING_TOP = , RANGE_PADDING_TOP = ;
private static final int DEFAULT_WIDTH = , DEFAULT_HEIGHT = ; //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 = ; 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 = ; i < code.length(); i++) {
randomTextStyle(paint);
randomPadding();
c.drawText(code.charAt(i) + "", padding_left, padding_top, paint);
} for (int i = ; 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 = ; 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();
paint.setColor(color);
canvas.drawLine(startX, startY, stopX, stopY, paint);
} private int randomColor() {
return randomColor();
} private int randomColor(int rate) {
int red = random.nextInt() / rate;
int green = random.nextInt() / rate;
int blue = random.nextInt() / 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() / ;
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项目中都需要用户登录.注册.这样的话在开发中做好保护用户密码的工作就显得尤为重要.这里我把自己的密码保护方法记录下来. 这是我建了一个保存密码的文件,以便于检查自己保存密码或者上 ...
- Android实现登录
登录界面布局文件 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android ...
- Android SharedPreferences登录记住密码
SharedPreferences是Android中存储简单数据的一个工具类.可以想象它是一个小小的Cookie,它通过用键值对的方式把简单 数据类型(boolean.int.float.long和S ...
- Android微信登录、分享、支付
转载需要著名出处: http://blog.csdn.net/lowprofile_coding/article/details/78004224 之前写过微信登录分享支付第一版: http://bl ...
- Androidの共享登录之方案研究
由于最近公司提到了一个需求是,一个应用登录成功了,另一个自动登录. 绞尽脑汁想了好几天,看起来很容易但是想深点就漏洞百出,有的时候代码都写完了测试都成功了突然发现给一个假设就完全失效. 先前几个同事之 ...
- egret打包android + android微信登录--小结
公司用egret做了款游戏,需要打android包,做安卓端的微信登录,于是乎开始了第一安卓上的打包,正的是一脸懵 首先遇到的问题有如下: 1. egret打安卓包时经常运行不起来, 主要是gradl ...
- Android实现登录小demo
安卓,在小编实习之前的那段岁月里面,小编都没有玩儿过,如果说玩儿过,那就是安卓手机了,咳咳,敲登录的时候有种特别久违的熟悉,这种熟悉的感觉就和当时敲机房收费系统一样,那叫一个艰难啊,不过小编相信,在小 ...
- Android 实现登录界面和功能实例
近期一个android小程序须要登录功能,我简单实现了一下.如今记录下来也当做个笔记,同一时候也希望能够相互学习.所以,假设我的代码有问题,还各位请提出来.多谢了! 以下.就简述一下此实例的主要内容: ...
- 记写 android 微信登录的demo历程
前言 首先看一条链接: https://github.com/Tencent/WeDemo 腾讯给了一个wedemo,微信第三方登录的例子.里面是php和ios,ios是object写的,php还是原 ...
随机推荐
- 德国W家HIPP 奶粉有货播报:2014.6.25 HIPP 1+ 4盒装有货啦!
德国W家HIPP 奶粉有货播报:2014.6.25 HIPP 1+ 4盒装有货啦!
- QGis、Qt对话框上的OK、Open、Cancel、Help等英文翻译
成功编译qgis,启动程序发现对话框上的OK.Open.Cancel.Help等依然是英文字段,然后查找源码看这些字段是否都添加到了语言翻译包中: 最后发现这些按钮都是qt的QTGui4库中的QDia ...
- web常见错误提示总结
在写web程序的时候,经常会出现一些网页错误的数字提示,如果能够明白这些提示的含义,那对于调试程序是有极大帮助的.网上有很多这方面的总结,但为了适应自己的阅读习惯,以及日后的查找方便,就做了一些修改并 ...
- sublime_text_2 ubuntu下无法输入中文 解决方法
参考资料:http://my.oschina.net/wugaoxing/blog/121281 环境配置:ubuntu 14.10 1.保存下述代码为 sublime_imfix.c 文件 /* s ...
- 响应式web网站设计制作方法
在研究响应式的时候,记录了一些感想,分享出来,抛砖引玉,希望可以和大家一起讨论.总结下来,响应式比之前想象的要复杂得多.1. ie9以下(不包括ie9)采用ie条件注释,为ie8以及一下单独开一个样式 ...
- 使用iframe的优缺点,为什么少用iframe以及iframe和frame的区别。
注:HTML5不再支持使用frame,iframe只有src 属性一.使用iframe的优缺点优点:1.程序调入静态页面比较方便;2.页面和程序分离;缺点:1.iframe有不好之处:样式/脚本需要额 ...
- MySQL Can't connect to MySQL server on 'localhost' (10061)
run > services.msc > rightclick MySQL > properties >start 搞定
- min.js反压缩
给个网址自己体会.. http://jsbeautifier.org/ 当需要修改min.js中的代码时,把min.js文件ctrl+c ctrl+v扔到上面的网页里,点击beautify 即可
- 前端神器avalonJS入门(三)
本章将介绍如何使用avalon来实现前端路由功能. 我们需要用到两个avalon路由配套模块—— mmHistory.js 和 mmRouter.js .其中mmHistory是用于历史管理,它会劫持 ...
- SQLite3
记录一个基础的IOS下SQLite的例子: @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSAr ...