我得到了一个AsyncTask,应该检查对主机名的网络访问。但是doInBackground()永远不会超时。有人知道吗?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
只需创建下面的类来检查internet连接:
public class ConnectionStatus {
private Context _context;
public ConnectionStatus(Context context) {
this._context = context;
}
public boolean isConnectionAvailable() {
ConnectivityManager connectivity = (ConnectivityManager) _context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
return false;
}
}
该类仅包含一个返回连接状态布尔值的方法。因此,简单来说,如果该方法找到一个到Internet的有效连接,则返回值为true,否则为false,如果没有找到有效连接。
MainActivity中的下面的方法调用前面描述的方法的结果,并提示用户进行相应的操作:
public void addListenerOnWifiButton() {
Button btnWifi = (Button)findViewById(R.id.btnWifi);
iia = new ConnectionStatus(getApplicationContext());
isConnected = iia.isConnectionAvailable();
if (!isConnected) {
btnWifi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
Toast.makeText(getBaseContext(), "Please connect to a hotspot",
Toast.LENGTH_SHORT).show();
}
});
}
else {
btnWifi.setVisibility(4);
warning.setText("This app may use your mobile data to update events and get their details.");
}
}
在上面的代码中,如果结果为假,(因此没有互联网连接,用户将被带到Android wi-fi面板,在那里他将被提示连接到wi-fi热点。
这是最简单和简单的方法来检查互联网连接的wifi和移动数据。
public static boolean isConnected(Activity _context) {
if (_context != null) {
ConnectivityManager connMgr = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeInfo = connMgr.getActiveNetworkInfo();
if (activeInfo != null && activeInfo.isConnected()) {
boolean wifiConnected = activeInfo.getType() == ConnectivityManager.TYPE_WIFI;
boolean mobileConnected = activeInfo.getType() == ConnectivityManager.TYPE_MOBILE;
if (wifiConnected || mobileConnected) {
Log.d(TAG, "Wifi Connected ");
return true;
} else {
showAlert(_context,_context.getString(R.string.err_no_internet));
return false;
}
} else {
showAlert(_context,_context.getString(R.string.err_no_internet));
return false;
}
} else {
Log.e(TAG, "networkConnectivity: Context NULL");
}
return false;
}
检查这段代码…这对我很有用:)
public static void isNetworkAvailable(final Handler handler, final int timeout) {
// ask fo message '0' (not connected) or '1' (connected) on 'handler'
// the answer must be send before before within the 'timeout' (in milliseconds)
new Thread() {
private boolean responded = false;
@Override
public void run() {
// set 'responded' to TRUE if is able to connect with google mobile (responds fast)
new Thread() {
@Override
public void run() {
HttpGet requestForTest = new HttpGet("http://m.google.com");
try {
new DefaultHttpClient().execute(requestForTest); // can last...
responded = true;
}
catch (Exception e) {
}
}
}.start();
try {
int waited = 0;
while(!responded && (waited < timeout)) {
sleep(100);
if(!responded ) {
waited += 100;
}
}
}
catch(InterruptedException e) {} // do nothing
finally {
if (!responded) { handler.sendEmptyMessage(0); }
else { handler.sendEmptyMessage(1); }
}
}
}.start();
}
然后,我定义处理程序:
Handler h = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what != 1) { // code if not connected
} else { // code if connected
}
}
};
...并启动测试:
isNetworkAvailable(h,2000); // get the answser within 2000 ms
移动设备上的一个重要用例是确保存在实际连接。当移动用户使用“专属门户”进入Wifi网络时,这是一个常见的问题,他们需要在其中登录。我在后台使用这个阻塞功能来确保连接存在。
/*
* Not Thread safe. Blocking thread. Returns true if it
* can connect to URL, false and exception is logged.
*/
public boolean checkConnectionHttps(String url){
boolean responded = false;
HttpGet requestTest = new HttpGet(url);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 5000);
DefaultHttpClient client = new DefaultHttpClient(params);
try {
client.execute(requestTest);
responded = true;
} catch (ClientProtocolException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
} catch (IOException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
e.printStackTrace();
}
return responded;
}
在我目前所见过的所有方法中,最短、最干净的方法应该是:
public final static boolean isConnected( Context context )
{
final ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
PS:这不会ping任何主机,它只是检查连接状态,所以如果你的路由器没有互联网连接,而你的设备连接到它,这个方法将返回true,尽管你没有互联网。
对于实际的测试,我建议执行一个HttpHead请求(例如到www.google.com)并检查状态,如果它是200 OK,一切正常,并且您的设备有互联网连接。