安卓实现扫码登录_安卓登录界面

安卓实现扫码登录_安卓登录界面首先不妨先看下Android:扫描二维码登陆原理:大概总结下这个过程就是:服务器生成全局唯一会话ID,并返回二维码、过期时间;用户扫描二维码,提交改会话ID,用户基本信息到服务器;PC端在过期时间内一直轮询,如果用户扫码,服务器记录状态,PC端跳转到已登录页面;那不妨按照这个思路来写一个简单的Demo。1.后台首先,我们需要搭建一个简易版的后台。在IDEA中创建SpringBoot项目,然后添加thymeleaf和session的依赖:<dependency> <

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

首先不妨先看下Android:扫描二维码登陆原理:
在这里插入图片描述
大概总结下这个过程就是:

  1. 服务器生成全局唯一会话ID,并返回二维码、过期时间;
  2. 用户扫描二维码,提交改会话ID,用户基本信息到服务器;
  3. PC端在过期时间内一直轮询,如果用户扫码,服务器记录状态,PC端跳转到已登录页面;

那不妨按照这个思路来写一个简单的Demo

1. 后台

首先,我们需要搭建一个简易版的后台。在IDEA中创建SpringBoot项目,然后添加thymeleaf和session的依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-core</artifactId>
</dependency>

Jetbrains全家桶1年46,售后保障稳定

然后,我们这里模拟Demo,不需要数据库,故而模拟系统中已注册用户,可以使用Set集合来存储。模拟记录系统登录用户来使用Map存储。然后将之封装到一个Bean对象中。同样二维码这里也直接使用一张静态二维码,内容为:

http://192.168.1.102:8080/scanlogin?uuid=Wxfsfdfskfj==
@Component
public class UserMap { 
   
    private static Map<String, User> loginmap = new HashMap<String, User>();
    private static Set<User> users = new HashSet<>();

项目结构如下:
在这里插入图片描述

添加对应的html页面,在loginpage.html中显示二维码,并进行轮询:

<body>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <center>
        <div>login page!</div>
        <img src="code.png" style="width=300px; height=300px;">
        <div style="color:red;" id="info"></div>
    </center>
    <script> var getting = { 
      url:'http://192.168.1.102:8080/checkscan', data:{ 
      "uuid": "Wxfsfdfskfj==" }, dataType:'text', success:function(res) { 
      if(JSON.parse(res)){ 
      $('#info').html("已授权"); setTimeout(function(){ 
      window.location.href = 'http://192.168.1.102:8080/home'; },1000); } else{ 
      $('#info').html("未授权"); } setTimeout(function(){ 
      $.ajax(getting); },1000); }, error:function(res){ 
      $('#info').html("请求发生了未知错误!"); } }; $.ajax(getting) </script>
</body>
</html>

然后就是Controller的Android端扫码后确认授权接口:

@GetMapping(value="/scanlogin")
@ResponseBody
// 手机端确定登录后调用该接口,将用户加入到登录Map
// http://localhost:8080/login?uuid=Wxfsfdfskfj==&userid=qwe&username=123
public String scanLogin(HttpSession session,
                           @RequestParam("uuid") String uuid,
                           @RequestParam("userid") String userid,
                           @RequestParam("username") String name){ 
   
    String UUID = "Wxfsfdfskfj==";
    User user = new User(name, userid);
    if(uuid.equals(UUID) && userService.checkUserInfo(user)){ 
   
        UserMap.loginUser(UUID, new User(name, userid));
        return "SUCCESS LOGIN!";
    }else { 
   
        return "ERROR UserInfo!";
    }
}

在请求主页home的时候,需要判断用户是否登录,即校验Session

@GetMapping(value="/home")
// 校验Session的主页
public String getHomePage(HttpSession session){ 
   
    String username = (String) session.getAttribute("name");
    if(username == null){ 
   
        return "redirect:/notlogin";
    }
    return "homepage";
}

前端ajax轮询接口:

@GetMapping(value="/checkscan")
@ResponseBody
// 需要前端轮询这个接口,判断是否确认登录
public boolean hasScan(HttpSession session,
                      @RequestParam("uuid") String uuid){ 
   
    User scanedUser = UserMap.getScanUserByUUID(uuid);
    if(scanedUser == null)
        return false;
    if(userService.hasUser(scanedUser.getUserID())){ 
   
        String username = (String) session.getAttribute("name");
        if(username == null){ 
   
            session.setAttribute("name", uuid);
        }
        return true;
    }
    return false;
}

2. Android端

首先添加两个依赖:

implementation 'cn.yipianfengye.android:zxing-library:2.2'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'

zxing是一个使用非常简单的扫码封装。项目地址:here

按照文档说明进行集成即可。页面非常简单,两个页面:
MainActivity中显示一个按钮,模拟扫码入口,调用后扫码后返回结果;
在这里插入图片描述

LoginActivity中进行提示用户确认授权,进行确认接口请求;
在这里插入图片描述
MainActivity中添加权限申请:

<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" />
// 请求读写权限
if (ContextCompat.checkSelfPermission(MainActivity.this,
        Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 
   
    //申请权限
    ActivityCompat.requestPermissions(MainActivity.this,
            new String[]{ 
   Manifest.permission.CAMERA}, 1);
}
if (ContextCompat.checkSelfPermission(MainActivity.this,
        Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) { 
   
    //申请权限
    ActivityCompat.requestPermissions(MainActivity.this,
            new String[]{ 
   Manifest.permission.INTERNET}, 1);
}

进行点击按钮的跳转

Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, 1);

复写onActivityResult方法(CaptureActivity中调用setResult,然后finish()):

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 
   
    //处理扫描结果(在界面上显示)
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 1){ 
   
        Toast.makeText(this, String.valueOf(null != data), Toast.LENGTH_LONG).show();
        if (null != data) { 
   
            Bundle bundle = data.getExtras();
            if (bundle == null) { 
   
                return;
            }
            if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) { 
   
                String result = bundle.getString(CodeUtils.RESULT_STRING);
                Intent intent = new Intent(MainActivity.this, LoginActivity.class);
                intent.putExtra("url", result);
                startActivity(intent);
            } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) { 
   
                Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
            }
        }
    }
}

在启动的LoginActivity中进行确认授权接口进行GET请求:

public void requestLogin() { 
   
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
            .url(url)
            .build();
    client.newCall(request).enqueue(new Callback() { 
   
        Message msg = new Message();
        @Override
        public void onFailure(Call call, IOException e) { 
   
            msg.obj="请求失败";
            handler.sendMessage(msg);
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException { 
   
            if (response.isSuccessful()) { 
   
                if (response.code() == 200) { 
   
                    String result = response.body().string();
                    if(result.equals("SUCCESS LOGIN!")){ 
   
                        msg.obj = "授权成功!";
                    }
                }
            }else{ 
   
                msg.obj = "出现了未知错误: " + response.code();
            }
            handler.sendMessage(msg);
        }
    });
}

3. 效果:

扫码前,我们直接home;扫码后Ajax处理直接跳转到主页home。
在这里插入图片描述

Demo地址

https://github.com/baiyazi/ScanQrCodeAndAutoLoginDemo

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234529.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 显卡机器linux 6卡挖矿,显卡挖矿是什么意思?购买显卡矿机应该注意什么?

    显卡机器linux 6卡挖矿,显卡挖矿是什么意思?购买显卡矿机应该注意什么?提到挖矿,很多人都比较感兴趣,众所周知,挖矿是除了直接交易数字货币之外,获取数字货币的唯一途径,而挖矿会根据不同的数字货币定义成不同的挖矿形式,比如说最近比较火的流动性挖矿,就是投资者抵押或锁定加密货币以换取报酬的做法,还有就是本文要说的显卡挖矿,下面小编就给大家通俗的讲解一下显卡挖矿是什么意思。显卡挖矿是什么意思?显卡挖矿其实就是用显卡去挖比特币,让显卡高负荷工作挖,淘汰了的就成了矿卡,矿卡一般…

    2022年6月10日
    45
  • c语言将时速转换成配速,配速和时速换算(配速时速换算)

    c语言将时速转换成配速,配速和时速换算(配速时速换算)时间除以路程,一般时间单位用分,路程单位用千米。比如20分钟跑了3千米,那配速就是20/3=6.66,也就是6分40秒每公里,一般说成640的配速。配速是针对长跑来说的,对短跑和中跑是不采用这个概念的。马拉松运动讲究匀速,在匀速的状态下才能更好地发挥自己的实力。很多跑步爱好者很注意控制速度。他们根.时速的意思是当时跑步的速度,配速是平均每公里耗时几分钟消耗是指跑步消耗的热量相当于每小时跑多少千…

    2022年6月28日
    171
  • mysql数据库优化大全

    mysql数据库优化大全

    2021年11月7日
    51
  • java销售管理系统_图书销售管理系统Java源代码

    java销售管理系统_图书销售管理系统Java源代码【实例简介】图书销售管理系统,内含源代码,项目需求分析,编写思路【实例截图】【核心代码】BookSaleManagementSystem└──BookSaleManagementSystem├──bin│├──com││└──pb││├──authority│││├──impl││││├──…

    2022年6月14日
    31
  • 什么是用户态和内核态的区别_内核态和用户态的概念

    什么是用户态和内核态的区别_内核态和用户态的概念什么是用户态和内核态从图上我们可以看出来通过系统调用将Linux整个体系分为用户态和内核态(或者说内核空间和用户空间)。那内核态到底是什么呢?其实从本质上说就是我们所说的内核,它是一种特殊的软件程序,特殊在哪儿呢?控制计算机的硬件资源,例如协调CPU资源,分配内存资源,并且提供稳定的环境供应用程序运行。用户态就是提供应用程序运行的空间,为了使应用程序访问到内核管理的资源例如CPU,内存,I/O。内核必须提供一组通用的访问接口,这些接口就叫系统调用。为什么要区分内核态和用户态往往我们的系统的资源是

    2025年12月5日
    5
  • 普通用户nginx安装步骤,并能够启动mongo的配置

    普通用户nginx安装步骤,并能够启动mongo的配置普通用户nginx安装步骤,并能够启动mongo的配置

    2022年4月24日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号