Android Http简单使用实现登录校园网App

Android Http简单使用实现登录校园网App

由于登录需要学校认证的WIFI比较繁琐,所以写了个小的App自己用,算是做笔记和试图养成一个写博客的习惯…

作为一个初学者,没有企业开发的经历,很多代码都是按照自己的思路来写,存在很多需要优化的方面,第二篇博客,经验不够,存在不足的地方,大神勿喷....

演示

演示

布局文件(没有自定义View,就是简单的登录界面,完全可以不看)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/main_back"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context="com.brioal.lzulogin.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginBottom="20dp"
            android:layout_weight="1"
            android:padding="20dp"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="match_parent"

            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/main_title"
            android:textColor="@color/colorWhite"
            android:textSize="30dp"
            android:typeface="serif" />

    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@color/colorWhite">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:background="@color/colorWhite"
            android:orientation="vertical">

            <LinearLayout

                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:orientation="horizontal">

                <android.support.design.widget.TextInputLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1">

                    <EditText
                        android:inputType="textAutoComplete"
                        android:id="@+id/main_et_name"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:hint="@string/username"
                        android:imeOptions="actionNext"
                        android:typeface="serif" />
                </android.support.design.widget.TextInputLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="10dp"
                    android:gravity="center"
                    android:text="@string/lzu_edu_cn"
                    android:textSize="20dp"
                    android:typeface="serif" />
            </LinearLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp">

                <EditText

                    android:imeOptions="actionDone"
                    android:id="@+id/main_et_password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/password"
                    android:inputType="textPassword"
                    android:typeface="serif" />
            </android.support.design.widget.TextInputLayout>

            <Button
                android:id="@+id/main_btn_save"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_margin="20dp"
                android:background="@drawable/btn_back"
                android:text="保存"
                android:textColor="@color/colorAccent"
                android:typeface="serif" />
        </LinearLayout>


    </RelativeLayout>


</LinearLayout>

实现原理

1.使用Http的Get请求,传入用户名和密码,获取返回的网页代码,通过代码内容来判断登录的结果
2.使用Receiver,监听WIFI连接状态的改变,当连接上一个可用的WIFI之后调用方法进行登录(因为学校大部分WIFI还是需要登陆的,所以没做过多的判断,对所有WIFI都进行登录操作);
3.获取网页的返回内容.判断登录的结果(看过返回网页的代码,没有其他判断语句,包含连接成功的网页就是登录成功,包含用户名或者密码的内容就是错误返回,所以偷懒直接判断网页源代码是否包含那几个字符串,具体情况需要具体分析)

部分用到的方法的解释

1.获取网页的返回内容 通过链接打开InputStream,读取数据返回字符串

应该都能看懂,就不做解释

public static String getHtml(InputStream inputStream, String encode) {
        InputStream is = inputStream;
        String code = encode;
        BufferedReader reader = null;
        StringBuffer sb = null;
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, encode));
            sb = new StringBuffer();
            String str = null;
            while ((str = reader.readLine()) != null) {
                if (str.isEmpty()) {

                } else {
                    sb.append(str);
                    sb.append("\n");
                }
            }
            reader.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

2.注册能监听WIFI状态的BroadcastReceiver  
使用静态注册方法,这样即使App不启动也能响应事件
我使用的是小米手机,安全中心内会默认禁止软件的自动启动和系统唤醒,需要关闭之后Receiver才会响应事件

Receiver继承BroadcastReceiver

public class LoginReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, Intent intent) {
     ...
    }

Manifes文件中对Receiver进行注册

 <receiver android:name=".receiver.LoginReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
                <action android:name="android.net.wifi.STATE_CHANGE" />
            </intent-filter>
        </receiver>

3.在onReceiver方法中对intent.getAction()进行判断

if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
            final Parcelable parcelableExtra = intent
                    .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            if (null != parcelableExtra) {
                NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
                NetworkInfo.State state = networkInfo.getState();
                boolean isConnected = state == NetworkInfo.State.CONNECTED;
                if (isConnected) {
                    Log.i(TAG, "onReceive: 连接上可用的WIFi");
                     // 开始登录

                } else {
                    Log.i(TAG, "onReceive: 未连接可用wifi");
                }
            }
        }

4.通过从FireDebug中获取到的点击登录按钮的响应连接和传入参数来进行登录操作 

String click_url = "..........";
String parma = "...........";
HttpURLConnection connection = null;
    URL url;
            try {
                    url = new URL(click_url);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    connection.setRequestMethod("GET");
                    connection.setUseCaches(false);
                    connection.getOutputStream().write(parma.getBytes());
                    connection.connect(); //????
                    int responseCode = connection.getResponseCode();
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                    //获取网页传回的数据
                        String s = getHtml(connection.getInputStream(), "GBK");
                        //此处测试的时候因为错误页面只返回几个字,所以格式于之前的登录成功的格式不同,改为UTF-8之后不会乱码
                        String errorMsg = new String(s.getBytes("GBK"), "UTF-8");
                        System.out.println("Html" + s);
                        if (s.contains("连接成功")) {
                            //使用Handler来更新界面handler.sendEmptyMessage(MainActivity.RESULT_SUCCESS);
                        } else if (errorMsg.contains("密码错误")) {
                            //密码错误
                            handler.sendEmptyMessage(MainActivity.RESULT_PASSWORD_ERROT);
                        } else if (errorMsg.contains("用户名错误")) {
                            handler.sendEmptyMessage(MainActivity.RESULT_NAME_ERROT);

                        }


                        connection.disconnect();
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (ProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

5.Handler接收消息显示通知或者更新布局
Activity前台的时候使用的是MainActiivty传入的Handler,负责更新登录按钮的显示文字
当Activity不在前台的时候,使用的是Receiver内的Handler,负责显示通知

Receiver内的Handler

    public Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == RESULT_SUCCESS) {
                showSuccess();
            } else if (msg.what == RESULT_NAME_ERROT) {
                showErron("用户名错误");
            } else if (msg.what == RESULT_PASSWORD_ERROT) {
                showErron("密码错误");
            }
        }
    };

显示登录成功的通知

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void showSuccess() {
        //获取NoticationManager对象
        manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        final Notification notify3 = new Notification.Builder(context)
                .setSmallIcon(R.mipmap.ic_launcher) // 设置图标
                .setTicker("登录成功") // 设置在通知栏上滚动的信息
                .setContentTitle("登陆成功") // 设置主标题
                .build();
        notify3.flags |= Notification.FLAG_AUTO_CANCEL; // 点击自动消失
        notify3.defaults |= Notification.DEFAULT_VIBRATE; //使用自动的振动模式
        manager.notify(NOTICATION_CANCLE_DELAY, notify3); // 显示通知
    }

显示错误的通知 (内容大同小异) ,不同的是设置了点击的时候启动MainActivity

 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void showErron(String msg) {
        manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        PendingIntent pendingIntent3 = PendingIntent.getActivity(context, 0,
                new Intent(context, MainActivity.class), 0);
        Notification notify3 = new Notification.Builder(context)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setTicker("登录失败")
                .setContentTitle("登陆失败")
                .setContentText(msg)
                .setContentIntent(pendingIntent3).build();
        notify3.flags |= Notification.FLAG_AUTO_CANCEL;
        manager.notify(NOTICATION_CANCLE_DELAY, notify3);
    }

至于MainActivity的代码都比较简单,因为宿舍要熄灯了,而且我感觉不会有多少人看吧,暂且不更新了,总结写的有点乱,等找个时候再重新整理一遍遇到的问题和解决思路.
源码已分享到Github
欢迎交流Android开发,大三狗一枚,联系方式:QQ:821329382

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值