編輯:關於Android編程
我們現在APP是斷然很難離開網絡存活下去,會有很多很頻繁的網絡操作,請求數據,傳遞數據等等,所以,我們需要對網絡狀態有多一點的了解。
首先,假如我們的APP在運行的時候,假如這時候用戶掉線了,沒有網絡了,我們就應該給用戶提示,然後用戶連上網絡了,我們這時候應該也給用戶提示,這樣他就可以繼續玩我們的APP,我們應該怎麼做了,沒錯,就是通過Receiver來實現,因為斷網和聯網系統都會發送廣播,然後,我們可以收到,通過廣播去判斷當前的網絡是否可用,具體代碼如下:其中,接受廣播需要的action是android.net.conn.CONNECTIVITY_CHANGE和ta.android.net.conn.CONNECTIVITY_CHANGE,我們需要注冊該廣播接受者的時候添加過濾器,這樣他就可以收到了。
import com.iyueju.guanggong.util.NetWorkUtil;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
/**
* 用於接受網絡狀態的變化的receiver
*
* @author Administrator
*
*/
public class NetWorkReceiver extends BroadcastReceiver
{
private static Boolean networkAvailable = false;// 默認網絡狀態
private static com.iyueju.guanggong.util.NetWorkUtil.netType type;
private final static String ANDROID_NET_CHANGE_ACTION = android.net.conn.CONNECTIVITY_CHANGE;
public final static String TA_ANDROID_NET_CHANGE_ACTION = ta.android.net.conn.CONNECTIVITY_CHANGE;
private static NetWorkReceiver receiver;
private NetWorkReceiver()
{
super();
}
public static NetWorkReceiver getNetWorkReceiver()
{
// TODO Auto-generated constructor stub
if (receiver == null)
{
synchronized (NetWorkReceiver.class)
{
if (receiver == null)
{
receiver = new NetWorkReceiver();
}
}
}
return receiver;
}
@Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stu
receiver = NetWorkReceiver.this;
if (intent.getAction().equalsIgnoreCase(ANDROID_NET_CHANGE_ACTION)
|| intent.getAction().equalsIgnoreCase(TA_ANDROID_NET_CHANGE_ACTION))
{
Log.i(Main, 有收到網絡連接的相關訊息);
if (!NetWorkUtil.isNetworkAvailable(context) && networkAvailable == true)
{
Log.i(Main, 斷開了網絡);
networkAvailable = false;
Toast.makeText(context, 網絡不可用, 1).show();
} else if (NetWorkUtil.isNetworkAvailable(context) && networkAvailable == false)
{
Log.i(Main, 網絡連接成功);
networkAvailable = true;
type = NetWorkUtil.getAPNType(context);
Toast.makeText(context, 網絡連接成功, 1).show();
}
}
}
/**
* 注冊網絡監聽
*
* @param context
*/
public static void registerNetworkStateReceiver(Context context)
{
Intent intent = new Intent();
intent.setAction(TA_ANDROID_NET_CHANGE_ACTION);
context.sendBroadcast(intent);
}
/**
* 顯示當前網絡狀態
*
* @param context
*/
public static void checkNetWorkState(Context context)
{
Intent intent = new Intent();
intent.setAction(TA_ANDROID_NET_CHANGE_ACTION);
context.sendBroadcast(intent);
}
/**
* 注銷網絡監聽
*
* @param context
*/
public static void unRegisterNetworkStateReceiver(Context context)
{
if (receiver != null)
{
try
{
context.getApplicationContext().unregisterReceiver(receiver);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
public static Boolean isNetWorkAvailable()
{
return networkAvailable;
}
public static com.iyueju.guanggong.util.NetWorkUtil.netType getNetWorkType()
{
return type;
}
}
注冊監聽:
/**
* 注冊監聽
*/
private void registerMessageReceiver()
{
// TODO Auto-generated method stub
NetWorkReceiver receiver = NetWorkReceiver.getNetWorkReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
filter.addAction(android.gzcpc.conn.CONNECTIVITY_CHANGE);
registerReceiver(receiver, filter);
}
然後,需要在不適用APP的時候注銷
則是:
unregisterReceiver(NetWorkReceiver.getNetWorkReceiver());
然後,假如是我們的APP中,我們通過一些view的點擊或者其他的事件觸發一些網絡操作,為了避免一些錯誤,我們需要先去判斷當前網絡是否可用,當前連接的網絡不是是wifi(為用戶考慮)以及當前是否有網絡連接,還有當前的網速是多大,是否適合我們的操作等等。
下面是具體的代碼實現:
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import com.iyueju.guanggong.constant.APPConstant;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* 網絡工具類
*
* @author Administrator
*
*/
public class NetWorkUtil
{
// Private fields
private static final String TAG = NetWorkUtil.class.getSimpleName();
private static final int EXPECTED_SIZE_IN_BYTES = 1048576;// 1MB 1024*1024
private static final double BYTE_TO_KILOBIT = 0.0078125;
private static final double KILOBIT_TO_MEGABIT = 0.0009765625;
private static Handler mHandler;
public static int timer;
// 網絡狀態,連接wifi,cmnet是直連互聯網的,cmwap是需要代理,noneNet是無連接的
// 一速度來說:wifi > cmnet >cmwap > noneNet
public static enum netType
{
wifi, CMNET, CMWAP, noneNet
}
/**
* 網絡是否可用
*
* @param context
* @return
*/
public static boolean isNetworkAvailable(Context context)
{
// 獲取網絡manager
ConnectivityManager mgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] info = mgr.getAllNetworkInfo();
// 遍歷所有可以連接的網絡
if (info != null)
{
for (int i = 0; i < info.length; i++)
{
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
}
return false;
}
/**
* 判斷是否有網絡連接
*
* @param context
* @return
*/
public static boolean isNetworkConnected(Context context)
{
if (context != null)
{
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null)
{
return mNetworkInfo.isAvailable();
}
}
return false;
}
/**
* 判斷WIFI網絡是否可用
*
* @param context
* @return
*/
public static boolean isWifiConnected(Context context)
{
if (context != null)
{
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWiFiNetworkInfo = mConnectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWiFiNetworkInfo != null)
{
return mWiFiNetworkInfo.isAvailable();
}
}
return false;
}
/**
* 判斷MOBILE網絡是否可用
*
* @param context
* @return
*/
public static boolean isMobileConnected(Context context)
{
if (context != null)
{
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mMobileNetworkInfo = mConnectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mMobileNetworkInfo != null)
{
return mMobileNetworkInfo.isAvailable();
}
}
return false;
}
/**
* 獲取當前網絡連接的類型信息
*
* @param context
* @return
*/
public static int getConnectedType(Context context)
{
if (context != null)
{
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null && mNetworkInfo.isAvailable())
{
return mNetworkInfo.getType();
}
}
return -1;
}
/**
*
* @author 白貓
*
* 獲取當前的網絡狀態 -1:沒有網絡 1:WIFI網絡2:wap 網絡3:net網絡
*
* @param context
*
* @return
*/
public static netType getAPNType(Context context)
{
ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo == null)
{
return netType.noneNet;
}
int nType = networkInfo.getType();
if (nType == ConnectivityManager.TYPE_MOBILE)
{
if (networkInfo.getExtraInfo().toLowerCase().equals(cmnet))
{
return netType.CMNET;
}
else
{
return netType.CMWAP;
}
} else if (nType == ConnectivityManager.TYPE_WIFI)
{
return netType.wifi;
}
return netType.noneNet;
}
/**
* 測試網速
*
* @param handler
*/
public static void textSpeed(Handler handler)
{
mHandler = handler;
new Thread(mWorker).start();
}
/**
* Our Slave worker that does actually all the work
*/
private static final Runnable mWorker = new Runnable()
{
@Override
public void run()
{
InputStream stream = null;
try
{
int bytesIn = 0;
String downloadFileUrl = http://120.24.237.77/test;
long startCon = System.currentTimeMillis();
URL url = new URL(downloadFileUrl);
URLConnection con = url.openConnection();
con.setUseCaches(false);
long connectionLatency = System.currentTimeMillis() - startCon;
stream = con.getInputStream();
Message msgUpdateConnection = Message.obtain(mHandler,
APPConstant.MSG_UPDATE_CONNECTION_TIME);
msgUpdateConnection.arg1 = (int) connectionLatency;
mHandler.sendMessage(msgUpdateConnection);
long start = System.currentTimeMillis();
int currentByte = 0;
long updateStart = System.currentTimeMillis();
long updateDelta = 0;
int bytesInThreshold = 0;
while ((currentByte = stream.read()) != -1)
{
bytesIn++;
bytesInThreshold++;
if (updateDelta >= APPConstant.UPDATE_THRESHOLD)
{
int progress = (int) ((bytesIn / (double) EXPECTED_SIZE_IN_BYTES) * 100);
Message msg = Message.obtain(mHandler, APPConstant.MSG_UPDATE_STATUS,
calculate(updateDelta, bytesInThreshold));
msg.arg1 = progress;
msg.arg2 = bytesIn;
mHandler.sendMessage(msg);
// Reset
updateStart = System.currentTimeMillis();
bytesInThreshold = 0;
}
updateDelta = System.currentTimeMillis() - updateStart;
}
long downloadTime = (System.currentTimeMillis() - start);
// Prevent AritchmeticException
if (downloadTime == 0)
{
downloadTime = 1;
}
Message msg = Message.obtain(mHandler, APPConstant.MSG_COMPLETE_STATUS,
calculate(downloadTime, bytesIn));
msg.arg1 = bytesIn;
mHandler.sendMessage(msg);
} catch (MalformedURLException e)
{
Log.e(TAG, e.getMessage());
} catch (IOException e)
{
Log.e(TAG, e.getMessage());
} finally
{
try
{
if (stream != null)
{
stream.close();
}
} catch (IOException e)
{
// Suppressed
}
}
}
};
/**
*
* 1 byte = 0.0078125 kilobits 1 kilobits = 0.0009765625 megabit
*
* @param downloadTime
* in miliseconds
* @param bytesIn
* number of bytes downloaded
* @return SpeedInfo containing current speed
*/
private static SpeedInfo calculate(final long downloadTime, final long bytesIn)
{
SpeedInfo info = new SpeedInfo();
// from mil to sec
long bytespersecond = (bytesIn / downloadTime) * 1000;
double kilobits = bytespersecond * BYTE_TO_KILOBIT;
double megabits = kilobits * KILOBIT_TO_MEGABIT;
info.downspeed = bytespersecond;
info.kilobits = kilobits;
info.megabits = megabits;
return info;
}
/**
* Transfer Object
*
* @author devil
*
*/
public static class SpeedInfo
{
public double kilobits = 0;
public double megabits = 0;
public double downspeed = 0;
}
}
其中,涉及到了四個其他常量是:
public static final int MSG_UPDATE_STATUS = 0; public static final int MSG_UPDATE_CONNECTION_TIME = 1; public static final int MSG_COMPLETE_STATUS = 2; public static final int UPDATE_THRESHOLD = 300;
注意:使用的時候需要加入一些權限,
Android 源碼系列之(十一)從源碼的角度深入理解AccessibilityService,打造自己的APP小外掛(下)
在上篇文章Android 源碼系列之<十>從源碼的角度深入理解AccessibilityService,打造自己的APP小外掛(上)中我們講解了通過Acces
android獲取系統自帶浏覽器書簽
剛剛接手一個備份系統浏覽器書簽的模塊,現在把代碼貼出來,另外有幾點疑問請路過的大神指教 1、根據官方api應該是有以下幾個字段是可以獲取的 但是除了
Android學習之獲取系統應用信息列表的實現
前言:好幾天電腦打不開CSDN博客,也不知道怎麼回事,今天下班回來突然能打開了,遂將周末實現的一個效果貼上。實現功能:獲取手機應用圖標,名稱,時間(安裝時間/更新時間),
Android清除數據、清除緩存、一鍵清理的區別
前言??在Android設備中,我們經常會看到與系統或者應用相關的清除功能有:清除數據、清除緩存、一鍵清理,這麼多清除功能對於一個程序猿就夠難理解了,偏偏很多安卓設備上都