android基站定位程序獲取地理位置

目錄

1、設置界面html

2、爲按鈕綁定事件java

3、獲取基站信息android

4、獲取經緯度git

5、獲取物理位置算法

6、顯示結果數據庫

7、運行程序apache

8、總結json

9、程序代碼api

正文

在Android操做系統下,基站定位其實很簡單,先說一下實現流程:安全

調用SDK中的API(TelephonyManager)得到MCC、MNC、LAC、CID等信息,而後經過google的API得到所在位置的經緯度,最後再經過google map的API得到實際的地理位置。(google真牛!)

有同窗會問:MNC、MCC、LAC、CID都是些什麼東西?google又怎麼經過這些東西就得到經緯度了呢?

咱們一塊兒來學習一下:

MCC,Mobile Country Code,移動國家代碼(中國的爲460);

MNC,Mobile Network Code,移動網絡號碼(中國移動爲00,中國聯通爲01);

LAC,Location Area Code,位置區域碼;

CID,Cell Identity,基站編號,是個16位的數據(範圍是0到65535)。

瞭解了這幾個名詞的意思,相信有些朋友已經知道後面的事了:google存儲了這些信息,直接查詢就能獲得經緯度了。(至於google怎麼獲得移動、聯通的基站信息,這就不得而知了,反正google免費提供接口,直接調用就是)

下面開始動手。

1、設置界面

咱們在上一節的程序的基礎上進行開發,在DemoActivity的界面上實現這個功能。(沒有代碼的同窗可點擊這裏下載,感謝yuejianjun同窗的建議,之後我會在每一節的最後把例子打包提供下載)

首先咱們將DemoActivity使用的佈局修改一下:

image

第1行爲TextView,顯示提示文字;第2行爲一個Button,觸發事件;第3行、第4行分別顯示基站信息和地理位置(如今爲空,看不到)。

layout/main.xml文件內容以下:

<? xml  version="1.0" encoding="utf-8"?>
< LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical" >
  
     < TextView
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:text="Please click the button below to get your location" />
  
     < Button
         android:id="@+id/button1"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Click Me" />
  
     < TextView
         android:id="@+id/cellText"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="" />
  
     < TextView
         android:id="@+id/lacationText"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="" />
  
</ LinearLayout >

接下來咱們打開DemoActivity.java編寫代碼。

2、爲按鈕綁定事件

咱們在Activity建立時綁定事件,將如下代碼添加到setContentView(R.layout.main);後:

/** 爲按鈕綁定事件 */
Button btnGetLocation = (Button)findViewById(R.id.button1);
btnGetLocation.setOnClickListener( new  OnClickListener() {
     @Override
     public  void  onClick(View arg0) {
         // TODO Auto-generated method stub
         onBtnClick();
     }
});

同時還須要在頭部import相關組件:

import  android.view.View;
import  android.widget.Button;
import  android.view.View.OnClickListener;

咱們來分析一下這段代碼:

首先咱們經過findViewById(R.id.button1)找到按鈕這個對象,前面加(Button)表示顯示的轉換爲Button對象;

而後設置按鈕點擊事件的監聽器,參數爲OnClickListener對象,再重載這個類的onClick方法,調用onBtnClick方法(這個方法得由咱們本身去寫,他在點擊按鈕時被調用)。

好了,調用方法寫好了,咱們來寫實現(調用後須要作什麼事)。動手編碼以前先在腦中整理好思路,養成好習慣。

咱們須要在DemoActivty類中添加以下私有方法:

  1. 咱們須要剛剛提到的onBtnClick回調方法,被調用時實現取得基站信息、獲取經緯度、獲取地理位置、顯示的功能。可是很顯然,所有揉到一個方法裏面並非個好主意,咱們將它分割爲幾個方法;

  2. 添加獲取基站信息的方法getCellInfo,返回基站信息;

  3. 添加獲取經緯度的方法getItude,傳入基站信息,返回經緯度;

  4. 添加獲取地理位置的方法getLocation,傳入經緯度,返回地理位置;

  5. 添加顯示結果的方法showResult,傳入獲得的信息在界面上顯示出來。

好了,先將方法添上,完整代碼以下:

package  com.android.demo;
  
import  android.R.bool;
import  android.R.integer;
import  android.app.Activity;
import  android.os.Bundle;
import  android.view.View;
import  android.widget.Button;
import  android.view.View.OnClickListener;
  
public  class  DemoActivity  extends  Activity {
     /** Called when the activity is first created. */
     @Override
     public  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
          
         /** 爲按鈕綁定事件 */
         Button btnGetLocation = (Button)findViewById(R.id.button1);
         btnGetLocation.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View arg0) {
                 // TODO Auto-generated method stub
                 onBtnClick();
             }
         });
     }
      
     /** 基站信息結構體 */
     public  class  SCell{
         public  int  MCC;
         public  int  MNC;
         public  int  LAC;
         public  int  CID;
     }
      
     /** 經緯度信息結構體 */
     public  class  SItude{
         public  String latitude;
         public  String longitude;
     }
      
     /** 按鈕點擊回調函數 */
     private  void  onBtnClick(){
          
     }
      
     /** 獲取基站信息 */
     private  SCell getCellInfo(){
  
     }
      
     /** 獲取經緯度 */
     private  SItude getItude(SCell cell){
          
     }
      
     /** 獲取地理位置 */
     private  String getLocation(SItude itude){
          
     }
      
     /** 顯示結果 */
     private  void  showResult(SCell cell, String location){
          
     }
}

如今在onBtnClick方法中編碼,依次調用後面幾個方法,代碼以下:

/** 按鈕點擊回調函數 */
private  void  onBtnClick(){
     /** 彈出一個等待狀態的框 */
     ProgressDialog mProgressDialog =  new  ProgressDialog( this );
     mProgressDialog.setMessage( "正在獲取中..." );
     mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
     mProgressDialog.show();
      
     try  {
         /** 獲取基站數據 */
         SCell cell = getCellInfo();
          
         /** 根據基站數據獲取經緯度 */
         SItude itude = getItude(cell);
          
         /** 獲取地理位置 */
         String location = getLocation(itude);
          
         /** 顯示結果 */
         showResult(cell, location);
          
         /** 關閉對話框 */
         mProgressDialog.dismiss();
     } catch  (Exception e) {
         /** 關閉對話框 */
         mProgressDialog.dismiss();
         /** 顯示錯誤 */
         TextView cellText = (TextView)findViewById(R.id.cellText);
         cellText.setText(e.getMessage());
     }
}

按鈕相關的工做就完成了,接下來編寫獲取基站信息的方法。

3、獲取基站信息

獲取基站信息咱們須要調用SDK提供的API中的TelephonyManager,須要在文件頭部引入:

import  android.telephony.TelephonyManager;
import  android.telephony.gsm.GsmCellLocation;

完整代碼爲:

/**
  * 獲取基站信息
 
  * @throws Exception
  */
private  SCell getCellInfo()  throws  Exception {
     SCell cell =  new  SCell();
 
     /** 調用API獲取基站信息 */
     TelephonyManager mTelNet = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
     GsmCellLocation location = (GsmCellLocation) mTelNet.getCellLocation();
     if  (location ==  null )
         throw  new  Exception( "獲取基站信息失敗" );
 
     String operator = mTelNet.getNetworkOperator();
     int  mcc = Integer.parseInt(operator.substring( 0 3 ));
     int  mnc = Integer.parseInt(operator.substring( 3 ));
     int  cid = location.getCid();
     int  lac = location.getLac();
 
     /** 將得到的數據放到結構體中 */
     cell.MCC = mcc;
     cell.MNC = mnc;
     cell.LAC = lac;
     cell.CID = cid;
 
     return  cell;
}

若是得到的位置信息爲null將拋出錯誤,再也不繼續執行。最後將獲取的基站信息封裝爲結構體返回。

4、獲取經緯度

在這一步,咱們須要採用HTTP調用google的API以獲取基站所在的經緯度。

Android做爲一款互聯網手機,聯網的功能必不可少。Android提供了多個接口供咱們使用,這裏咱們使用DefaultHttpClient

完整的方法代碼以下:

/**
  * 獲取經緯度
 
  * @throws Exception
  */
private  SItude getItude(SCell cell)  throws  Exception {
     SItude itude =  new  SItude();
 
     /** 採用Android默認的HttpClient */
     HttpClient client =  new  DefaultHttpClient();
     /** 採用POST方法 */
     HttpPost post =  new  HttpPost( "http://www.google.com/loc/json" );
     try  {
         /** 構造POST的JSON數據 */
         JSONObject holder =  new  JSONObject();
         holder.put( "version" "1.1.0" );
         holder.put( "host" "maps.google.com" );
         holder.put( "address_language" "zh_CN" );
         holder.put( "request_address" true );
         holder.put( "radio_type" "gsm" );
         holder.put( "carrier" "HTC" );
 
         JSONObject tower =  new  JSONObject();
         tower.put( "mobile_country_code" , cell.MCC);
         tower.put( "mobile_network_code" , cell.MNC);
         tower.put( "cell_id" , cell.CID);
         tower.put( "location_area_code" , cell.LAC);
 
         JSONArray towerarray =  new  JSONArray();
         towerarray.put(tower);
         holder.put( "cell_towers" , towerarray);
 
         StringEntity query =  new  StringEntity(holder.toString());
         post.setEntity(query);
 
         /** 發出POST數據並獲取返回數據 */
         HttpResponse response = client.execute(post);
         HttpEntity entity = response.getEntity();
         BufferedReader buffReader =  new  BufferedReader( new InputStreamReader(entity.getContent()));
         StringBuffer strBuff =  new  StringBuffer();
         String result =  null ;
         while  ((result = buffReader.readLine()) !=  null ) {
             strBuff.append(result);
         }
 
         /** 解析返回的JSON數據得到經緯度 */
         JSONObject json =  new  JSONObject(strBuff.toString());
         JSONObject subjosn =  new  JSONObject(json.getString( "location" ));
 
         itude.latitude = subjosn.getString( "latitude" );
         itude.longitude = subjosn.getString( "longitude" );
          
         Log.i( "Itude" , itude.latitude + itude.longitude);
          
     catch  (Exception e) {
         Log.e(e.getMessage(), e.toString());
         throw  new  Exception( "獲取經緯度出現錯誤:" +e.getMessage());
     finally {
         post.abort();
         client =  null ;
     }
      
     return  itude;
}

代筆中關鍵的地方都做了註釋,同窗們還有不理解的舉手哈。

在這裏採用POST方法將JSON數據發送到googleAPI,google返回JSON數據,咱們獲得數據後解析,獲得經緯度信息。

關於google 基站信息API的官方說明>>請到這裏查看

5、獲取物理位置

獲得經緯度後,咱們將之轉換爲物理地址。

咱們仍然使用DefaultHttpClient來調用google地圖的API,得到物理信息,不過在這裏咱們使用GET方法。

完整的方法代碼以下:

/**
  * 獲取地理位置
 
  * @throws Exception
  */
private  String getLocation(SItude itude)  throws  Exception {
     String resultString =  "" ;
 
     /** 這裏採用get方法,直接將參數加到URL上 */
     String urlString = String.format( "http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s" , itude.latitude, itude.longitude);
     Log.i( "URL" , urlString);
 
     /** 新建HttpClient */
     HttpClient client =  new  DefaultHttpClient();
     /** 採用GET方法 */
     HttpGet get =  new  HttpGet(urlString);
     try  {
         /** 發起GET請求並得到返回數據 */
         HttpResponse response = client.execute(get);
         HttpEntity entity = response.getEntity();
         BufferedReader buffReader =  new  BufferedReader( new InputStreamReader(entity.getContent()));
         StringBuffer strBuff =  new  StringBuffer();
         String result =  null ;
         while  ((result = buffReader.readLine()) !=  null ) {
             strBuff.append(result);
         }
         resultString = strBuff.toString();
 
         /** 解析JSON數據,得到物理地址 */
         if  (resultString !=  null  && resultString.length() >  0 ) {
             JSONObject jsonobject =  new  JSONObject(resultString);
             JSONArray jsonArray =  new JSONArray(jsonobject.get( "Placemark" ).toString());
             resultString =  "" ;
             for  ( int  i =  0 ; i < jsonArray.length(); i++) {
                 resultString = jsonArray.getJSONObject(i).getString( "address" );
             }
         }
     catch  (Exception e) {
         throw  new  Exception( "獲取物理位置出現錯誤:"  + e.getMessage());
     finally  {
         get.abort();
         client =  null ;
     }
 
     return  resultString;
}

GET方法就比POST方法簡單多了,獲得的數據一樣爲JSON格式,解析一下獲得物理地址。

6、顯示結果

好了,咱們已經獲得咱們想要的信息了,咱們把它顯示出來,方法代碼以下:

/** 顯示結果 */
private  void  showResult(SCell cell, String location) {
     TextView cellText = (TextView) findViewById(R.id.cellText);
     cellText.setText(String.format( "基站信息:mcc:%d, mnc:%d, lac:%d, cid:%d" ,
             cell.MCC, cell.MNC, cell.LAC, cell.CID));
 
     TextView locationText = (TextView) findViewById(R.id.lacationText);
     locationText.setText( "物理位置:"  + location);
}

7、運行程序

咱們的編碼工做已經完成了。在上面的代碼中有些地方須要的引入代碼沒有提到,下面把完整的代碼貼出來:

package  com.android.demo;
  
import  java.io.BufferedReader;
import  java.io.InputStreamReader;
  
import  org.apache.http.HttpEntity;
import  org.apache.http.HttpResponse;
import  org.apache.http.client.HttpClient;
import  org.apache.http.client.methods.HttpGet;
import  org.apache.http.client.methods.HttpPost;
import  org.apache.http.entity.StringEntity;
import  org.apache.http.impl.client.DefaultHttpClient;
  
import  org.json.JSONArray;
import  org.json.JSONObject;
  
import  android.app.Activity;
import  android.app.ProgressDialog;
import  android.content.Context;
import  android.os.Bundle;
import  android.telephony.TelephonyManager;
import  android.telephony.gsm.GsmCellLocation;
import  android.util.Log;
import  android.view.View;
import  android.widget.Button;
import  android.widget.TextView;
import  android.view.View.OnClickListener;
  
public  class  DemoActivity  extends  Activity {
     /** Called when the activity is first created. */
     @Override
     public  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
  
         /** 爲按鈕綁定事件 */
         Button btnGetLocation = (Button) findViewById(R.id.button1);
         btnGetLocation.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View arg0) {
                 // TODO Auto-generated method stub
                 onBtnClick();
             }
         });
     }
      
     /** 基站信息結構體 */
     public  class  SCell{
         public  int  MCC;
         public  int  MNC;
         public  int  LAC;
         public  int  CID;
     }
      
     /** 經緯度信息結構體 */
     public  class  SItude{
         public  String latitude;
         public  String longitude;
     }
      
     /** 按鈕點擊回調函數 */
     private  void  onBtnClick() {
         /** 彈出一個等待狀態的框 */
         ProgressDialog mProgressDialog =  new  ProgressDialog( this );
         mProgressDialog.setMessage( "正在獲取中..." );
         mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
         mProgressDialog.show();
  
         try  {
             /** 獲取基站數據 */
             SCell cell = getCellInfo();
  
             /** 根據基站數據獲取經緯度 */
             SItude itude = getItude(cell);
  
             /** 獲取地理位置 */
             String location = getLocation(itude);
  
             /** 顯示結果 */
             showResult(cell, location);
  
             /** 關閉對話框 */
             mProgressDialog.dismiss();
         catch  (Exception e) {
             /** 關閉對話框 */
             mProgressDialog.dismiss();
             /** 顯示錯誤 */
             TextView cellText = (TextView) findViewById(R.id.cellText);
             cellText.setText(e.getMessage());
             Log.e( "Error" , e.getMessage());
         }
     }
      
     /**
      * 獲取基站信息
     
      * @throws Exception
      */
     private  SCell getCellInfo()  throws  Exception {
         SCell cell =  new  SCell();
  
         /** 調用API獲取基站信息 */
         TelephonyManager mTelNet = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
         GsmCellLocation location = (GsmCellLocation) mTelNet.getCellLocation();
         if  (location ==  null )
             throw  new  Exception( "獲取基站信息失敗" );
  
         String operator = mTelNet.getNetworkOperator();
         int  mcc = Integer.parseInt(operator.substring( 0 3 ));
         int  mnc = Integer.parseInt(operator.substring( 3 ));
         int  cid = location.getCid();
         int  lac = location.getLac();
  
         /** 將得到的數據放到結構體中 */
         cell.MCC = mcc;
         cell.MNC = mnc;
         cell.LAC = lac;
         cell.CID = cid;
  
         return  cell;
     }
      
     /**
      * 獲取經緯度
     
      * @throws Exception
      */
     private  SItude getItude(SCell cell)  throws  Exception {
         SItude itude =  new  SItude();
  
         /** 採用Android默認的HttpClient */
         HttpClient client =  new  DefaultHttpClient();
         /** 採用POST方法 */
         HttpPost post =  new  HttpPost( "http://www.google.com/loc/json" );
         try  {
             /** 構造POST的JSON數據 */
             JSONObject holder =  new  JSONObject();
             holder.put( "version" "1.1.0" );
             holder.put( "host" "maps.google.com" );
             holder.put( "address_language" "zh_CN" );
             holder.put( "request_address" true );
             holder.put( "radio_type" "gsm" );
             holder.put( "carrier" "HTC" );
  
             JSONObject tower =  new  JSONObject();
             tower.put( "mobile_country_code" , cell.MCC);
             tower.put( "mobile_network_code" , cell.MNC);
             tower.put( "cell_id" , cell.CID);
             tower.put( "location_area_code" , cell.LAC);
  
             JSONArray towerarray =  new  JSONArray();
             towerarray.put(tower);
             holder.put( "cell_towers" , towerarray);
  
             StringEntity query =  new  StringEntity(holder.toString());
             post.setEntity(query);
  
             /** 發出POST數據並獲取返回數據 */
             HttpResponse response = client.execute(post);
             HttpEntity entity = response.getEntity();
             BufferedReader buffReader =  new  BufferedReader( new InputStreamReader(entity.getContent()));
             StringBuffer strBuff =  new  StringBuffer();
             String result =  null ;
             while  ((result = buffReader.readLine()) !=  null ) {
                 strBuff.append(result);
             }
  
             /** 解析返回的JSON數據得到經緯度 */
             JSONObject json =  new  JSONObject(strBuff.toString());
             JSONObject subjosn =  new  JSONObject(json.getString( "location" ));
  
             itude.latitude = subjosn.getString( "latitude" );
             itude.longitude = subjosn.getString( "longitude" );
              
             Log.i( "Itude" , itude.latitude + itude.longitude);
              
         catch  (Exception e) {
             Log.e(e.getMessage(), e.toString());
             throw  new  Exception( "獲取經緯度出現錯誤:" +e.getMessage());
         finally {
             post.abort();
             client =  null ;
         }
          
         return  itude;
     }
      
     /**
      * 獲取地理位置
     
      * @throws Exception
      */
     private  String getLocation(SItude itude)  throws  Exception {
         String resultString =  "" ;
  
         /** 這裏採用get方法,直接將參數加到URL上 */
         String urlString = String.format( "http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s" , itude.latitude, itude.longitude);
         Log.i( "URL" , urlString);
  
         /** 新建HttpClient */
         HttpClient client =  new  DefaultHttpClient();
         /** 採用GET方法 */
         HttpGet get =  new  HttpGet(urlString);
         try  {
             /** 發起GET請求並得到返回數據 */
             HttpResponse response = client.execute(get);
             HttpEntity entity = response.getEntity();
             BufferedReader buffReader =  new  BufferedReader( new InputStreamReader(entity.getContent()));
             StringBuffer strBuff =  new  StringBuffer();
             String result =  null ;
             while  ((result = buffReader.readLine()) !=  null ) {
                 strBuff.append(result);
             }
             resultString = strBuff.toString();
  
             /** 解析JSON數據,得到物理地址 */
             if  (resultString !=  null  && resultString.length() >  0 ) {
                 JSONObject jsonobject =  new  JSONObject(resultString);
                 JSONArray jsonArray =  new JSONArray(jsonobject.get( "Placemark" ).toString());
                 resultString =  "" ;
                 for  ( int  i =  0 ; i < jsonArray.length(); i++) {
                     resultString = jsonArray.getJSONObject(i).getString( "address" );
                 }
             }
         catch  (Exception e) {
             throw  new  Exception( "獲取物理位置出現錯誤:"  + e.getMessage());
         finally  {
             get.abort();
             client =  null ;
         }
  
         return  resultString;
     }
      
     /** 顯示結果 */
     private  void  showResult(SCell cell, String location) {
         TextView cellText = (TextView) findViewById(R.id.cellText);
         cellText.setText(String.format( "基站信息:mcc:%d, mnc:%d, lac:%d, cid:%d" ,
                 cell.MCC, cell.MNC, cell.LAC, cell.CID));
  
         TextView locationText = (TextView) findViewById(R.id.lacationText);
         locationText.setText( "物理位置:"  + location);
     }
}

咱們連上手機在手機上運行程序看看。

不出意外的話程序運行起來了,自動跳轉到了主界面。點擊「Click Me」,出錯了!

image

詳細的錯誤信息爲:Neither user 10078 nor current process has android.permission.ACCESS_COARSE_LOCATION.

原來是沒有權限,通過前面的學習,咱們知道Android在應用的安全上下了一番功夫,要用一些特殊功能必須先報告,安裝應用的時候列給用戶看,必需要獲得用戶的容許。這裏咱們用了獲取基站信息的功能,涉及到用戶的隱私了,因此咱們必須申明一下。

打開AndroidManifest.xml配置文件,在裏面添加相應的配置信息:

< uses-permission  android:name="android.permission.ACCESS_FINE_LOCATION"></ uses-permission >

咱們繼續把網絡鏈接的權限申明也加上:

< uses-permission  android:name="android.permission.INTERNET"></ uses-permission >

再編譯運行看看(點擊「Click Me」後程序會卡住,等待一段時間纔有反應,取決於網絡狀況):

豌豆莢截圖201202021637

成功啦!

可能有的同窗仍是出現錯誤,沒有成功:

 提示「www.google.com…」什麼的錯誤

請確認你的手機能訪問互聯網,調用google的API是必須聯網的。

 提示獲取不到基站信息

你肯定你是在手機上測試的嗎?模擬器可不行哦。或者你的手機使用的CMDA網絡?這個例子只支持GSM網絡…

 獲取不到經緯度

頗有可能你中獎了,你所在的基站還沒歸入google的數據庫…(話說我以前也遇到過,怎麼查就是查不出經緯度來,返回數據爲空)

 獲取到的地理地址不正確

這個可能程序出錯了,可能google出錯了?

其實google map API返回的數據中還包含了不少其餘信息,咱們能夠用來開發一些更有趣的功能,如製做咱們專屬的地圖軟件、足跡記錄軟件等,充分發揮你的創造力:)

8、總結

這個程序基本實現了基站定位功能,但還有不少問題,如:點擊了按鈕後界面會卡住(訪問網絡時阻塞了進程)、未對異常進一步處理、不兼容CMDA網絡等。

另外這個程序的精度也不夠,得到的位置其實是基站的物理位置,與人所在的位置還有必定差距。在城市裏面,通常採用密集型的小功率基站,精度通常在幾百米範圍內,而在郊區常爲大功率基站,密度很小,精度通常在幾公里以上。

想要取得更高的精度須要經過一些其餘的算法來實現,若是你們有興趣的話咱們能夠一塊兒來研究一下,再專門寫篇筆記。

可見寫一段程序和作一個實際的產品是有很大差異的。

9、程序代碼

這一節完整程序的請點擊這裏下載

相關文章
相關標籤/搜索