開發(fā)初衷
很久之前做一鍵登錄校園網(wǎng)以失敗告終胎撤,最近看By_syk大神的文章By_syk簡書寫的一鍵登錄校園網(wǎng),很受鼓舞豪硅,于是自己動手實驗了一下哩照,By_syk的校園網(wǎng)系統(tǒng)和我們的是同一個系統(tǒng)(很神奇),我們學校的校園網(wǎng)也是按流量計費,所以每個人都會有一個帳號懒浮,然后連接校園網(wǎng)之后使用這個帳號登錄才能使用飘弧,由于每次都要登錄比較麻煩识藤,所以才會考慮寫簡單的小工具。
開發(fā)原型
做一個簡單的APP次伶,提供通知欄瓷片或者快捷方式登錄校園網(wǎng)痴昧,同時可以提供流量統(tǒng)計等功能(在下一版本考慮)
第一階段截圖
可以看到第三排第二個圖標就是我們的校園網(wǎng)登錄按鈕(這里由于我對Quick TIle不太熟悉,有一些小問題冠王,不影響使用)
這里寫圖片描述
下面是具體信息頁面赶撰,只上傳一個看看
**
一.分析登錄接口
**
首先我們進入我們的校園網(wǎng)登錄頁面
我使用Chrome的開發(fā)者工具來分析網(wǎng)站,發(fā)現(xiàn)有個Ipv6地址字段柱彻,是獲取本機的Ipv6地址上傳豪娜,于是訪問了一下手機登錄頁面,也就是59.67.0.245/a30.html(本地址只能在校內(nèi)訪問)哟楷,發(fā)現(xiàn)沒有該字段瘤载,所以打算使用這個頁面來抓包
訪問59.67.0.245/a30.html輸入賬號密碼,打開瀏覽器網(wǎng)站分析工具(快捷鍵F12)切換到開發(fā)者工具network選項卡進行抓包卖擅,記得要勾選 ?Preserve log 選項進行長連接記錄日志鸣奔。
當點擊校園網(wǎng)登錄按鈕的時候,所有的數(shù)據(jù)都被開發(fā)者工具記錄下來惩阶,我們選擇a30.html這個頁面進行分析挎狸,這個是post我們的賬號密碼數(shù)據(jù)的頁面,一般會列在第一位
在這個頁面header選項卡里我們可以看到
Request URL:http://59.67.0.245/a30.htm
這樣一行断楷,這也就是我們的數(shù)據(jù)將要post到的地方锨匆,那我們的數(shù)據(jù)在哪呢?對脐嫂,就是下面打馬賽克的那一塊统刮,F(xiàn)orm Data(表單數(shù)據(jù)),可以看到一共有8個數(shù)據(jù)账千,第一個DDDDD是學號(網(wǎng)站的開發(fā)者還真是隨便命名)侥蒙,第二個打馬賽克當然是密碼啦,另外R1匀奏,R2鞭衩,R6,R7娃善,para论衍,0MKKey初步判斷為定值
字段 | 值 |
---|---|
DDDDD | 15104413 |
upass | ××××××××××× |
R1 | 0 |
R2 | |
R6 | 1 |
R7 | 0 |
para | 00 |
0MKKey | 123456 |
那我下面列出了本次我們需要提交的值
字段 | 值 |
---|---|
DDDDD | 15104413 |
upass | ××××××××××× |
R1 | 0 |
R2 | |
R6 | 1 |
R7 | 0 |
para | 00 |
0MKKey | 123456 |
在這里我們的密碼并沒有通過任何方式加密,所以我也就不研究源碼了
直接使用postman(一款chrome插件)進行測試
打開postman聚磺,第一步選擇post方式坯台,第二步填入我們剛才所找到的請求url,然后就是填入表中所列的form瘫寝,點擊藍色send按鈕后蜒蕾,出現(xiàn)PC登錄成功頁面稠炬,說明已經(jīng)登錄成功,這也就意味著我們的測試成功了咪啡,我們可以準備開始寫代碼了首启。
**
二.準備 APP 藍圖
**
這里我們使用幕布(腦圖)分析一下,我們的APP分為3個頁面撤摸,狀態(tài)毅桃,賬號和充值(本篇文章只講狀態(tài)里的登錄部分)
一鍵登錄的按鈕是根據(jù)是否連接校園路由器決定的,但是在代碼中可能這部分不會判斷(也就是請求一下59.67.0.245這個頁面准夷,如果成功說明當前連接著校園網(wǎng)钥飞,否則連接的不是校園網(wǎng)),為了簡單起見冕象,我們選擇連接上wifi之后代承,就可以登錄,然后如果不通過就顯示登錄失敗渐扮。
下面準備開發(fā),這里我使用的開發(fā)環(huán)境是deepin15系統(tǒng)下的Android Studio2.3 掖棉。
配置依賴
//網(wǎng)絡請求
compile 'com.squareup.okhttp3:okhttp:3.8.1'
//Material Design引導頁面
compile 'agency.tango.android:material-intro-screen:0.0.5'
//Design庫
compile 'com.android.support:design:25.1.0'
配置權限
<!--網(wǎng)絡-->
<uses-permission android:name="android.permission.INTERNET" />
<!--網(wǎng)絡狀態(tài)讀取-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
有了這些我們就可以做登錄操作了(先實現(xiàn)核心功能)
三.核心代碼
1.第一步墓律,我們把要post的數(shù)據(jù)單獨寫一個文件
文件名:Data.java
public class Data {
//post地址
public static final String post_url = "http://59.67.0.245/a70.htm";
//固定參數(shù)
public static final String R1 = "0";
public static final String R2 = "";
public static final String R7 = "0";
public static final String para = "00";
public static final String MKKey = "123456";
public static final String R6 = "1";
}
2.第二步,新建類幔亥,里面包含兩個靜態(tài)方法耻讽,第一個是檢查網(wǎng)絡狀態(tài),第二個是登錄
獲取網(wǎng)絡狀態(tài)
//3種網(wǎng)絡狀態(tài)(wifi鏈接帕棉,gprs鏈接针肥,斷網(wǎng))
private static final int NETWORK_WIFI_CONNECTION = 1;
private static final int NETWORK_MOBILE_CONNECTION = 2;
private static final int NETWORK_DISCONNECTION = 0;
//獲取網(wǎng)絡狀態(tài)
public static int getNetWorkStatus(Context context) {
//連接管理器對象
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
//如果連接管理器不為null
if (connectivityManager != null) {
//通過連接管理器獲取網(wǎng)絡連接狀態(tài)
NetworkInfo networkInfo = connectivityManager
.getActiveNetworkInfo();
//如果網(wǎng)絡狀態(tài)不為null并且網(wǎng)絡已經(jīng)連接
if (networkInfo != null && networkInfo.isConnected()) {
//根據(jù)網(wǎng)絡信息狀態(tài)獲取連接種類
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
return NETWORK_WIFI_CONNECTION;
}
return NETWORK_MOBILE_CONNECTION;
}
}
//返回未連接
return NETWORK_DISCONNECTION;
}
登錄核心代碼
//返回給調(diào)用者登錄狀態(tài)
static int status = 0;
public static int LoginNetWork(final Context mContext) {
//這里是讀取文件中儲存的賬號密碼并解密的過程(使用base64加密)
SharedPreferences sharedPreferences = mContext.getSharedPreferences("data",MODE_PRIVATE);
String id = new String(Base64.
decode(sharedPreferences.getString("id","0"),Base64.DEFAULT));
String pwd = new String(Base64.
decode(sharedPreferences.getString("pwd","0"),Base64.DEFAULT));
//初始化okhttp的客戶端
OkHttpClient client = new OkHttpClient();
//填寫表單香伴,如果APP自己用慰枕,賬號密碼可以寫死,而不需要從保存的數(shù)值里讀取
FormBody formBody = new FormBody.Builder()
.add("DDDDD", id)
.add("R1", Data.R1)
.add("R2", Data.R2)
.add("R7", Data.R7)
.add("upass", pwd)
.add("para", Data.para)
.add("0MKKey", Data.MKKey)
.add("R6", Data.R6)
.build();
//將表單提交到url
Request request=new Request.Builder().url(Data.post_url).post(formBody).build();
client.newCall(request).enqueue(new Callback() {
//請求失敗回調(diào)
@Override
public void onFailure(Call call, IOException e) {
status = -1;
}
//請求成功回調(diào)
@Override
public void onResponse(Call call, Response response) throws IOException {
status = 1;
}
});
//將狀態(tài)返回給調(diào)用者
return status;
啊即纲,猝不及防就結束了具帮?
沒錯就是這樣,使用了Okhttp讓請求變得更簡單低斋,剩下的蜂厅,就是調(diào)用的過程咯
寫一個Activity,名字叫ShortActivity膊畴,并且配置他為啟動器掘猿,這樣我們就有了一個一鍵登錄的圖標,可以放在桌面上
<activity android:name=".ShortActivity"
android:label="快捷登錄"
android:theme="@style/myTransparent"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
3.最后一步吧唇跨,在shortActivity里調(diào)用登錄方法
//這是他的onCreate方法稠通,不需要界面衬衬,直接登錄,隨后自己finish掉自己
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在這里我沒有寫檢查網(wǎng)絡的代碼采记,當然也非常簡單佣耐,調(diào)用我們寫好的方法,根據(jù)返回值來判斷是不是需要開放登錄
//根據(jù)login方法的返回值確定是否登錄成功
if(CheckWiFiANDLogin.LoginNetWork(this)==1){
Toast.makeText(this,"登錄成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,"登錄失敗",Toast.LENGTH_SHORT).show();
}
finish();
}
現(xiàn)在可以運行試試了
此處沒有截圖……
連接校園網(wǎng)唧龄,點擊登錄的圖標就可以登錄
就這樣就結束了么兼砖?
應該沒毛病啊Android4.0 - Android 8.0都兼容了
老板讓你兼容到Android2.0!<裙住讽挟!
日你MMP的2.0
在Android日益發(fā)展更迭的版本中,有這么一個版本(7.0)丸冕,新增加了Quilk Setting TIle功能耽梅,這是個什么功能呢,就是在通知欄下拉的列表中胖烛,添加自定義的設置瓷片眼姐,達到快速設置的功能,所以叫快速設置瓷片
對佩番,就是這個樣子
我們來實現(xiàn)更高大上的操作方式吧
不過很遺憾众旗,大部分國產(chǎn)的Android Rom都被定制的不成樣子,根本就沒有這個功能趟畏,所以這個也只能在原生的系統(tǒng)上體驗了贡歧。
如果你想體驗的話,不妨試試刷機原生系統(tǒng)
寶寶這里是小米note 標準版 赋秀,系統(tǒng)是Lineage os Android7.1.2
實現(xiàn)QST首先要在清單文件中注冊服務
//配置一些必須的參數(shù)
<service
android:name=".Service.QSTileService"
android:icon="@drawable/ic_action_wifi2"
android:label="@string/app_name"
//必須 android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
//必須
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
下面實現(xiàn)這個服務
/**
* 快速設置系統(tǒng)磁塊
* Created by surine on 17-7-6.
*/
//Android7.0使用注解
@SuppressLint("NewApi")
public class QSTileService extends TileService {
int net_status = 0;
private static final String SERVICE_STATUS_FLAG = "serviceStatus";
private static final String PREFERENCES_KEY = "com.google.android_quick_settings";
/**
* 這個方法是打開通知欄的時候進行的處理
* 比如說我們這個情況就是打開通知欄判斷網(wǎng)絡有沒有連接
* 連接了就可用利朵,沒連接就不可用
*/
@Override
public void onStartListening() {
//如果網(wǎng)絡未連接或者gprs網(wǎng)絡,設置圖塊不可見
if (CheckWiFiANDLogin.getNetWorkStatus(this) == 0 || CheckWiFiANDLogin.getNetWorkStatus(this) == 2) {
//我們自定義一個更新磁塊方法
updateTile("校園網(wǎng)未連接", false);
} else {
updateTile("校園網(wǎng)已連接", true);
}
}
/**
* 當磁塊點擊了會發(fā)生什么情況
*/
@Override
public void onClick() {
Log.d("QS", "Tile tapped");
//開一個子線程來執(zhí)行要發(fā)生的邏輯
new Thread(new Runnable() {
@Override
public void run() {
//沒錯猎莲,就是登錄绍弟,并且返回登錄狀態(tài)
if(CheckWiFiANDLogin.LoginNetWork(QSTileService.this) == -1){
updateTile("登錄失敗",true);
}else{
updateTile("登錄成功",true);
}
}
}).start();
}
// 更新瓷片方法
private void updateTile(String title,boolean b) {
//獲取瓷片
Tile tile = this.getQsTile();
int newState;
// 改變瓷片活躍度
if (b){
newState = Tile.STATE_ACTIVE;
}else{
newState = Tile.STATE_UNAVAILABLE;
}
// 設置標簽,圖標益眉,活躍度等
tile.setLabel(title);
tile.setState(newState);
// 刷新
tile.updateTile();
}
}
本寶寶也是第一次接觸這個功能晌柬,所以不太會,根據(jù)Google Code Lab提供的方法簡單實現(xiàn)了一下郭脂,不過還有些ui上的小bug年碘,不影響使用
到這里我們的瓷片也已經(jīng)做好了,一個簡單的登錄校園網(wǎng)APP已經(jīng)做好了
以后終于不用使用瀏覽器登錄了展鸡。
四.寫在最后
本篇文章主要講解了分析抓包屿衅,測試抓包,利用抓包實現(xiàn)實用功能
在下一篇文章中莹弊,我們將利用抓包進行更多酷炫的操作
在這里很感謝By_syk大佬涤久,在酷安遇到他涡尘,很巧在簡書也遇到了他,他的文章給了我很大的幫助响迂。