編輯:關於Android編程
本文實例講述了Android實現Service獲取當前位置(GPS+基站)的方法。分享給大家供大家參考。具體如下:
需求詳情:
1)、Service中每隔1秒執行一次定位操作(GPS+基站)
2)、定位的結果實時顯示在界面上(要求得到經度、緯度)
技術支持:
1)、獲取經緯度
通過GPS+基站獲取經緯度,先通過GPS來獲取,如果為空改用基站進行獲取–>GPS+基站(基站獲取支持聯通、電信、移動)。
2)、實時獲取經緯度
為了達到實時獲取經緯度,需在後台啟動獲取經緯度的Service,然後把經緯度數據通過廣播發送出去,在需要的地方進行廣播注冊(比如在Activity中注冊廣播,顯示在界面中)–>涉及到Service+BroadcastReceiver+Activity+Thread等知識點。
備注:本文注重實踐,如有看不懂的,先去鞏固下知識點,可以去看看前面相關的幾篇文章。
1、CellInfo實體類–>基站信息
package com.ljq.activity; /** * 基站信息 * * @author jiqinlin * */ public class CellInfo { /** 基站id,用來找到基站的位置 */ private int cellId; /** 移動國家碼,共3位,中國為460,即imsi前3位 */ private String mobileCountryCode="460"; /** 移動網絡碼,共2位,在中國,移動的代碼為00和02,聯通的代碼為01,電信的代碼為03,即imsi第4~5位 */ private String mobileNetworkCode="0"; /** 地區區域碼 */ private int locationAreaCode; /** 信號類型[選 gsm|cdma|wcdma] */ private String radioType=""; public CellInfo() { } public int getCellId() { return cellId; } public void setCellId(int cellId) { this.cellId = cellId; } public String getMobileCountryCode() { return mobileCountryCode; } public void setMobileCountryCode(String mobileCountryCode) { this.mobileCountryCode = mobileCountryCode; } public String getMobileNetworkCode() { return mobileNetworkCode; } public void setMobileNetworkCode(String mobileNetworkCode) { this.mobileNetworkCode = mobileNetworkCode; } public int getLocationAreaCode() { return locationAreaCode; } public void setLocationAreaCode(int locationAreaCode) { this.locationAreaCode = locationAreaCode; } public String getRadioType() { return radioType; } public void setRadioType(String radioType) { this.radioType = radioType; } }
2、Gps類–>Gps封裝類,用來獲取經緯度
package com.ljq.activity; import android.content.Context; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; public class Gps{ private Location location = null; private LocationManager locationManager = null; private Context context = null; /** * 初始化 * * @param ctx */ public Gps(Context ctx) { context=ctx; locationManager=(LocationManager)context.getSystemService(Context.LOCATION_SERVICE); location = locationManager.getLastKnownLocation(getProvider()); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener); } // 獲取Location Provider private String getProvider() { // 構建位置查詢條件 Criteria criteria = new Criteria(); // 查詢精度:高 criteria.setAccuracy(Criteria.ACCURACY_FINE); // 是否查詢海撥:否 criteria.setAltitudeRequired(false); // 是否查詢方位角 : 否 criteria.setBearingRequired(false); // 是否允許付費:是 criteria.setCostAllowed(true); // 電量要求:低 criteria.setPowerRequirement(Criteria.POWER_LOW); // 返回最合適的符合條件的provider,第2個參數為true說明 , 如果只有一個provider是有效的,則返回當前provider return locationManager.getBestProvider(criteria, true); } private LocationListener locationListener = new LocationListener() { // 位置發生改變後調用 public void onLocationChanged(Location l) { if(l!=null){ location=l; } } // provider 被用戶關閉後調用 public void onProviderDisabled(String provider) { location=null; } // provider 被用戶開啟後調用 public void onProviderEnabled(String provider) { Location l = locationManager.getLastKnownLocation(provider); if(l!=null){ location=l; } } // provider 狀態變化時調用 public void onStatusChanged(String provider, int status, Bundle extras) { } }; public Location getLocation(){ return location; } public void closeLocation(){ if(locationManager!=null){ if(locationListener!=null){ locationManager.removeUpdates(locationListener); locationListener=null; } locationManager=null; } } }
3、GpsService服務類
package com.ljq.activity; import java.util.ArrayList; import android.app.Service; import android.content.Intent; import android.location.Location; import android.os.IBinder; import android.util.Log; public class GpsService extends Service { ArrayList<CellInfo> cellIds = null; private Gps gps=null; private boolean threadDisable=false; private final static String TAG=GpsService.class.getSimpleName(); @Override public void onCreate() { super.onCreate(); gps=new Gps(GpsService.this); cellIds=UtilTool.init(GpsService.this); new Thread(new Runnable(){ @Override public void run() { while (!threadDisable) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if(gps!=null){ //當結束服務時gps為空 //獲取經緯度 Location location=gps.getLocation(); //如果gps無法獲取經緯度,改用基站定位獲取 if(location==null){ Log.v(TAG, "gps location null"); //2.根據基站信息獲取經緯度 try { location = UtilTool.callGear(GpsService.this, cellIds); } catch (Exception e) { location=null; e.printStackTrace(); } if(location==null){ Log.v(TAG, "cell location null"); } } //發送廣播 Intent intent=new Intent(); intent.putExtra("lat", location==null?"":location.getLatitude()+""); intent.putExtra("lon", location==null?"":location.getLongitude()+""); intent.setAction("com.ljq.activity.GpsService"); sendBroadcast(intent); } } } }).start(); } @Override public void onDestroy() { threadDisable=true; if(cellIds!=null&&cellIds.size()>0){ cellIds=null; } if(gps!=null){ gps.closeLocation(); gps=null; } super.onDestroy(); } @Override public IBinder onBind(Intent arg0) { return null; } }
4、GpsActivity–>在界面上實時顯示經緯度數據
package com.ljq.activity; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; import android.widget.EditText; import android.widget.Toast; public class GpsActivity extends Activity { private Double homeLat=26.0673834d; //宿捨緯度 private Double homeLon=119.3119936d; //宿捨經度 private EditText editText = null; private MyReceiver receiver=null; private final static String TAG=GpsActivity.class.getSimpleName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); editText=(EditText)findViewById(R.id.editText); //判斷GPS是否可用 Log.i(TAG, UtilTool.isGpsEnabled((LocationManager)getSystemService(Context.LOCATION_SERVICE))+""); if(!UtilTool.isGpsEnabled((LocationManager)getSystemService(Context.LOCATION_SERVICE))){ Toast.makeText(this, "GSP當前已禁用,請在您的系統設置屏幕啟動。", Toast.LENGTH_LONG).show(); Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(callGPSSettingIntent); return; } //啟動服務 startService(new Intent(this, GpsService.class)); //注冊廣播 receiver=new MyReceiver(); IntentFilter filter=new IntentFilter(); filter.addAction("com.ljq.activity.GpsService"); registerReceiver(receiver, filter); } //獲取廣播數據 private class MyReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Bundle bundle=intent.getExtras(); String lon=bundle.getString("lon"); String lat=bundle.getString("lat"); if(lon!=null&&!"".equals(lon)&&lat!=null&&!"".equals(lat)){ double distance=getDistance(Double.parseDouble(lat), Double.parseDouble(lon), homeLat, homeLon); editText.setText("目前經緯度\n經度:"+lon+"\n緯度:"+lat+"\n離宿捨距離:"+java.lang.Math.abs(distance)); }else{ editText.setText("目前經緯度\n經度:"+lon+"\n緯度:"+lat); } } } @Override protected void onDestroy() { //注銷服務 unregisterReceiver(receiver); //結束服務,如果想讓服務一直運行就注銷此句 stopService(new Intent(this, GpsService.class)); super.onDestroy(); } /** * 把經緯度換算成距離 * * @param lat1 開始緯度 * @param lon1 開始經度 * @param lat2 結束緯度 * @param lon2 結束經度 * @return */ private double getDistance(double lat1, double lon1, double lat2, double lon2) { float[] results = new float[1]; Location.distanceBetween(lat1, lon1, lat2, lon2, results); return results[0]; } }
5、UtilTool–>工具類
package com.ljq.activity; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Locale; import org.apache.http.client.ClientProtocolException; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.location.Location; import android.location.LocationManager; import android.telephony.NeighboringCellInfo; import android.telephony.TelephonyManager; import android.telephony.cdma.CdmaCellLocation; import android.telephony.gsm.GsmCellLocation; import android.util.Log; import android.widget.Toast; public class UtilTool { public static boolean isGpsEnabled(LocationManager locationManager) { boolean isOpenGPS = locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER); boolean isOpenNetwork = locationManager.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER); if (isOpenGPS || isOpenNetwork) { return true; } return false; } /** * 根據基站信息獲取經緯度 * * 原理向http://www.google.com/loc/json發送http的post請求,根據google返回的結果獲取經緯度 * * @param cellIds * @return * @throws Exception */ public static Location callGear(Context ctx, ArrayList<CellInfo> cellIds) throws Exception { String result=""; JSONObject data=null; if (cellIds == null||cellIds.size()==0) { UtilTool.alert(ctx, "cell request param null"); return null; }; try { result = UtilTool.getResponseResult(ctx, "http://www.google.com/loc/json", cellIds); if(result.length() <= 1) return null; data = new JSONObject(result); data = (JSONObject) data.get("location"); Location loc = new Location(LocationManager.NETWORK_PROVIDER); loc.setLatitude((Double) data.get("latitude")); loc.setLongitude((Double) data.get("longitude")); loc.setAccuracy(Float.parseFloat(data.get("accuracy").toString())); loc.setTime(UtilTool.getUTCTime()); return loc; } catch (JSONException e) { return null; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 接收Google返回的數據格式 * * 出參:{"location":{"latitude":26.0673834,"longitude":119.3119936, * "address":{"country":"ä¸å½","country_code":"CN","region":"ç¦å»ºç","city":"ç¦å·å¸", * "street":"äºä¸ä¸è·¯","street_number":"128å·"},"accuracy":935.0}, * "access_token":"2:xiU8YrSifFHUAvRJ:aj9k70VJMRWo_9_G"} * 請求路徑:http://maps.google.cn/maps/geo?key=abcdefg&q=26.0673834,119.3119936 * * @param cellIds * @return * @throws UnsupportedEncodingException * @throws MalformedURLException * @throws IOException * @throws ProtocolException * @throws Exception */ public static String getResponseResult(Context ctx,String path, ArrayList<CellInfo> cellInfos) throws UnsupportedEncodingException, MalformedURLException, IOException, ProtocolException, Exception { String result=""; Log.i(ctx.getApplicationContext().getClass().getSimpleName(), "in param: "+getRequestParams(cellInfos)); InputStream inStream=UtilTool.sendPostRequest(path, getRequestParams(cellInfos), "UTF-8"); if(inStream!=null){ byte[] datas=UtilTool.readInputStream(inStream); if(datas!=null&&datas.length>0){ result=new String(datas, "UTF-8"); //Log.i(ctx.getClass().getSimpleName(), "receive result:"+result);//服務器返回的結果信息 Log.i(ctx.getApplicationContext().getClass().getSimpleName(), "google cell receive data result:"+result); }else{ Log.i(ctx.getApplicationContext().getClass().getSimpleName(), "google cell receive data null"); } }else{ Log.i(ctx.getApplicationContext().getClass().getSimpleName(), "google cell receive inStream null"); } return result; } /** * 拼裝json請求參數,拼裝基站信息 * * 入參:{'version': '1.1.0','host': 'maps.google.com','home_mobile_country_code': 460, * 'home_mobile_network_code': 14136,'radio_type': 'cdma','request_address': true, * 'address_language': 'zh_CN','cell_towers':[{'cell_id': '12835','location_area_code': 6, * 'mobile_country_code': 460,'mobile_network_code': 14136,'age': 0}]} * @param cellInfos * @return */ public static String getRequestParams(List<CellInfo> cellInfos){ StringBuffer sb=new StringBuffer(""); sb.append("{"); if(cellInfos!=null&&cellInfos.size()>0){ sb.append("'version': '1.1.0',"); //google api 版本[必] sb.append("'host': 'maps.google.com',"); //服務器域名[必] sb.append("'home_mobile_country_code': "+cellInfos.get(0).getMobileCountryCode()+","); //移動用戶所屬國家代號[選 中國460] sb.append("'home_mobile_network_code': "+cellInfos.get(0).getMobileNetworkCode()+","); //移動系統號碼[默認0] sb.append("'radio_type': '"+cellInfos.get(0).getRadioType()+"',"); //信號類型[選 gsm|cdma|wcdma] sb.append("'request_address': true,"); //是否返回數據[必] sb.append("'address_language': 'zh_CN',"); //反饋數據語言[選 中國 zh_CN] sb.append("'cell_towers':["); //移動基站參數對象[必] for(CellInfo cellInfo:cellInfos){ sb.append("{"); sb.append("'cell_id': '"+cellInfo.getCellId()+"',"); //基站ID[必] sb.append("'location_area_code': "+cellInfo.getLocationAreaCode()+","); //地區區域碼[必] sb.append("'mobile_country_code': "+cellInfo.getMobileCountryCode()+","); sb.append("'mobile_network_code': "+cellInfo.getMobileNetworkCode()+","); sb.append("'age': 0"); //使用好久的數據庫[選 默認0表示使用最新的數據庫] sb.append("},"); } sb.deleteCharAt(sb.length()-1); sb.append("]"); } sb.append("}"); return sb.toString(); } /** * 獲取UTC時間 * * UTC + 時區差 = 本地時間(北京為東八區) * * @return */ public static long getUTCTime() { //取得本地時間 Calendar cal = Calendar.getInstance(Locale.CHINA); //取得時間偏移量 int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET); //取得夏令時差 int dstOffset = cal.get(java.util.Calendar.DST_OFFSET); //從本地時間裡扣除這些差量,即可以取得UTC時間 cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset)); return cal.getTimeInMillis(); } /** * 初始化,記得放在onCreate()方法裡初始化,獲取基站信息 * * @return */ public static ArrayList<CellInfo> init(Context ctx) { ArrayList<CellInfo> cellInfos = new ArrayList<CellInfo>(); TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE); //網絡制式 int type = tm.getNetworkType(); /** * 獲取SIM卡的IMSI碼 * SIM卡唯一標識:IMSI 國際移動用戶識別碼(IMSI:International Mobile Subscriber Identification Number)是區別移動用戶的標志, * 儲存在SIM卡中,可用於區別移動用戶的有效信息。IMSI由MCC、MNC、MSIN組成,其中MCC為移動國家號碼,由3位數字組成, * 唯一地識別移動客戶所屬的國家,我國為460;MNC為網絡id,由2位數字組成, * 用於識別移動客戶所歸屬的移動網絡,中國移動為00,中國聯通為01,中國電信為03;MSIN為移動客戶識別碼,采用等長11位數字構成。 * 唯一地識別國內GSM移動通信網中移動客戶。所以要區分是移動還是聯通,只需取得SIM卡中的MNC字段即可 */ String imsi = tm.getSubscriberId(); alert(ctx, "imsi: "+imsi); //為了區分移動、聯通還是電信,推薦使用imsi來判斷(萬不得己的情況下用getNetworkType()判斷,比如imsi為空時) if(imsi!=null&&!"".equals(imsi)){ alert(ctx, "imsi"); if (imsi.startsWith("46000") || imsi.startsWith("46002")) {// 因為移動網絡編號46000下的IMSI已經用完,所以虛擬了一個46002編號,134/159號段使用了此編號 // 中國移動 mobile(cellInfos, tm); } else if (imsi.startsWith("46001")) { // 中國聯通 union(cellInfos, tm); } else if (imsi.startsWith("46003")) { // 中國電信 cdma(cellInfos, tm); } }else{ alert(ctx, "type"); // 在中國,聯通的3G為UMTS或HSDPA,電信的3G為EVDO // 在中國,移動的2G是EGDE,聯通的2G為GPRS,電信的2G為CDMA // String OperatorName = tm.getNetworkOperatorName(); //中國電信 if (type == TelephonyManager.NETWORK_TYPE_EVDO_A || type == TelephonyManager.NETWORK_TYPE_EVDO_0 || type == TelephonyManager.NETWORK_TYPE_CDMA || type ==TelephonyManager.NETWORK_TYPE_1xRTT){ cdma(cellInfos, tm); } //移動(EDGE(2.75G)是GPRS(2.5G)的升級版,速度比GPRS要快。目前移動基本在國內升級普及EDGE,聯通則在大城市部署EDGE。) else if(type == TelephonyManager.NETWORK_TYPE_EDGE || type == TelephonyManager.NETWORK_TYPE_GPRS ){ mobile(cellInfos, tm); } //聯通(EDGE(2.75G)是GPRS(2.5G)的升級版,速度比GPRS要快。目前移動基本在國內升級普及EDGE,聯通則在大城市部署EDGE。) else if(type == TelephonyManager.NETWORK_TYPE_GPRS ||type == TelephonyManager.NETWORK_TYPE_EDGE ||type == TelephonyManager.NETWORK_TYPE_UMTS ||type == TelephonyManager.NETWORK_TYPE_HSDPA){ union(cellInfos, tm); } } return cellInfos; } /** * 電信 * * @param cellInfos * @param tm */ private static void cdma(ArrayList<CellInfo> cellInfos, TelephonyManager tm) { CdmaCellLocation location = (CdmaCellLocation) tm.getCellLocation(); CellInfo info = new CellInfo(); info.setCellId(location.getBaseStationId()); info.setLocationAreaCode(location.getNetworkId()); info.setMobileNetworkCode(String.valueOf(location.getSystemId())); info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3)); info.setRadioType("cdma"); cellInfos.add(info); //前面獲取到的都是單個基站的信息,接下來再獲取周圍鄰近基站信息以輔助通過基站定位的精准性 // 獲得鄰近基站信息 List<NeighboringCellInfo> list = tm.getNeighboringCellInfo(); int size = list.size(); for (int i = 0; i < size; i++) { CellInfo cell = new CellInfo(); cell.setCellId(list.get(i).getCid()); cell.setLocationAreaCode(location.getNetworkId()); cell.setMobileNetworkCode(String.valueOf(location.getSystemId())); cell.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3)); cell.setRadioType("cdma"); cellInfos.add(cell); } } /** * 移動 * * @param cellInfos * @param tm */ private static void mobile(ArrayList<CellInfo> cellInfos, TelephonyManager tm) { GsmCellLocation location = (GsmCellLocation)tm.getCellLocation(); CellInfo info = new CellInfo(); info.setCellId(location.getCid()); info.setLocationAreaCode(location.getLac()); info.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5)); info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3)); info.setRadioType("gsm"); cellInfos.add(info); //前面獲取到的都是單個基站的信息,接下來再獲取周圍鄰近基站信息以輔助通過基站定位的精准性 // 獲得鄰近基站信息 List<NeighboringCellInfo> list = tm.getNeighboringCellInfo(); int size = list.size(); for (int i = 0; i < size; i++) { CellInfo cell = new CellInfo(); cell.setCellId(list.get(i).getCid()); cell.setLocationAreaCode(location.getLac()); cell.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5)); cell.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3)); cell.setRadioType("gsm"); cellInfos.add(cell); } } /** * 聯通 * * @param cellInfos * @param tm */ private static void union(ArrayList<CellInfo> cellInfos, TelephonyManager tm) { GsmCellLocation location = (GsmCellLocation)tm.getCellLocation(); CellInfo info = new CellInfo(); //經過測試,獲取聯通數據以下兩行必須去掉,否則會出現錯誤,錯誤類型為JSON Parsing Error //info.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5)); //info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3)); info.setCellId(location.getCid()); info.setLocationAreaCode(location.getLac()); info.setMobileNetworkCode(""); info.setMobileCountryCode(""); info.setRadioType("gsm"); cellInfos.add(info); //前面獲取到的都是單個基站的信息,接下來再獲取周圍鄰近基站信息以輔助通過基站定位的精准性 // 獲得鄰近基站信息 List<NeighboringCellInfo> list = tm.getNeighboringCellInfo(); int size = list.size(); for (int i = 0; i < size; i++) { CellInfo cell = new CellInfo(); cell.setCellId(list.get(i).getCid()); cell.setLocationAreaCode(location.getLac()); cell.setMobileNetworkCode(""); cell.setMobileCountryCode(""); cell.setRadioType("gsm"); cellInfos.add(cell); } } /** * 提示 * * @param ctx * @param msg */ public static void alert(Context ctx,String msg){ Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show(); } /** * 發送post請求,返回輸入流 * * @param path 訪問路徑 * @param params json數據格式 * @param encoding 編碼 * @return * @throws UnsupportedEncodingException * @throws MalformedURLException * @throws IOException * @throws ProtocolException */ public static InputStream sendPostRequest(String path, String params, String encoding) throws UnsupportedEncodingException, MalformedURLException, IOException, ProtocolException { byte[] data = params.getBytes(encoding); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); //application/x-javascript text/xml->xml數據 application/x-javascript->json對象 application/x-www-form-urlencoded->表單數據 conn.setRequestProperty("Content-Type", "application/x-javascript; charset="+ encoding); conn.setRequestProperty("Content-Length", String.valueOf(data.length)); conn.setConnectTimeout(5 * 1000); OutputStream outStream = conn.getOutputStream(); outStream.write(data); outStream.flush(); outStream.close(); if(conn.getResponseCode()==200) return conn.getInputStream(); return null; } /** * 發送get請求 * * @param path 請求路徑 * @return * @throws Exception */ public static String sendGetRequest(String path) throws Exception { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); InputStream inStream = conn.getInputStream(); byte[] data = readInputStream(inStream); String result = new String(data, "UTF-8"); return result; } /** * 從輸入流中讀取數據 * @param inStream * @return * @throws Exception */ public static byte[] readInputStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while( (len = inStream.read(buffer)) !=-1 ){ outStream.write(buffer, 0, len); } byte[] data = outStream.toByteArray();//網頁的二進制數據 outStream.close(); inStream.close(); return data; } }
6、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"> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:cursorVisible="false" android:editable="false" android:id="@+id/editText"/> </LinearLayout>
7、清單文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ljq.activity" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".GpsActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:label="GPS服務" android:name=".GpsService" /> </application> <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> </manifest>
效果如下:
希望本文所述對大家的Android程序設計有所幫助。
Android應用程序內存洩漏介紹內存洩漏和內存溢出的區別內存溢出(out of memory)是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of mem
Android的待機狀態管理由PowerManagerService.java管理主要的狀態更新方法在下面貼出代碼, 注釋寫的很清楚, 第一次看系統源碼感覺還比較爽主要是
要想實現android手機通過掃描名片,得到名片信息,可以使用脈可尋提供的第三方SDK,即Maketion ScanCard SDK,脈可尋雲名片識別服務。他們的官方網站
遇到的問題如下:java.lang.NullPointerException: Attempt to invoke virtual method ‘void