1、基於socket的用法html
服務器端:java
先啓動一個服務器端的socket ServerSocket svr = new ServerSocket(8989);android
開始偵聽請求 Socket s = svr.accept();git
取得輸入和輸出 DataInputStream dis = new DataInputStream(s.getInputStream());web
DataOutputStream dos = new DataOutputStream(s.getOutputStream());sql
Socket 的交互經過流來完成,便是說傳送的字節流,所以任何文件均可以在上面傳送。誰打開的記得要關上。數據庫
用DataInputStream/DataOutputStream來進行包裝是由於咱們想要他們對基本數據類型的讀寫功能readInt(),writeInt(),readUTF(),writeUTF()等等。express
客戶端:apache
發起一個socket鏈接 Socket s = new Socket("192.168.1.200",8989);編程
取得輸入和輸出 DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
以後就能夠相互通訊了。誰打開的記得要關上。
2、基於Http協議
通常是發送請求到某個應用服務器。此時須要用到HttpURLConnection
先取得HttpURLConnection urlConn = new URL("http://www.google.com").openConnection();
設置標誌
urlConn.setDoOutput(true); urlConn.setDoInput(true);//post的狀況下須要設置DoOutput爲true
urlConn.setRequestMethod("POST");
urlConn.setUseCache(false);//設置是否用緩存
urlConn.setRequestProperty("Content-type","application/x-www-form-urlencoded");//設置content-type
得到輸出流,便於想服務器發送信息。
DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());
望流裏面寫請求參數
dos.writeBytes("name="+URLEncoder.encode("chenmouren","gb2312");
dos.flush();dos.close();//發送完後立刻關閉。
得到輸入流,取數據
BufferReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
reader.readLine();//用 !=null來判斷是否結束
reader.close();
讀完了記得關閉connection urlConn.disconnect();
流程記錄就到此爲止。
三、HttpURLConnection接口
首先須要明確的是,Http通訊中的POST和GET請求方式的不一樣。GET能夠得到靜態頁面,也能夠把參數放在URL字符串後面,傳遞給服務器。而POST方法的參數是放在Http請求中。所以,在編程以前,應當首先明確使用的請求方法,而後再根據所使用的方式選擇相應的編程方式。
HttpURLConnection是繼承於URLConnection類,兩者都是抽象類。其對象主要經過URL的openConnection方法得到。建立方法以下代碼所示:
|
經過如下方法能夠對請求的屬性進行一些設置,以下所示:
|
HttpURLConnection默認使用GET方式,例以下面代碼所示:
|
若是須要使用POST方式,則須要setRequestMethod設置。代碼以下:
|
四、使用Apache提供的HttpClient接口一樣能夠進行HTTP操做。
對於GET和POST請求方法的操做有所不一樣。GET方法的操做代碼示例以下:
[java] view plaincopy
使用POST方法進行參數傳遞時,須要使用NameValuePair來保存要傳遞的參數。,另外,還須要設置所使用的字符集。代碼以下所示:
[java] view plaincopy
HttpClient其實是對Java提供方法的一些封裝,在HttpURLConnection中的輸入輸出流操做,在這個接口中被統一封裝成了HttpPost(HttpGet)和HttpResponse,這樣,就減小了操做的繁瑣性。
另外,在使用POST方式進行傳輸時,須要進行字符編碼。
五、
6、1、獲取並使用KSOAP包
在Android SDK中並無提供調用WebService的庫,所以,須要使用第三方的SDK來調用WebService。PC版本的WebService庫很是豐富,但這些對Android來講過於龐大。適合手機的WebService客戶端的SDK有一些,比較經常使用的是KSOAP2。
KSOAP2 地址:http://code.google.com/p/ksoap2-android/
我下載的最新的是: ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar
注意:
我在使用ksoap2-android時犯了一個低級錯誤:使用時報錯誤:The import org.ksoap2 cannot be resolved。
當時分析這個問題時一直覺得是Eclipse出了問題,找了好多方法都不行,
實際是我下載的ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar文件是錯誤的致使的,走了彎路。
在 http://code.google.com/p/ksoap2-android/wiki/HowToUse?tm=2 頁面 經過鼠標右鍵連接另存爲存的是同名的一個純文本的Html文件。而不是咱們想要的。
我是在
http://code.google.com/p/ksoap2-android/source/browse/m2-repo/com/google/code/ksoap2-android/ksoap2-android-assembly/2.5.4/ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar 點 View raw file 才正確下載對應文件的。
選擇咱們的項目,右鍵菜單中 Build Path –> Add External Archives… 增長這個下載的包
增長好後,咱們在 選擇咱們的項目,右鍵菜單中 Build Path –> Configure Build Path 的 Libraries 中能夠看到下面圖:
二,分如下幾步來調用 WebService
1、指定 WebService 的命名空間和調用方法
import org.ksoap2.serialization.SoapObject;private static final String NAMESPACE = "http://WebXml.com.cn/";private static final String METHOD_NAME = "getWeatherbyCityName"; SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME);
SoapObject類的第一個參數表示WebService的命名空間,能夠從WSDL文檔中找到WebService的命名空間。
第二個參數表示要調用的WebService方法名。
2、設置調用方法的參數值,若是沒有參數,能夠省略,設置方法的參數值的代碼以下:
rpc.addProperty("theCityName", "北京");
要注意的是,addProperty方法的第1個參數雖然表示調用方法的參數名,但該參數值並不必定與服務端的WebService類中的方法參數名一致,只要設置參數的順序一致便可。
3、生成調用Webservice方法的SOAP請求信息。
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);envelope.bodyOut = rpc;envelope.dotNet = true;envelope.setOutputSoapObject(rpc);
建立SoapSerializationEnvelope對象時須要經過SoapSerializationEnvelope類的構造方法設置SOAP協議的版本號。
該版本號須要根據服務端WebService的版本號設置。
在建立SoapSerializationEnvelope對象後,不要忘了設置SOAPSoapSerializationEnvelope類的bodyOut屬性,
該屬性的值就是在第一步建立的SoapObject對象。
4、建立HttpTransportsSE對象。
這裏不要使用 AndroidHttpTransport ht = new AndroidHttpTransport(URL); 這是一個要過時的類
private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx";HttpTransportSE ht = new HttpTransportSE(URL);
ht.debug = true;
5、使用call方法調用WebService方法
private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName";ht.call(SOAP_ACTION, envelope);
網上有人說這裏的call的第一個參數爲null,可是通過個人測試,null是不行的。
第2個參數就是在第3步建立的SoapSerializationEnvelope對象。
6、得到WebService方法的返回結果
有兩種方法:
1、使用getResponse方法得到返回數據。
private SoapObject detail;detail =(SoapObject) envelope.getResponse();
2、使用 bodyIn 及 getProperty。
private SoapObject detail;SoapObject result = (SoapObject)envelope.bodyIn;detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult");
7、 這時候執行會出錯,提示沒有權限訪問網絡
須要修改 AndroidManifest.xml 文件,賦予相應權限
簡單來講就是增長下面這行配置:<uses-permission android:name="android.permission.INTERNET"></uses-permission>
完整的 AndroidManifest.xml 文件 以下:
注:Android 中在代碼中爲了調試寫了system.out.print()輸出項
在菜單:Window-->show view-->other-->找到Android,選擇Logcat 是能夠看到輸出的,
若是你想在一個單獨的窗口看到system.out.print()的輸出的話,能夠在logcat界面點那個綠色的「+」好,
在Filter name 和 By log tag裏面均填入System.out,這樣的話你就能在單獨的界面查看system.out.print()的輸出了!!
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ghj1976.MyWeather" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MyWeatherActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest>
完整的代碼以下:
package ghj1976.MyWeather;import java.io.UnsupportedEncodingException;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;import org.ksoap2.SoapEnvelope;import org.ksoap2.serialization.SoapObject;import org.ksoap2.serialization.SoapSerializationEnvelope;//import org.ksoap2.transport.AndroidHttpTransport;import org.ksoap2.transport.HttpTransportSE;public class MyWeatherActivity extends Activity { private Button okButton; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); okButton = (Button) this.findViewById(R.id.btn_Search); okButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { String city = "北京"; getWeather(city); } }); } private static final String NAMESPACE = "http://WebXml.com.cn/"; // WebService地址 private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx"; private static final String METHOD_NAME = "getWeatherbyCityName"; private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName"; private String weatherToday; private SoapObject detail; public void getWeather(String cityName) { try { System.out.println("rpc------"); SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME); System.out.println("rpc" + rpc); System.out.println("cityName is " + cityName); rpc.addProperty("theCityName", cityName); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.bodyOut = rpc; envelope.dotNet = true; envelope.setOutputSoapObject(rpc); HttpTransportSE ht = new HttpTransportSE(URL); //AndroidHttpTransport ht = new AndroidHttpTransport(URL); ht.debug = true; ht.call(SOAP_ACTION, envelope); //ht.call(null, envelope); //SoapObject result = (SoapObject)envelope.bodyIn; //detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult"); detail =(SoapObject) envelope.getResponse(); //System.out.println("result" + result); System.out.println("detail" + detail); Toast.makeText(this, detail.toString(), Toast.LENGTH_LONG).show(); parseWeather(detail); return; } catch (Exception e) { e.printStackTrace(); } } private void parseWeather(SoapObject detail) throws UnsupportedEncodingException { String date = detail.getProperty(6).toString(); weatherToday = "今天:" + date.split(" ")[0]; weatherToday = weatherToday + "\n天氣:" + date.split(" ")[1]; weatherToday = weatherToday + "\n氣溫:" + detail.getProperty(5).toString(); weatherToday = weatherToday + "\n風力:" + detail.getProperty(7).toString() + "\n"; System.out.println("weatherToday is " + weatherToday); Toast.makeText(this, weatherToday, Toast.LENGTH_LONG).show(); }}
參考資料
在Android中訪問WebService接口
http://www.cnblogs.com/yy-7years/archive/2011/01/24/1943286.html
Android調用WebService
http://express.ruanko.com/ruanko-express_34/technologyexchange5.html
中國氣象局的WebService地址
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
Android與服務器端數據交互(基於SOAP協議整合android+webservice)
http://www.cnblogs.com/zhangdongzi/archive/2011/04/19/2020688.html
版權聲明:本文爲博主原創文章,未經博主容許不得轉載。
7、[java] view plaincopy
8、[java] view plaincopy
[java] view plaincopy
[java] view plaincopy
[java] view plaincopy
9、[java] view plaincopy
10、Android開發應用程序時,若是應用程序須要訪問網絡權限,須要在 AndroidManifest.xml 中加入如下代碼<uses-permission android:name=」android.permission.INTERNET」></uses-permission>
若是不知道放在哪一個位置,那就放在</manifest>前邊好了。
一樣的若是用到其它的權限,也須要做出聲明,部分權限列表以下:
android.permission.ACCESS_CHECKIN_PROPERTIES
容許讀寫訪問」properties」表在 checkin數據庫中,改值能夠修改上傳( Allows read/write access to the 「properties」 table in the checkin database, to change values that get uploaded)
android.permission.ACCESS_COARSE_LOCATION
容許一個程序訪問CellID或WiFi熱點來獲取粗略的位置(Allows an application to access coarse (e.g., Cell-ID, WiFi) location)
android.permission.ACCESS_FINE_LOCATION
容許一個程序訪問精良位置(如GPS) (Allows an application to access fine (e.g., GPS) location)
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
容許應用程序訪問額外的位置提供命令(Allows an application to access extra location provider commands)
android.permission.ACCESS_MOCK_LOCATION
容許程序建立模擬位置提供用於測試(Allows an application to create mock location providers for testing)
android.permission.ACCESS_NETWORK_STATE
容許程序訪問有關GSM網絡信息(Allows applications to access information about networks)
android.permission.ACCESS_SURFACE_FLINGER
容許程序使用SurfaceFlinger底層特性 (Allows an application to use SurfaceFlinger’s low level features)
android.permission.ACCESS_WIFI_STATE
容許程序訪問Wi-Fi網絡狀態信息(Allows applications to access information about Wi-Fi networks)
android.permission.ADD_SYSTEM_SERVICE
容許程序發佈系統級服務(Allows an application to publish system-level services).
android.permission.BATTERY_STATS
容許程序更新手機電池統計信息(Allows an application to update the collected battery statistics)
android.permission.BLUETOOTH
容許程序鏈接到已配對的藍牙設備(Allows applications to connect to paired bluetooth devices)
11、不說廢話,直接說說實現android定位有關的API吧。
這些API都在android.location包下,一共有三個接口和八個類。它們配合使用便可實現定位功能。
三個接口:
GpsStatus.Listener:這是一個當GPS狀態發生改變時,用來接收通知的接口。
GpsStatus.NmeaListener:這是一個用來從GPS裏接收Nmea-0183(爲海用電子設備制定的標準格式)信息的接口。
LocationListener:位置監聽器,用於接收當位置信息發生改變時從LocationManager接收通知的接口。
八個類:
Address:描述地址的類,好比:北京天安門
Criteria:用於描述Location Provider標準的類,標準包括位置精度水平,電量消耗水平,是否獲取海拔、方位信息,是否容許接收付費服務。
GeoCoder:用於處理地理位置的編碼。
GpsSatellite:和GpsStatus聯合使用,用於描述當前GPS衛星的狀態。
GpsStatus:和GpsStatus.Listener聯合使用,用於描述當前GPS衛星的狀態。
Location:用於描述位置信息。
LocationManager:經過此類獲取和調用系統位置服務
LocationProvider:用於描述Location Provider的抽象超類,一個LocationProvider應該可以週期性的報告當前設備的位置信息。
這裏經過一個示例代碼來演示一下android定位。
首先,在AndroidManifest.xml清單文件裏須要加入ACCESS_FINE_LOCATION權限:
1 |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> |
其次,實現代碼以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
package com.test;
import java.io.IOException; import java.util.List;
import android.app.Activity; import android.location.Address; import android.location.Criteria; import android.location.Geocoder; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; import android.widget.Toast;
public class PositionActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 獲取到LocationManager對象 LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // 建立一個Criteria對象 Criteria criteria = new Criteria(); // 設置粗略精確度 criteria.setAccuracy(Criteria.ACCURACY_COARSE); // 設置是否須要返回海拔信息 criteria.setAltitudeRequired(false); // 設置是否須要返回方位信息 criteria.setBearingRequired(false); // 設置是否容許付費服務 criteria.setCostAllowed(true); // 設置電量消耗等級 criteria.setPowerRequirement(Criteria.POWER_HIGH); // 設置是否須要返回速度信息 criteria.setSpeedRequired(false); // 根據設置的Criteria對象,獲取最符合此標準的provider對象 41 String currentProvider = locationManager .getBestProvider(criteria, true); Log.d("Location", "currentProvider: " + currentProvider); // 根據當前provider對象獲取最後一次位置信息 44 Location currentLocation = locationManager .getLastKnownLocation(currentProvider); // 若是位置信息爲null,則請求更新位置信息 46 if (currentLocation == null) { locationManager.requestLocationUpdates(currentProvider, 0, 0, locationListener); } // 直到得到最後一次位置信息爲止,若是未得到最後一次位置信息,則顯示默認經緯度 50 // 每隔10秒獲取一次位置信息 51 while (true) { currentLocation = locationManager .getLastKnownLocation(currentProvider); if (currentLocation != null) { Log.d("Location", "Latitude: " + currentLocation.getLatitude()); Log.d("Location", "location: " + currentLocation.getLongitude()); break; } else { Log.d("Location", "Latitude: " + 0); Log.d("Location", "location: " + 0); } try { Thread.sleep(10000); } catch (InterruptedException e) { Log.e("Location", e.getMessage()); } } // 解析地址並顯示 69 Geocoder geoCoder = new Geocoder(this); try { int latitude = (int) currentLocation.getLatitude(); int longitude = (int) currentLocation.getLongitude(); List<Address> list = geoCoder.getFromLocation(latitude, longitude, 2); for (int i = 0; i < list.size(); i++) { Address address = list.get(i); Toast.makeText( PositionActivity.this, address.getCountryName() + address.getAdminArea() + address.getFeatureName(), Toast.LENGTH_LONG) .show(); } } catch (IOException e) { Toast.makeText(PositionActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } // 建立位置監聽器 85 private LocationListener locationListener = new LocationListener() { // 位置發生改變時調用 87 @Override public void onLocationChanged(Location location) { Log.d("Location", "onLocationChanged"); Log.d("Location", "onLocationChanged Latitude" + location.getLatitude()); Log.d("Location", "onLocationChanged location" + location.getLongitude()); }
// provider失效時調用 95 @Override public void onProviderDisabled(String provider) { Log.d("Location", "onProviderDisabled"); }
// provider啓用時調用101 @Override public void onProviderEnabled(String provider) { Log.d("Location", "onProviderEnabled"); }
// 狀態改變時調用107 @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.d("Location", "onStatusChanged"); } }; } |
因爲代碼裏的Criteria對象對位置精度要求並不高,因此通常會返回「network」做爲provider,而基於network的定位每每會存在必定的位置誤差,這對於須要精肯定位的應用程序來講,顯然不合要求。這時,須要則須要用到基於GPS的定位方法了
12、在前文Android定位功能(一)中,已經大體介紹了一下在Android平臺中,和定位功能相關的類,並舉例獲取了位置信息。可是前文是基於Criteria定製了一個標準,經過getBestProvider()方法由Android系統自動獲取最符合Criteria的LocationProvider,從而實現了定位功能。這樣的作法能最大限度的保證定位功能的可實現性,可是卻沒法保證獲取到的位置信息有最大的準確度。由於除了GPS外,其餘定位方式都或多或少存在着位置偏移。
在實現GPS定位前,先了解一下GPS的部分特性:
1:GPS定位須要依靠3顆或以上的衛星。
2:GPS定位受環境影響較大,在晴朗的空地上,較容易搜索到衛星,而在室內一般是沒法搜索到衛星的。
3:GPS定位須要使用GPS功能模塊,而GPS功能模塊的耗電量是巨大的。
在Android系統中,實現GPS定位的思路大體是:
1、獲取GPS的Location Provider。
2、將此Provider傳入到requestLocationUpdates()方法,讓Android系統獲知搜索位置方式。
3、建立實現了GpsStatus.Listener接口的對象,重寫onGpsStatusChanged()方法,向LocationManager添加次監聽器,檢測衛星狀態。(可選步驟)
根據以上思路,仿照Android定位功能(一)中的例子,能夠很容易的獲得如下實現代碼:(此代碼的實現前提是GPS功能模塊處於打開狀態)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
public class MainActivity extends Activity { private LocationManager locationManager; private GpsStatus gpsstatus;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
// 獲取到LocationManager對象 locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// 根據設置的Criteria對象,獲取最符合此標準的provider對象 String currentProvider = locationManager.getProvider( LocationManager.GPS_PROVIDER).getName();
// 根據當前provider對象獲取最後一次位置信息 Location currentLocation = locationManager .getLastKnownLocation(currentProvider); // 若是位置信息爲null,則請求更新位置信息 if (currentLocation == null) { locationManager.requestLocationUpdates(currentProvider, 0, 0, locationListener); } // 增長GPS狀態監聽器 locationManager.addGpsStatusListener(gpsListener);
// 直到得到最後一次位置信息爲止,若是未得到最後一次位置信息,則顯示默認經緯度 // 每隔10秒獲取一次位置信息 while (true) { currentLocation = locationManager .getLastKnownLocation(currentProvider); if (currentLocation != null) { Log.d("Location", "Latitude: " + currentLocation.getLatitude()); Log.d("Location", "location: " + currentLocation.getLongitude()); break; } else { Log.d("Location", "Latitude: " + 0); Log.d("Location", "location: " + 0); } try { Thread.sleep(10000); } catch (InterruptedException e) { Log.e("Location", e.getMessage()); } } }
private GpsStatus.Listener gpsListener = new GpsStatus.Listener() { // GPS狀態發生變化時觸發 @Override public void onGpsStatusChanged(int event) { // 獲取當前狀態 gpsstatus = locationManager.getGpsStatus(null); switch (event) { // 第一次定位時的事件 case GpsStatus.GPS_EVENT_FIRST_FIX: break; // 開始定位的事件 case GpsStatus.GPS_EVENT_STARTED: break; // 發送GPS衛星狀態事件 case GpsStatus.GPS_EVENT_SATELLITE_STATUS: Toast.makeText(MainActivity.this,"GPS_EVENT_SATELLITE_STATUS", Toast.LENGTH_SHORT).show(); Iterable<GpsSatellite> allSatellites = gpsstatus .getSatellites(); Iterator<GpsSatellite> it = allSatellites.iterator(); int count = 0; while (it.hasNext()) { count++; } Toast.makeText(MainActivity.this, "Satellite Count:" + count, Toast.LENGTH_SHORT).show(); break; // 中止定位事件 case GpsStatus.GPS_EVENT_STOPPED: Log.d("Location", "GPS_EVENT_STOPPED"); break; } } };
// 建立位置監聽器 private LocationListener locationListener = new LocationListener() { // 位置發生改變時調用 @Override public void onLocationChanged(Location location) { Log.d("Location", "onLocationChanged"); }
// provider失效時調用 @Override public void onProviderDisabled(String provider) { Log.d("Location", "onProviderDisabled"); }
// provider啓用時調用 @Override public void onProviderEnabled(String provider) { Log.d("Location", "onProviderEnabled"); }
// 狀態改變時調用 @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.d("Location", "onStatusChanged"); } }; } |
13、[java] view plaincopy
14、登錄頁面輸入用戶名和密碼,登錄成功後跳轉到主頁面,失敗時顯示錯誤信息。
傳遞參數時用BasicNameValuePair的List以httpPost.setEntity的方式來作,不能用HttpParams。
[java] view plaincopy
15、Android Http JSon服務器端和客戶端通訊
服務器端:
[java] view plaincopy
[java] view plaincopy
[java] view plaincopy
[java] view plaincopy
16、咱們編寫的是Andorid的HTTP協議多線程斷點下載應用程序。直接使用單線程下載HTTP文件對咱們來講是一件很是簡單的事。那麼,多線程斷點須要什麼功能?
1.多線程下載,
2.支持斷點。
使用多線程的好處:使用多線程下載會提高文件下載的速度。那麼多線程下載文件的過程是:
(1)首先得到下載文件的長度,而後設置本地文件的長度。
HttpURLConnection.getContentLength();//獲取下載文件的長度
RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd");
file.setLength(filesize);//設置本地文件的長度
(2)根據文件長度和線程數計算每條線程下載的數據長度和下載位置。
如:文件的長度爲6M,線程數爲3,那麼,每條線程下載的數據長度爲2M,每條線程開始下載的位置以下圖所示。
例如10M大小,使用3個線程來下載,
線程下載的數據長度 (10%3 == 0 ? 10/3:10/3+1) ,第1,2個線程下載長度是4M,第三個線程下載長度爲2M
下載開始位置:線程id*每條線程下載的數據長度 = ?
下載結束位置:(線程id+1)*每條線程下載的數據長度-1=?
(3)使用Http的Range頭字段指定每條線程從文件的什麼位置開始下載,下載到什麼位置爲止,
如:指定從文件的2M位置開始下載,下載到位置(4M-1byte)爲止
代碼以下:HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");
(4)保存文件,使用RandomAccessFile類指定每條線程從本地文件的什麼位置開始寫入數據。
RandomAccessFile threadfile = new RandomAccessFile("QQWubiSetup.exe ","rwd");
threadfile.seek(2097152);//從文件的什麼位置開始寫入數據
程序結構以下圖所示:
string.xml文件中代碼:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">Android網絡多線程斷點下載</string>
<string name="path">下載路徑</string>
<string name="downloadbutton">下載</string>
<string name="sdcarderror">SDCard不存在或者寫保護</string>
<string name="success">下載完成</string>
<string name="error">下載失敗</string>
</resources>
main.xml文件中代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- 下載路徑 -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/path"/>
<EditText
android:id="@+id/path"
android:text="http://www.winrar.com.cn/download/wrar380sc.exe"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</EditText>
<!-- 下載按鈕 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/downloadbutton"
android:id="@+id/button"/>
<!-- 進度條 -->
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="20dip"
style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/downloadbar" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/resultView" />
</LinearLayout>
AndroidManifest.xml文件中代碼:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.downloader" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- 在SDCard中建立與刪除文件權限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard寫入數據權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 訪問internet權限 -->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
MainActivity中代碼:
package com.android.downloader;
import java.io.File;
import com.android.network.DownloadProgressListener;
import com.android.network.FileDownloader;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText downloadpathText;
private TextView resultView;
private ProgressBar progressBar;
/**
* 當Handler被建立會關聯到建立它的當前線程的消息隊列,該類用於往消息隊列發送消息
* 消息隊列中的消息由當前線程內部進行處理
*/
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
progressBar.setProgress(msg.getData().getInt("size"));
float num = (float)progressBar.getProgress()/(float)progressBar.getMax();
int result = (int)(num*100);
resultView.setText(result+ "%");
if(progressBar.getProgress()==progressBar.getMax()){
Toast.makeText(MainActivity.this, R.string.success, 1).show();
}
break;
case -1:
Toast.makeText(MainActivity.this, R.string.error, 1).show();
break;
}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
downloadpathText = (EditText) this.findViewById(R.id.path);
progressBar = (ProgressBar) this.findViewById(R.id.downloadbar);
resultView = (TextView) this.findViewById(R.id.resultView);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String path = downloadpathText.getText().toString();
System.out.println(Environment.getExternalStorageState()+"------"+Environment.MEDIA_MOUNTED);
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
download(path, Environment.getExternalStorageDirectory());
}else{
Toast.makeText(MainActivity.this, R.string.sdcarderror, 1).show();
}
}
});
}
/**
* 主線程(UI線程)
* 對於顯示控件的界面更新只是由UI線程負責,若是是在非UI線程更新控件的屬性值,更新後的顯示界面不會反映到屏幕上
* @param path
* @param savedir
*/
private void download(final String path, final File savedir) {
new Thread(new Runnable() {
@Override
public void run() {
FileDownloader loader = new FileDownloader(MainActivity.this, path, savedir, 3);
progressBar.setMax(loader.getFileSize());//設置進度條的最大刻度爲文件的長度
try {
loader.download(new DownloadProgressListener() {
@Override
public void onDownloadSize(int size) {//實時獲知文件已經下載的數據長度
Message msg = new Message();
msg.what = 1;
msg.getData().putInt("size", size);
handler.sendMessage(msg);//發送消息
}
});
} catch (Exception e) {
handler.obtainMessage(-1).sendToTarget();
}
}
}).start();
}
}
DBOpenHelper中代碼:
package com.android.service;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String DBNAME = "down.db";
private static final int VERSION = 1;
public DBOpenHelper(Context context) {
super(context, DBNAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS filedownlog (id integer primary key autoincrement, downpath varchar(100), threadid INTEGER, downlength INTEGER)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS filedownlog");
onCreate(db);
}
}
FileService中代碼:
package com.android.service;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class FileService {
private DBOpenHelper openHelper;
public FileService(Context context) {
openHelper = new DBOpenHelper(context);
}
/**
* 獲取每條線程已經下載的文件長度
* @param path
* @return
*/
public Map<Integer, Integer> getData(String path){
SQLiteDatabase db = openHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select threadid, downlength from filedownlog where downpath=?", new String[]{path});
Map<Integer, Integer> data = new HashMap<Integer, Integer>();
while(cursor.moveToNext()){
data.put(cursor.getInt(0), cursor.getInt(1));
}
cursor.close();
db.close();
return data;
}
/**
* 保存每條線程已經下載的文件長度
* @param path
* @param map
*/
public void save(String path, Map<Integer, Integer> map){//int threadid, int position
SQLiteDatabase db = openHelper.getWritableDatabase();
db.beginTransaction();
try{
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
db.execSQL("insert into filedownlog(downpath, threadid, downlength) values(?,?,?)",
new Object[]{path, entry.getKey(), entry.getValue()});
}
db.setTransactionSuccessful();
}finally{
db.endTransaction();
}
db.close();
}
/**
* 實時更新每條線程已經下載的文件長度
* @param path
* @param map
*/
public void update(String path, Map<Integer, Integer> map){
SQLiteDatabase db = openHelper.getWritableDatabase();
db.beginTransaction();
try{
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
db.execSQL("update filedownlog set downlength=? where downpath=? and threadid=?",
new Object[]{entry.getValue(), path, entry.getKey()});
}
db.setTransactionSuccessful();
}finally{
db.endTransaction();
}
db.close();
}
/**
* 當文件下載完成後,刪除對應的下載記錄
* @param path
*/
public void delete(String path){
SQLiteDatabase db = openHelper.getWritableDatabase();
db.execSQL("delete from filedownlog where downpath=?", new Object[]{path});
db.close();
}
}
DownloadProgressListener中代碼:
package com.android.network;
public interface DownloadProgressListener {
public void onDownloadSize(int size);
}
FileDownloader中代碼:
package com.android.network;
import java.io.File;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.android.service.FileService;
import android.content.Context;
import android.util.Log;
public class FileDownloader {
private static final String TAG = "FileDownloader";
private Context context;
private FileService fileService;
/* 已下載文件長度 */
private int downloadSize = 0;
/* 原始文件長度 */
private int fileSize = 0;
/* 線程數 */
private DownloadThread[] threads;
/* 本地保存文件 */
private File saveFile;
/* 緩存各線程下載的長度*/
private Map<Integer, Integer> data = new ConcurrentHashMap<Integer, Integer>();
/* 每條線程下載的長度 */
private int block;
/* 下載路徑 */
private String downloadUrl;
/**
* 獲取線程數
*/
public int getThreadSize() {
return threads.length;
}
/**
* 獲取文件大小
* @return
*/
public int getFileSize() {
return fileSize;
}
/**
* 累計已下載大小
* @param size
*/
protected synchronized void append(int size) {
downloadSize += size;
}
/**
* 更新指定線程最後下載的位置
* @param threadId 線程id
* @param pos 最後下載的位置
*/
protected synchronized void update(int threadId, int pos) {
this.data.put(threadId, pos);
this.fileService.update(this.downloadUrl, this.data);
}
/**
* 構建文件下載器
* @param downloadUrl 下載路徑
* @param fileSaveDir 文件保存目錄
* @param threadNum 下載線程數
*/
public FileDownloader(Context context, String downloadUrl, File fileSaveDir, int threadNum) {
try {
this.context = context;
this.downloadUrl = downloadUrl;
fileService = new FileService(this.context);
URL url = new URL(this.downloadUrl);
if(!fileSaveDir.exists()) fileSaveDir.mkdirs();
this.threads = new DownloadThread[threadNum];
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5*1000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Referer", downloadUrl);
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
printResponseHeader(conn);
if (conn.getResponseCode()==200) {
this.fileSize = conn.getContentLength();//根據響應獲取文件大小
if (this.fileSize <= 0) throw new RuntimeException("Unkown file size ");
String filename = getFileName(conn);//獲取文件名稱
this.saveFile = new File(fileSaveDir, filename);//構建保存文件
Map<Integer, Integer> logdata = fileService.getData(downloadUrl);//獲取下載記錄
if(logdata.size()>0){//若是存在下載記錄
for(Map.Entry<Integer, Integer> entry : logdata.entrySet())
data.put(entry.getKey(), entry.getValue());//把各條線程已經下載的數據長度放入data中
}
if(this.data.size()==this.threads.length){//下面計算全部線程已經下載的數據長度
for (int i = 0; i < this.threads.length; i++) {
this.downloadSize += this.data.get(i+1);
}
print("已經下載的長度"+ this.downloadSize);
}
//計算每條線程下載的數據長度
this.block = (this.fileSize % this.threads.length)==0? this.fileSize / this.threads.length : this.fileSize / this.threads.length + 1;
}else{
throw new RuntimeException("server no response ");
}
} catch (Exception e) {
print(e.toString());
throw new RuntimeException("don't connection this url");
}
}
/**
* 獲取文件名
* @param conn
* @return
*/
private String getFileName(HttpURLConnection conn) {
String filename = this.downloadUrl.substring(this.downloadUrl.lastIndexOf('/') + 1);
if(filename==null || "".equals(filename.trim())){//若是獲取不到文件名稱
for (int i = 0;; i++) {
String mine = conn.getHeaderField(i);
if (mine == null) break;
if("content-disposition".equals(conn.getHeaderFieldKey(i).toLowerCase())){
Matcher m = Pattern.compile(".*filename=(.*)").matcher(mine.toLowerCase());
if(m.find()) return m.group(1);
}
}
filename = UUID.randomUUID()+ ".tmp";//默認取一個文件名
}
return filename;
}
/**
* 開始下載文件
* @param listener 監聽下載數量的變化,若是不須要了解實時下載的數量,能夠設置爲null
* @return 已下載文件大小
* @throws Exception
*/
public int download(DownloadProgressListener listener) throws Exception{
try {
RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rw");
if(this.fileSize>0) randOut.setLength(this.fileSize);
randOut.close();
URL url = new URL(this.downloadUrl);
if(this.data.size() != this.threads.length){
this.data.clear();
for (int i = 0; i < this.threads.length; i++) {
this.data.put(i+1, 0);//初始化每條線程已經下載的數據長度爲0
}
}
for (int i = 0; i < this.threads.length; i++) {//開啓線程進行下載
int downLength = this.data.get(i+1);
if(downLength < this.block && this.downloadSize<this.fileSize){//判斷線程是否已經完成下載,不然繼續下載
this.threads[i] = new DownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);
this.threads[i].setPriority(7);
this.threads[i].start();
}else{
this.threads[i] = null;
}
}
this.fileService.save(this.downloadUrl, this.data);
boolean notFinish = true;//下載未完成
while (notFinish) {// 循環判斷全部線程是否完成下載
Thread.sleep(900);
notFinish = false;//假定所有線程下載完成
for (int i = 0; i < this.threads.length; i++){
if (this.threads[i] != null && !this.threads[i].isFinish()) {//若是發現線程未完成下載
notFinish = true;//設置標誌爲下載沒有完成
if(this.threads[i].getDownLength() == -1){//若是下載失敗,再從新下載
this.threads[i] = new DownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);
this.threads[i].setPriority(7);
this.threads[i].start();
}
}
}
if(listener!=null) listener.onDownloadSize(this.downloadSize);//通知目前已經下載完成的數據長度
}
fileService.delete(this.downloadUrl);
} catch (Exception e) {
print(e.toString());
throw new Exception("file download fail");
}
return this.downloadSize;
}
/**
* 獲取Http響應頭字段
* @param http
* @return
*/
public static Map<String, String> getHttpResponseHeader(HttpURLConnection http) {
Map<String, String> header = new LinkedHashMap<String, String>();
for (int i = 0;; i++) {
String mine = http.getHeaderField(i);
if (mine == null) break;
header.put(http.getHeaderFieldKey(i), mine);
}
return header;
}
/**
* 打印Http頭字段
* @param http
*/
public static void printResponseHeader(HttpURLConnection http){
Map<String, String> header = getHttpResponseHeader(http);
for(Map.Entry<String, String> entry : header.entrySet()){
String key = entry.getKey()!=null ? entry.getKey()+ ":" : "";
print(key+ entry.getValue());
}
}
private static void print(String msg){
Log.i(TAG, msg);
}
}
DownloadThread 中代碼:
package com.android.network;
import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import android.util.Log;
public class DownloadThread extends Thread {
private static final String TAG = "DownloadThread";
private File saveFile;
private URL downUrl;
private int block;
/* 下載開始位置 */
private int threadId = -1;
private int downLength;
private boolean finish = false;
private FileDownloader downloader;
public DownloadThread(FileDownloader downloader, URL downUrl, File saveFile, int block, int downLength, int threadId) {
this.downUrl = downUrl;
this.saveFile = saveFile;
this.block = block;
this.downloader = downloader;
this.threadId = threadId;
this.downLength = downLength;
}
@Override
public void run() {
if(downLength < block){//未下載完成
try {
HttpURLConnection http = (HttpURLConnection) downUrl.openConnection();
http.setConnectTimeout(5 * 1000);
http.setRequestMethod("GET");
http.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
http.setRequestProperty("Accept-Language", "zh-CN");
http.setRequestProperty("Referer", downUrl.toString());
http.setRequestProperty("Charset", "UTF-8");
int startPos = block * (threadId - 1) + downLength;//開始位置
int endPos = block * threadId -1;//結束位置
http.setRequestProperty("Range", "bytes=" + startPos + "-"+ endPos);//設置獲取實體數據的範圍
http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
http.setRequestProperty("Connection", "Keep-Alive");
InputStream inStream = http.getInputStream();
byte[] buffer = new byte[1024];
int offset = 0;
print("Thread " + this.threadId + " start download from position "+ startPos);
RandomAccessFile threadfile = new RandomAccessFile(this.saveFile, "rwd");
threadfile.seek(startPos);
while ((offset = inStream.read(buffer, 0, 1024)) != -1) {
threadfile.write(buffer, 0, offset);
downLength += offset;
downloader.update(this.threadId, downLength);
downloader.append(offset);
}
threadfile.close();
inStream.close();
print("Thread " + this.threadId + " download finish");
this.finish = true;
} catch (Exception e) {
this.downLength = -1;
print("Thread "+ this.threadId+ ":"+ e);
}
}
}
private static void print(String msg){
Log.i(TAG, msg);
}
/**
* 下載是否完成
* @return
*/
public boolean isFinish() {
return finish;
}
/**
* 已經下載的內容大小
* @return 若是返回值爲-1,表明下載失敗
*/
public long getDownLength() {
return downLength;
}
}
運行效果以下:
版權聲明:本文爲博主原創文章,未經博主容許不得轉載。
17、Android手機操做系統已經出現就受到了用戶的好評。各大手機廠商也開始利用這一開源的系統抓住商機,發展本身的產業。在這裏先來了解一下這一操做系統的一個小技巧,有關Android顯示網絡圖片的實現。
在Android中顯示一張網絡圖片實際上是超級簡單的,下面就一個很是簡單的例子:
Android顯示網絡圖片Step1:
一、建立你的Activity,本例中以ViewWebImageActivity說明;
二、ViewWebImageActivity中的代碼以下:
[java] view plaincopy
三、其中,returnBitMap(String url) 方法就是具體實現網絡圖片轉換成bitmap。
Android顯示網絡圖片Step2:
一、修改你的main.xml文件以下:
[java] view plaincopy
Android顯示網絡圖片Step3:
在你的AndroidManifest.xml文件的< /manifest>節點上面添加< uses-permission android:name="android.permission.INTERNET" />,這是因爲Android有不少的權限限制,不然圖片是不能在你的模擬器上顯示的
18、android
[java] view plaincopy
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1)判斷是否有網絡鏈接
[java] view plaincopy
2)判斷WIFI網絡是否可用
[java] view plaincopy
3)判斷MOBILE網絡是否可用
[java] view plaincopy
4)獲取當前網絡鏈接的類型信息
[java] view plaincopy
在開發android應用時,涉及到要進行網絡訪問,時常須要進行網絡狀態的檢查,以提供給用戶必要的提醒。通常能夠經過ConnectivityManager來完成該工做。
ConnectivityManager有四個主要任務:
1、監聽手機網絡狀態(包括GPRS,WIFI, UMTS等)
2、手機狀態發生改變時,發送廣播
3、當一個網絡鏈接失敗時進行故障切換
4、爲應用程序提供能夠獲取可用網絡的高精度和粗糙的狀態
當咱們要在程序中監聽網絡狀態時,只要一下幾個步驟便可:
1、定義一個Receiver重載其中的onReceive函數,在其中完成所須要的功能,如根據WIFI和GPRS是否斷開來改變空間的外觀
[java] view plaincopy
2、在適當的地方註冊Receiver,能夠在程序中註冊,在onCreate中調用以下函數便可:
[java] view plaincopy
3、在適當時取消註冊Receiver,能夠在程序中取消,在onDestroye中調用以下函數便可:
[java] view plaincopy
Ps:網上還有不少關於使用TelephonyManager 的方法的,方法以下(可是我試了好幾回都有問題,如每次第一次進入一個Activity時會自動收到網絡斷開的信號,每次網絡狀態改變時收到屢次回調且狀態不正確。不知道有什麼要注意的地方,求指點!)
[java] view plaincopy
至於第二種方法,本人並無去嘗試過。第一種方式仍是比較好用,若是要程序隱藏在後臺的話,建議開個service,將BroadcastReceiver註冊在service,但不要忘了取消註冊。
在測試中遇到過這樣的情況,將一個當前鏈接wifi的路由設備關閉,可是程序並無捕捉到unconnect network,多是由於手機設備馬上鍊接另外一個路由設備了
Android 監控網絡狀態
[java] view plaincopy
上面這個方法就是判斷網絡是否鏈接的代碼,返回true表示有網絡,返回false表示無網絡。 在Android網絡應用程序開發中,常常要判斷網絡鏈接是否可用,所以常常有必要監聽網絡狀態的變化。android的網絡狀態監聽能夠用BroadcastReceiver來接收網絡狀態改變的廣 播,具體實現以下
[java] view plaincopy
[java] view plaincopy
不少朋友在android開發中,都會遇到手機網絡類型判斷,由於就目前的android平臺手機來講:可能會存在4中狀態
1.無網絡(這種狀態多是由於手機停機,網絡沒有開啓,信號很差等緣由)
2.使用WIFI上網
3.CMWAP(中國移動代理)
4.CMNET上網
這四種狀態,若是沒有網絡,確定是沒法請求Internet了,若是是wap就須要爲手機添加中國移動代理,關於爲手機添加中國移動的代理!
下面是網絡判斷的方法:
[java] view plaincopy