很难理解 wifi 连接是如何工作的
Hard time understanding how wifi connection work
我有一个应用程序监听指定的 ip 和端口。我明白了如何连接,如何接收数据。
事情是这样的:
- 不明白如何确认连接是否成功
- 我不明白如何检测连接丢失
- 而且我不明白如何在退出我的应用程序时退出我的 AsyncTask(使用菜单)
这是我用来获取数据的class:
public final class MyClientTask extends AsyncTask<Void, Void, Void> {
BufferedReader br = null;
String dstAddress;
int dstPort;
String response = "";
public MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
@Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
//Instanciation de l'inputStreamReader
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
// creation nouveau bufferreader
br = new BufferedReader(inputStreamReader);
StringBuilder msgBuilder = new StringBuilder();
// on évite String = String + char qui fait des créations de builders automatiques en java.
boolean ended = false;
while (!ended) {
int nextChar = inputStreamReader.read();
if (nextChar == -1) {
ended = true; // <= fin du stream
} else if (nextChar == 03) {
String maChaine="";
// fin du message
maChaine = msgBuilder.toString();
//récupération du char après <STX>
Character nbChamps = maChaine.charAt(1);
//test pour savoir si c'est une alerte
if(nbChamps == '7'){
//insertion de l'alerte dans la BDD
BDDAlerte.insertAlerte1(maChaine);
//creation de la notif
createNotification();
}
//ici les tests splits pour le nombre de champs et inserer dans BdD ou faire ce qu'il faut
//suppVieillesAlertes();
runOnUiThread(new Runnable() {
@Override
public void run() {
//find listview to populate
final ListView lvItems = (ListView)findViewById(R.id.listView1);
//setup cursor adapter using Cursor from last step
final AlerteAdapter todoAdapter = new AlerteAdapter(getBaseContext(), BDDAlerte.getAllRows(),0);
lvItems.setAdapter(todoAdapter);
}
});
// réinitialisation du builder
msgBuilder.setLength(0);
} else {
msgBuilder.append((char)nextChar);
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}
finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
}
我的退出按钮位于 onOptionsItemSelected 应用程序的菜单中。
如果我没有提供所有数据,我是来澄清事情的。
西蒙
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
构造套接字前,应先检查网络状态
如果在读取数据时抛出io异常,则意味着连接丢失。
您可以定义一个布尔字段 "running",初始为 true,当应用程序退出时将其设置为 false,在您的 while 循环中检查它的值,如下所示:
while (!ended&&running) {
int nextChar = inputStreamReader.read();
if (nextChar == -1) {
ended = true; // <= fin du stream
}
// ......
}
首先创建一个单独的 class 来检查连接并通过调用方法来设置条件,而不是仅对套接字进行进一步处理..
public class 移动连接 {
public static NetworkInfo getNetworkInfo(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
}
public static boolean isConnected(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected());
}
public static boolean isConnectedWifi(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
}
public static boolean isConnectedMobile(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
}
public static boolean isConnectedFast(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected()
&& MobileConnectivity.isConnectionFast(info.getType(), info.getSubtype()));
}
public static boolean isConnectionFast(int type, int subType) {
if (type == ConnectivityManager.TYPE_WIFI) {
return true;
} else if (type == ConnectivityManager.TYPE_MOBILE) {
switch (subType) {
case TelephonyManager.NETWORK_TYPE_1xRTT:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_CDMA:
return false; // ~ 14-64 kbps
case TelephonyManager.NETWORK_TYPE_EDGE:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return true; // ~ 400-1000 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return true; // ~ 600-1400 kbps
case TelephonyManager.NETWORK_TYPE_GPRS:
return false; // ~ 100 kbps
case TelephonyManager.NETWORK_TYPE_HSDPA:
return true; // ~ 2-14 Mbps
case TelephonyManager.NETWORK_TYPE_HSPA:
return true; // ~ 700-1700 kbps
case TelephonyManager.NETWORK_TYPE_HSUPA:
return true; // ~ 1-23 Mbps
case TelephonyManager.NETWORK_TYPE_UMTS:
return true; // ~ 400-7000 kbps
/*
* Above API level 7, make sure to set android:targetSdkVersion to
* appropriate level to use these
*/
case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
return true; // ~ 1-2 Mbps
case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
return true; // ~ 5 Mbps
case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
return true; // ~ 10-20 Mbps
case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
return false; // ~25 kbps
case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
return true; // ~ 10+ Mbps
// Unknown
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
default:
return false;
}
} else {
return false;
}
}
我有一个应用程序监听指定的 ip 和端口。我明白了如何连接,如何接收数据。
事情是这样的:
- 不明白如何确认连接是否成功
- 我不明白如何检测连接丢失
- 而且我不明白如何在退出我的应用程序时退出我的 AsyncTask(使用菜单)
这是我用来获取数据的class:
public final class MyClientTask extends AsyncTask<Void, Void, Void> {
BufferedReader br = null;
String dstAddress;
int dstPort;
String response = "";
public MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
@Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
//Instanciation de l'inputStreamReader
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
// creation nouveau bufferreader
br = new BufferedReader(inputStreamReader);
StringBuilder msgBuilder = new StringBuilder();
// on évite String = String + char qui fait des créations de builders automatiques en java.
boolean ended = false;
while (!ended) {
int nextChar = inputStreamReader.read();
if (nextChar == -1) {
ended = true; // <= fin du stream
} else if (nextChar == 03) {
String maChaine="";
// fin du message
maChaine = msgBuilder.toString();
//récupération du char après <STX>
Character nbChamps = maChaine.charAt(1);
//test pour savoir si c'est une alerte
if(nbChamps == '7'){
//insertion de l'alerte dans la BDD
BDDAlerte.insertAlerte1(maChaine);
//creation de la notif
createNotification();
}
//ici les tests splits pour le nombre de champs et inserer dans BdD ou faire ce qu'il faut
//suppVieillesAlertes();
runOnUiThread(new Runnable() {
@Override
public void run() {
//find listview to populate
final ListView lvItems = (ListView)findViewById(R.id.listView1);
//setup cursor adapter using Cursor from last step
final AlerteAdapter todoAdapter = new AlerteAdapter(getBaseContext(), BDDAlerte.getAllRows(),0);
lvItems.setAdapter(todoAdapter);
}
});
// réinitialisation du builder
msgBuilder.setLength(0);
} else {
msgBuilder.append((char)nextChar);
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}
finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
}
我的退出按钮位于 onOptionsItemSelected 应用程序的菜单中。
如果我没有提供所有数据,我是来澄清事情的。
西蒙
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
构造套接字前,应先检查网络状态
如果在读取数据时抛出io异常,则意味着连接丢失。
您可以定义一个布尔字段 "running",初始为 true,当应用程序退出时将其设置为 false,在您的 while 循环中检查它的值,如下所示:
while (!ended&&running) {
int nextChar = inputStreamReader.read();
if (nextChar == -1) {
ended = true; // <= fin du stream
}
// ......
}
首先创建一个单独的 class 来检查连接并通过调用方法来设置条件,而不是仅对套接字进行进一步处理..
public class 移动连接 {
public static NetworkInfo getNetworkInfo(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
}
public static boolean isConnected(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected());
}
public static boolean isConnectedWifi(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
}
public static boolean isConnectedMobile(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
}
public static boolean isConnectedFast(Context context) {
NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
return (info != null && info.isConnected()
&& MobileConnectivity.isConnectionFast(info.getType(), info.getSubtype()));
}
public static boolean isConnectionFast(int type, int subType) {
if (type == ConnectivityManager.TYPE_WIFI) {
return true;
} else if (type == ConnectivityManager.TYPE_MOBILE) {
switch (subType) {
case TelephonyManager.NETWORK_TYPE_1xRTT:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_CDMA:
return false; // ~ 14-64 kbps
case TelephonyManager.NETWORK_TYPE_EDGE:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return true; // ~ 400-1000 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return true; // ~ 600-1400 kbps
case TelephonyManager.NETWORK_TYPE_GPRS:
return false; // ~ 100 kbps
case TelephonyManager.NETWORK_TYPE_HSDPA:
return true; // ~ 2-14 Mbps
case TelephonyManager.NETWORK_TYPE_HSPA:
return true; // ~ 700-1700 kbps
case TelephonyManager.NETWORK_TYPE_HSUPA:
return true; // ~ 1-23 Mbps
case TelephonyManager.NETWORK_TYPE_UMTS:
return true; // ~ 400-7000 kbps
/*
* Above API level 7, make sure to set android:targetSdkVersion to
* appropriate level to use these
*/
case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
return true; // ~ 1-2 Mbps
case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
return true; // ~ 5 Mbps
case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
return true; // ~ 10-20 Mbps
case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
return false; // ~25 kbps
case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
return true; // ~ 10+ Mbps
// Unknown
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
default:
return false;
}
} else {
return false;
}
}