• 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;
            
        }
    
    }

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

  • 相关阅读:
    400多个开源项目以及43个优秀的Swift开源项目-Swift编程语言资料大合集
    iOS开发-OC分支结构
    iOS开发-OC数据类型
    const volatile同时限定一个类型int a = 10
    详细解说Tomcat 设置虚拟路径的几种方法及为什么设置虚拟路径
    MySQL5.7数据库的基本操作命令
    CentOS7下搭建LAMP+FreeRadius+Daloradius Web管理
    Python安装第三方库的两种方式
    如何更换CentOS6的yum源
    CentOS6.5下搭建LAMP+FreeRadius+Daloradius Web管理和TP-LINK路由器、H3C交换机连接,实现,上网认证和记账功能
  • 原文地址:https://www.cnblogs.com/AndroidJotting/p/4944693.html
Copyright © 2020-2023  润新知