基于android的wifi签到签离App

  为了记录同学们的学习时长以及签到情况,学院说要我弄一个签到签离助手吧。首先想到的是GitHub,去上面搜寻了一番发现真正能直接拿来用的寥寥无几,可能是因为我比较菜鸡。然后打算自己写,花了两天时间写完前后端以及app,本文主要介绍一下开发原理。没有用到任何框架,都是简单代码。不擅长安卓,班门弄斧啦,仅供学习参考!

界面展示

使用思路

同学打开App就进入登录页面进行注册登录,一次登录后如果不退出下次就不需要再次登录,除非主动退出登录。学生注册信息学号作为登录账号,手机可用于找回密码等等。一切准备好了之后当学生点击登录时,如果没有连接指定wifi则提示“请连接指定wifi,签到失败!”,如果已经连接指定wifi则将签到按钮设置为不可点击状态,释放签离按钮为可点击状态,此时记录下当前时刻即为签到时刻,保存到本地手机存储中。当点击签离时同样进行指定wifi判断,如果正确则获取此刻的签离时间,立即计算出签到、签离的时间差即为本次签到的学习时长。然后再释放签到按钮为可点击状态,设置签离按钮为不可点击状态。

面临的问题

1、避免在后台运行activity进程被杀死。

扫描二维码关注公众号,回复: 13116245 查看本文章

       这里解决方法比较多,可以直接百度解决,但是有些手机还需要在省电管理里面加入白名单或者锁定后台。

2、android 9 以后的手机获取wifi信息需要各种授权,且授权方式发生了很大改变,只有授权开启定位信息才可能获取wifi MAC地址成功。

       我只能说网上那些解决“获取wifi信息失败”的博客都是渣渣(建议不看,解决不了问题的,可能是过时了),毫无营养的垃圾,浪费时间生命。这里给一句话如果获取不到wifi或者路由器的信息一定是没有权限,没有动态申请用户权限。参考郭霖的权限解决方案一定能够解决的。这才是正确的方法,按照官方的思路去做,不要投机取巧瞎扯。

3、android 绝对不能使用代码直接访问数据库,需要搭建后台,通过服务器回传进行数据修改。

      网上所有说“android访问mysql数据库”的博客都是垃圾文章,不要看,没有任何用处,如果你敢在android里面直接用sql语句,在企业三天之内必定滚蛋。谷歌强烈不建议这样子做,而且极其危险,相当于裸奔。最最最重要的是android7以上新版本不支持,而且报错不会直接说,让你怀疑人生为什么别人的博客是这样的可以,那是因为他们可能是低版本老版本android。

设计思路

1、获取wifi(路由器)的MAC地址确定唯一wifi,这里权限申请非常恶心,请参考郭霖大神的博客,不要参考那些垃圾博客,真的是浪费生命而且解决不了。android真的非常恶心,各种版本更新不兼容,还要适配各种机型,可能这就是开源的缺点吧。

2、数据库,我选择的是MySql数据库,当然可以选择SQLServer数据库等等。适合自己就好。

2、搭建后台,这里可以选择asp.net 或者 java 搭建。主要就是通过安卓发送http请求,然后返回请求结果,在服务器上处理请求。比如注册,将学生注册信息通过http请求传给服务器后台指定程序,后台指定程序进行处理——将学生注册数据插入到数据库中然后返回1(成功)或者0(失败)。所以我们的SQL语句实在服务器上运行的,不是在APP,APP把它理解为html,只是作为前端界面交互功能。当然不能完全等价于html。

反思总结

1、http传输信息非常不安全,不过考虑到我们的用途,安全性要求不高,没有谁这么无聊会去搞事情。如果在企业请用https协议。

2、可以改进为自动签离,无需点击。实现方法:使用android的server(服务)功能,使用线程不断检测wifi连接情况,如果断开wifi就立即签离。同样要保证服务不要被杀死。

3、还有其他问题后续再更新,希望大家有什么意见与建议多多提出!谢谢!

项目文件涉及到了太多学校私密信息,为了服务器安全性着想就不再给大家了。有什么困难可以解答哈!

难点参考

1、申请权限代码(不全,请参考郭霖的博客,不要照抄下面的没有用)

@Override
    public int getPermissionsRequestCode () {
        return 0;
    }

    @Override
    public String[] getPermissions () {
        return mPermissions;
    }

    @Override
    public void requestPermissionsSuccess () {
//        Toast.makeText(this, "成功授予权限!", Toast.LENGTH_SHORT).show();
        Log.d("555", "requestPermissionsSuccess: "+"成功授予权限!");
    }


    @Override
    public void requestPermissionsFail() {
        StringBuilder sb = new StringBuilder();
        mPermissions = PermissionUtil.getDeniedPermissions(this, mPermissions);
        for (String s : mPermissions) {
            if (s.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
                sb.append("定位权限(用于获取您的位置信息;\n");
            }
        }
        PermissionUtil.PermissionDialog(this, "程序运行需要如下权限:\n" + sb.toString() + "请在应用权限管理进行设置!");
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] mPermissions, int[] grantResults) {
        if (permissionHelper.requestPermissionsResult(requestCode, mPermissions, grantResults)) {
            //权限请求结果,并已经处理了该回调

            return;
        }
        super.onRequestPermissionsResult(requestCode, mPermissions, grantResults);
    }

2、实现签到的Http请求

 //签到功能
    public boolean sign(String st_id,String start) throws InterruptedException {
        is=false;
        final int[] flag = {1};  //线程同步问题,控制线程同步,必须执行了子线程才能返回is值
        new Thread(new Runnable() {
            @Override
            public void run() {

                String path="http://服务器地址:端口号/Base1/Sign?st_id="+st_id+"&start="+start;
                Log.d("qqqqqq", path);

                URL url = null; //新建url并实例化
                try {
                    url = new URL(path);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
                HttpURLConnection connection = null;
                try {
                    connection = (HttpURLConnection) url.openConnection();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    connection.setRequestMethod("GET");//获取服务器数据
                } catch (ProtocolException e) {
                    e.printStackTrace();
                }
                connection.setReadTimeout(8000);//设置读取超时的毫秒数
                connection.setConnectTimeout(8000);//设置连接超时的毫秒数
                InputStream in = null;
                try {
                    in = connection.getInputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String result = null;//读取服务器进行逻辑处理后页面显示的数据
                try {
                    result = reader.readLine();
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Log.d("qqqqqq","run: "+result+"");
                if (result.equals("1")){
                    is=true;
                }
//                flag[0] =0;
                connection.disconnect();
            }

        }).start();

//        while(flag[0]==1){
//            Log.d("isisisis", "isLogin: "+is);
//        }
        Thread.sleep(1000);
        return is;
    }

猜你喜欢

转载自blog.csdn.net/cj151525/article/details/106896869
今日推荐