Android google maps
This presentation is the property of its rightful owner.
Sponsored Links
1 / 83

Android Google Maps PowerPoint PPT Presentation


  • 146 Views
  • Uploaded on
  • Presentation posted in: General

Android 智慧型手機程式設計. Android Google Maps. 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2 2013/5 V3 V4. Google Maps. Reference : https://developers.google.com/maps/documentation/android/start#creating_an_api_project. 取得 Google Map API. Step1: 先進入 JDK 目錄. Google Maps. 透過 keytool.exe 建立認證指紋 SHA1

Download Presentation

Android Google Maps

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Android智慧型手機程式設計

AndroidGoogle Maps

建國科技大學 資管系

饒瑞佶

2012/4 V1

2012/8 V2

2013/5 V3 V4


Google Maps

Reference:

https://developers.google.com/maps/documentation/android/start#creating_an_api_project

  • 取得Google Map API

Step1:先進入JDK目錄


Google Maps

  • 透過keytool.exe建立認證指紋SHA1

  • 需要debug_keystore路徑


新版IDE已經列出SHA1碼不過好像不太能用

下一步驟用


重做一次認證

  • 輸入

    • keytool -list -v -keystore "C:\Documents and Settings\Administrator\.android\debug.keystore“

  • 預設密碼是android

來自Eclipse內的default keystore


Google Maps

  • 產生認證指紋

要的是SHA1編碼


Google Maps

  • 進入Google Map API Key申請頁面

  • http://code.google.com/intl/zh-Tw/android/add-ons/google-apis/maps-api-signup.html(不再使用)

目前不用

輸入認證指紋碼


Google Maps Android API Version 1開發法已經停用

  • http://cheng-min-i-taiwan.blogspot.tw/2013/04/google-maps-android-api-v2-android.html

  • 新版API需要配合Google Play Services


進入申請頁面

  • https://developers.google.com/maps/documentation/javascript/tutorial#api_key

需要登入Google


Google Maps

  • 進入Google Map API Key申請頁面

Reference:這裡有做法

https://developers.google.com/maps/documentation/android/start#creating_an_api_project


API Access


使用SHA1與package Name


result


使用API Key


首先將API key加入AndroidManifest.xml

<meta-dataandroid:name="com.google.android.maps.v2.API_KEY"android:value="your_api_key"/>


加入使用權限


加入使用權限到AndroidManifest.xml

改成自己的package name

<permissionandroid:name="ctu.rcjao.helloandroid.permission.MAPS_RECEIVE“ android:protectionLevel="signature"/>

<uses-permission android:name="ctu.rcjao.helloandroid.permission.MAPS_RECEIVE"/>

改成自己的package name


加入使用權限到AndroidManifest.xml


Use permission

<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permissionandroid:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/><!-- The following two permissions are not required to useGoogle Maps Android API v2, but are recommended. --><uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/><uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>


再加入use-feature


uses-feature

<uses-featureandroid:glEsVersion="0x00020000"android:required="true"/>


最後加入地圖


Xml檔案

加入下列code

<fragment xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/map"

android:layout_width="match_parent"

android:layout_height="match_parent"

class="com.google.android.gms.maps.SupportMapFragment"/>


JAVA程式

publicclass Map extends FragmentActivity {

@Override

protectedvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.map);

}

}


執行

結果不能跑,有錯誤!


打開SDK中的SDK Manager,找到Extras並安裝Android Support Library及 Google Play Services兩個項目


匯入Google Play Services函式庫File > Import > Android > Existing Android Code Into Workspace

路徑:

android-sdk\extras\google\google_play_services\libproject\google-play-services_lib


匯入完成


專案要加入這個library


還有要開google Maps Android API v2

不是這個喔!


執行

  • 需要實體手機

  • 過程中可能需要更新Google Play


Google Maps

實體手機


發佈到AVD2.2


有了,但是還是不行!

換個版本4.0.3


使用SDK 4.0.3

AVD設定


設定模擬器顯示地圖

  • 首先在模擬器中安裝Google Play Service

  • 修改System目錄之檔案權限,允許寫入權限

    • adb shell mount -o remount,rw -t yaffs2 /dev/block/mtdblock0 /system

    • adb shell chmod 777 /system/app

  • adb push GoogleLoginService.apk /system/app/

  • adb push GoogleServicesFramework.apk /system/app/

  • adb push Phonesky.apk /system/app/


  • adb install Maps_6.12.0.apk

  • adb install com.google.android.gms-3.apk

Google Play Service

要夠新

漫長的等待….


如果出現要update Google Play Service!


通常是失敗,因為不支援線上更新

下載新的APK重裝就可以了


result


在Google Maps上加標示

@SuppressLint("NewApi")

publicclass Main extendsFragmentActivity {

//要顯示的座標

staticfinal LatLng CTU = new LatLng(24.06660656734983, 120.54975986480713);

private GoogleMap map;

@SuppressLint("NewApi")

@Override

protectedvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//取得地圖物件

map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

//建立紅色氣球標示

Marker mk = map.addMarker(new MarkerOptions().position(CTU).title("建國科技大學").snippet("資管系"));

// 設定縮放大小是16,且將標示點放在正中央

map.moveCamera(CameraUpdateFactory.newLatLngZoom(CTU, 16));

}

}

  • SDK至少要4.0

如果更早的SDK也要可以用

map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();


result


修改UI的xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<fragment android:layout_weight="1"

android:id="@+id/map"

android:layout_width="match_parent"

android:layout_height="match_parent"

class="com.google.android.gms.maps.SupportMapFragment"/>

<LinearLayout

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:layout_weight="0" >

<Button

android:id="@+id/button1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="地圖" />

<Button

android:id="@+id/button2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="衛星" />

</LinearLayout>

</LinearLayout>

原地圖

設定layout_weight

加入這段來切換地圖種類


result


Oncreate中加入下列code

Button btn_normalview=(Button)findViewById(R.id.button1);

Button btn_satellitetview=(Button)findViewById(R.id.button2);

btn_normalview.setOnClickListener(new Button.OnClickListener()

{

publicvoid onClick(View arg0) {

map.setMapType(GoogleMap.MAP_TYPE_NORMAL); //顯示地圖模式

}

});

btn_satellitetview.setOnClickListener(new Button.OnClickListener()

{

publicvoid onClick(View arg0) {

map.setMapType(GoogleMap.MAP_TYPE_SATELLITE); //顯示衛星模式

}

});


地址轉座標功能將下列code加入UI (fragment前)

<LinearLayout

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:layout_weight="0" >

<EditText

android:id="@+id/editText1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:ems="10" >

<requestFocus />

</EditText>

<Button

android:id="@+id/button3"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="顯示" />

<TextView

android:id="@+id/textview1"

android:text=""

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

</LinearLayout>


地址轉座標功能

Button btn_address_to_geo=(Button)findViewById(R.id.button3);

btn_address_to_geo.setOnClickListener(new Button.OnClickListener()

{

publicvoid onClick(View arg0) {

try {

EditText inputaddress=(EditText)findViewById(R.id.editText1);

tv1=(TextView)findViewById(R.id.textview1);

Geocoder geocoder = new Geocoder(Main.this, Locale.getDefault());

List<Address> geoResults = geocoder.getFromLocationName(inputaddress.getText().toString(), 5);

while (geoResults.size()==0) {

geoResults = geocoder.getFromLocationName(inputaddress.getText().toString(), 5);

}

if (geoResults.size()>0) {

Address addr = geoResults.get(0);

Double latitude = addr.getLatitude() * 1E6;

Double longitude = addr.getLongitude() * 1E6;

tv1.setText(latitude + "/" + longitude);

}

} catch (Exception e) {

tv1.setText("轉換失敗");

}

}

});


result

模擬器

實機


建立showlocation方法

// 顯示座標點

privatevoid showloaction(double d,double e,String title, String snip){

LatLng CTU = new LatLng(d, e);

//取得地圖物件

map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

//建立紅色氣球標示

Marker mk = map.addMarker(new MarkerOptions().position(CTU).title(title).snippet(snip));

// 設定縮放大小是16,且將標示點放在正中央

map.moveCamera(CameraUpdateFactory.newLatLngZoom(CTU, 16));

}


呼叫showlocation方法

showloaction(24.06660656734983, 120.54975986480713,"建國科技大學","資管系");


呼叫showlocation方法

Button btn_address_to_geo=(Button)findViewById(R.id.button3);

btn_address_to_geo.setOnClickListener(new Button.OnClickListener()

{

publicvoid onClick(View arg0) {

try {

EditText inputaddress=(EditText)findViewById(R.id.editText1);

tv1=(TextView)findViewById(R.id.textview1);

Geocoder geocoder = new Geocoder(Main.this, Locale.getDefault());

List<Address> geoResults = geocoder.getFromLocationName(inputaddress.getText().toString(), 5);

while (geoResults.size()==0) {

geoResults = geocoder.getFromLocationName(inputaddress.getText().toString(), 5);

}

if (geoResults.size()>0) {

Address addr = geoResults.get(0);

Double latitude = addr.getLatitude() * 1E6;

Double longitude = addr.getLongitude() * 1E6;

tv1.setText(latitude + "/" + longitude);

showloaction((double)(addr.getLatitude()), (double)(addr.getLongitude()),inputaddress.getText().toString(),"");

}

} catch (Exception e) {

tv1.setText("轉換失敗");

}

}

});


AVD多數執行有問題,

最好使用手機測試

輸入地址

轉換地址成座標

座標

顯示座標點


不用註冊Google MapsAPI也可以使用Intent


顯示Google Maps地圖

publicclass MapIntent extends Activity {

@Override

protectedvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Uri uri=Uri.parse("geo:24.06660656734983,120.54975986480713");

Intent it=new Intent(Intent.ACTION_VIEW,uri);

startActivity(it);

}

}


利用Intent 玩Google Maps


Google Mapsstreet view

  • Uri uri=Uri.parse("google.streetview:cbll=46.813812,-71.207378&cbp=1,99.56,,1,-5.27&mz=21");

    只支援美加地區

AVD是看不到的!


更多Google Maps

  • 路徑規劃Uri uri = Uri.parse("http://maps.google.com/maps? f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); Intent it = new Intent(Intent.ACTION_VIEW, uri); startActivity(it); //where startLat, startLng, endLat, endLng are a long with 6 decimals like: 50.123456


整合GPS


加入對應的xml

<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:id="@+id/textview1"

android:text=""

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

<fragment android:layout_weight="1"

android:id="@+id/map"

android:layout_width="match_parent"

android:layout_height="match_parent"

class="com.google.android.gms.maps.SupportMapFragment"/>

</LinearLayout>


AndroidManiFest.xml

  • 需要開放以下權限

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

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


偵測是否開啟GPS

private LocationManager mLocationManager;

//如果沒有開啟GPS---------------------

mLocationManager=(LocationManager)(this.getSystemService(Context.LOCATION_SERVICE));

if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){

}else{

// 到系統開啟GPS與WIFI服務的畫面

startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));

}

//--------------------如果沒有開啟GPS


Android GPS運作方式

  • 使用LocationManager:判定是否有提供定位服務(硬體GPS或WIFI)

  • 建立LocationProvider,設定定位參數,並同時透過LocationManager取得座標(硬體軟體,GPS或是WiFi)

  • 設定LocationManager的Listener事件,偵測事件的改變

  • MapController負責控制Google Maps


GPS訊號抓取主體

宣告

GPS訊號擷取主體

沒有GPS時觸發


補充說明

mLocationManager =(LocationManager)(this.getSystemService(Context.LOCATION_SERVICE));

if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){

}else{

// 到達系統開啟GPS與WIFI服務的畫面

startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));

}

//--------------------如果沒有開啟GPS

/* Provider 初始化 */

getLocationPrivider();

/* 設定事件的Listener */

mLocationManager.requestLocationUpdates(mLocationPrivider, 2000, 0, mLocationListener);

if(mLocation!=null)//第一次顯示

{

// 取得速度

double speed=mLocation.getSpeed()/1000*60*60; //原單位是m/s

double altitude = mLocation.getAltitude();

tv_show_gps.setText("緯度:"+ formatgeo(mLocation.getLatitude()) + " 經度:"+ formatgeo(mLocation.getLongitude()) + " 海拔:"+ altitude + " m 速度:"+ formatspeed(speed) + "km/h");

}

啟動GPS

如果沒有啟動

使用GPS服務,

將跳至設定畫面

要求GPS提供服務

設定GPS監聽

服務

如果有GPS訊號,

顯示到畫面上

TextView tv_show_gps;

private ProgressDialog MyDialog;

private String mLocationPrivider="";

private Location mLocation;

宣告物件


tv_show_gps=(TextView)findViewById(R.id.textview1);

createCancelProgressDialog("定位中","定位中..請稍待!","取消");

try{

//如果沒有開啟GPS---------------------

mLocationManager =(LocationManager)(this.getSystemService(Context.LOCATION_SERVICE));

if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){

}else{

// 到系統開啟GPS與WIFI服務的畫面

startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));

}

//--------------------如果沒有開啟GPS

mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

// Provider 初始化

getLocationPrivider();

// 設定GPS的Listener

mLocationManager.requestLocationUpdates(mLocationPrivider, 2000, 0, mLocationListener);

if(mLocation!=null) //第一次顯示

{

// 取得速度

double speed=mLocation.getSpeed()/1000*60*60; //原單位是m/s

double altitude = mLocation.getAltitude();

tv_show_gps.setText("緯度:"+ formatgeo(mLocation.getLatitude()) + " 經度:"+ formatgeo(mLocation.getLongitude()) + " 海拔:"+ altitude + " m 速度:"+ formatspeed(speed) + "km/h");

}


}catch(Exception e){

new AlertDialog.Builder(GPS.this)

.setTitle("系統訊息")

.setMessage("無法取得GPS座標")

.setPositiveButton("確認",new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

// TODO Auto-generated method stub

MyDialog.dismiss();

}

})

.show();

}


// 取得LocationProvider

public void getLocationPrivider()

{

Criteria mCriteria01 = new Criteria();

mCriteria01.setAccuracy(Criteria.ACCURACY_FINE);

mCriteria01.setAltitudeRequired(true); //需要高度

mCriteria01.setBearingRequired(false);

mCriteria01.setCostAllowed(true);

mCriteria01.setPowerRequirement(Criteria.POWER_LOW);

mLocationPrivider = mLocationManager.getBestProvider(mCriteria01, true);

mLocation = mLocationManager.getLastKnownLocation(mLocationPrivider);

}


// 偵測位置改變

public final LocationListener mLocationListener = new LocationListener()

{

public void onLocationChanged(Location location)

{

// 取得速度

double speed=location.getSpeed()/1000*60*60; //原單位是m/s

double altitude = location.getAltitude();

tv_show_gps.setText("緯度:"+ formatgeo(location.getLatitude()) + " 經度:"+ formatgeo(location.getLongitude()) + " 海拔:"+ altitude + " m 速度:"+ formatspeed(speed) + "km/h");

MyDialog.dismiss();//結束進度

}

public void onProviderDisabled(String provider)

{

}

public void onProviderEnabled(String provider)

{

}

public void onStatusChanged(String provider,int status,Bundle extras)

{

}

};

//-----------------偵測位置改變


// format GPS座標的方法

public String formatgeo(double num)

{

NumberFormat formatter = new DecimalFormat("###.####");

String s=formatter.format(num);

return s;

}

// format speed的方法

public String formatspeed(double num)

{

NumberFormat formatter = new DecimalFormat("###.##");

String s=formatter.format(num);

return s;

}


// 按BACK按鍵時關閉程式

@Override

public void onBackPressed() {

android.os.Process.killProcess(android.os.Process.myPid());

HelloGPSActivity.this.finish();

}

// 產生定位中視窗

private void createCancelProgressDialog(String title, String message, String buttonText) {

MyDialog = new ProgressDialog(this);

MyDialog.setTitle(title);

MyDialog.setMessage(message);

MyDialog.setButton(buttonText, new DialogInterface.OnClickListener(){

public void onClick(DialogInterface dialog, int which){

// Use either finish() or return() to either close the activity or just the dialog

android.os.Process.killProcess(android.os.Process.myPid());

HelloGPSActivity.this.finish();

return;

}

});

MyDialog.show();// 顯示進度

}


透過ddms送出模擬GPS座標到AVD

需要

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


取得GPS訊號後,將其顯示到Google Maps上


結合前面的showloaction方法

  • 在onLocationChanged中加入呼叫

記得加入地圖

private GoogleMap map;


稍微修改showloaction方法

Marker mk=null;

// 顯示座標點

privatevoidshowloaction(doubled,doublee,String title, String snip){

LatLng CTU = newLatLng(d, e);

//取得地圖物件

map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

//建立紅色氣球標示

if(mk != null) mk.remove();

mk = map.addMarker(newMarkerOptions().position(CTU).title(title).snippet(snip));

// 設定縮放大小是16,且將標示點放在正中央

map.moveCamera(CameraUpdateFactory.newLatLngZoom(CTU, 16));

}

移除前一個氣球


result


控制旋轉不觸發oncreate

  • AndroidMainfast.xml中設定允許改變:

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

  • AndroidMainfast.xml中對要攔截旋轉事件的Activity加入屬性:

    • android:configChanges="orientation"


畫路徑-從現在的範例修改

加入成全域

LatLng p1; //出發點

LatLng p2; //結束點

加入第一個點

if(mLocation!=null) //第一次顯示

{

//取得速度

double speed=mLocation.getSpeed()/1000*60*60; //原單位是m/s

double altitude = mLocation.getAltitude();

p1 = new LatLng(mLocation.getLatitude(), mLocation.getLongitude());

tv_show_gps.setText(“緯度:”+ formatgeo(mLocation.getLatitude()) + " 經度:"+ formatgeo(mLocation.getLongitude()) + " 海拔:"+ altitude + " m 速度:"+ formatspeed(speed) + "km/h");

}


publicvoid onLocationChanged(Location location)

{

// 取得速度

double speed=location.getSpeed()/1000*60*60; //原單位是m/s

double altitude = location.getAltitude();

tv_show_gps.setText("緯度:"+ formatgeo(location.getLatitude()) + " 經度:"+ formatgeo(location.getLongitude()) + " 海拔:"+ altitude + " m 速度:"+ formatspeed(speed) + "km/h");

p2 = new LatLng(location.getLatitude(), location.getLongitude());

showloaction((double)(location.getLatitude()), (double)(location.getLongitude()),"目前GPS座標點","");

p1=p2;

MyDialog.dismiss(); //結束進度

}

取得結束點

畫線

將結束點變成出發點


// 顯示座標點

privatevoid showloaction(double d,double e,String title, String snip){

LatLng CTU = new LatLng(d, e);

//取得地圖物件

map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

//建立紅色氣球標示

if(mk != null) mk.remove();

mk = map.addMarker(new MarkerOptions().position(CTU).title(title).snippet(snip));

// 設定縮放大小是16,且將標示點放在正中央

//map.moveCamera(CameraUpdateFactory.newLatLngZoom(CTU, 16));

PolylineOptions line=new PolylineOptions().add(p1,p2).width(5).color(Color.BLUE);

map.addPolyline(line);

map.moveCamera(CameraUpdateFactory.newLatLngZoom(p2, 16));

}

加入畫線


  • Login