820 likes | 1.05k Views
Android 智慧型手機程式設計. Android Google Maps. 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2. Google Maps. Reference : http://developer.android.com/resources/tutorials/views/hello-mapview.html. 取得 Google Map API. Step1: 先進入 JDK 目錄. Google Maps. 透過 keytool.exe 建立認證指紋 需要 debug_keystore 路徑. Google Maps.
E N D
Android智慧型手機程式設計 AndroidGoogle Maps 建國科技大學 資管系 饒瑞佶 2012/4 V1 2012/8 V2
Google Maps Reference: http://developer.android.com/resources/tutorials/views/hello-mapview.html • 取得Google Map API Step1:先進入JDK目錄
Google Maps • 透過keytool.exe建立認證指紋 • 需要debug_keystore路徑
Google Maps • debug_keystore路徑
Google Maps • 輸入keytool -list -alias androiddebugkey -keystore "C:\Documents and Settings\Administrator\.android\debug.keystore" -storepass android -keypass android 如果使用的是jdk 7 keytool -list –v -alias androiddebugkey -keystore "C:\Documents and Settings\Administrator\.android\debug.keystore" -storepass android -keypass android
Google Maps • 產生認證指紋 要的是MD5編碼的
Google Maps • 進入Google Map API Key申請頁面 • http://code.google.com/intl/zh-Tw/android/add-ons/google-apis/maps-api-signup.html 輸入認證指紋碼
Google Maps • 進入Google Map API Key申請頁面 • http://code.google.com/intl/zh-Tw/android/add-ons/google-apis/maps-api-signup.html
Google Maps • 產生出API金鑰 0O7bGO2vQxBc90bpYbJ8PnSjJapePPkrSGRvP3A <com.google.android.maps.MapView android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="0O7bGO2vQxBc90bpYbJ8PnSjJapePPkrSGRvP3A" /> 加入main.xml
Google Maps main.xml
Google Maps • 建立新專案: HelloMaps 沒有Google APIs target
Google Maps • 如果沒有Google APIs target • 請選擇Available packages進行安裝
Google Maps • 安裝完Google APIs target畫面
Google Maps • 建立新專案: HelloMaps
顯示Google Maps地圖 加入 改成MapActivity 加入
Google Maps • AVD也要對應具備Google APIs功能
Google Maps • 增加 <uses-permission android:name="android.permission.INTERNET" /> • 在 <application> 裡頭增加 <uses-library android:name="com.google.android.maps" /> 資訊
在Google Maps上加標示 • 需要一個overlay class,做堆疊圖層之用
MapsOverlay import java.util.ArrayList; import android.app.AlertDialog; import android.content.Context; import android.graphics.drawable.Drawable; import com.google.android.maps.ItemizedOverlay; import com.google.android.maps.OverlayItem; public class MapsOverlay extends ItemizedOverlay<OverlayItem> { private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>(); private Context context; public MapsOverlay(Drawable defaultMarker) { super(boundCenterBottom(defaultMarker)); } public MapsOverlay(Drawable defaultMarker, Context context) { this(defaultMarker); this.context = context; } @Override protected OverlayItem createItem(int i) { return mapOverlays.get(i); } @Override public int size() { return mapOverlays.size(); } @Override protected boolean onTap(int index) { OverlayItem item = mapOverlays.get(index); AlertDialog.Builder dialog = new AlertDialog.Builder(context); dialog.setTitle(item.getTitle()); dialog.setMessage(item.getSnippet()); dialog.show(); return true; } public void addOverlay(OverlayItem overlay) { mapOverlays.add(overlay); this.populate(); } }
Main.xml 決定地圖能不能互動 決定View顯示方式 需要與layout_width或layout_height一起使用 加入這段來切換地圖種類
<com.google.android.maps.MapView android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="0O7bGO2vQxBeLzI0QcgiCeACyJVnbWwK4xInhyw" android:enabled="true" android:clickable="true" android:layout_weight="1" /> <LinearLayout xmlns:tools="http://schemas.android.com/tools" 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:layout_alignParentLeft="true" android:layout_centerVertical="true" android:text="地圖" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:text="衛星" /> </LinearLayout> 剩下空間分給maps
layout_weight • 決定View的重要性 • 預設為0,代表需要顯示,怎麼設定就怎麼顯示,其他的空間再給其他View去分 • 若layout_weight>0,則將畫面空間分割,分割比例取決於其他view的layout_weight • 數字相同代表重要性相當 • 最後大小=本身數字/(全部數字總和)
layout_weight 改變看看 改變看看 改變看看 改變看看 改變看看 改變看看
<?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:text="redwwwwwww" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"/> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="2" android:text="地圖" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="6" android:text="衛星" /> </LinearLayout>
result 1/(1+2+6) 2/(1+2+6) 6/(1+2+6)
HelloMaps 給定一個座標(未來可以來自於GPS) 坐標 圖示 在給定座標上 加圖示 圖示按下時顯示的資訊 切換成衛星圖 切換成標準地圖
private MapView mapView; private static final int latitudeE6=37985339; //先給一個座標,圖要顯示的位置 private static final int longitudeE6=23716735; Button btn_streetview=(Button)findViewById(R.id.button1); Button btn_satellitetview=(Button)findViewById(R.id.button2); mapView=(MapView)findViewById(R.id.mapview); mapView.setBuiltInZoomControls(true); //出現放大縮小選項 mapView.setSatellite(false); //預設顯示地圖模式 List<Overlay> mapOverlays=mapView.getOverlays(); Drawable drawable=this.getResources().getDrawable(R.drawable.ic_launcher); //要顯示的小圖 MapsOverlay itemizedOverlay=new MapsOverlay(drawable,this); //將小圖加入圖層 GeoPoint point=new GeoPoint(latitudeE6,longitudeE6); //座標點 OverlayItem overlayitem=new OverlayItem(point,"Hello","I'm in Athens, Greece!"); //點圖時要顯示的字 itemizedOverlay.addOverlay(overlayitem); //將文字加入圖層 mapOverlays.add(itemizedOverlay); //將圖層加入地圖 MapController mapcontroller=mapView.getController(); //建立地圖控制物件 mapcontroller.animateTo(point); //將小圖顯示在正中央 mapcontroller.setZoom(10); //預設圖的縮放比例大小
btn_streetview.setOnClickListener(new Button.OnClickListener() { public void onClick(View arg0) { // TODO Auto-generated method stub mapView.setSatellite(false); //顯示地圖模式 } }); btn_satellitetview.setOnClickListener(new Button.OnClickListener() { public void onClick(View arg0) { // TODO Auto-generated method stub mapView.setSatellite(true); //顯示衛星模式 } });
地址轉座標 try { inputaddress=(EditText)findViewById(R.id.editText1); Geocoder geocoder = new Geocoder(Maps1Activity.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); showlocation((int) (addr.getLatitude() * 1E6),(int) (addr.getLongitude() * 1E6)); } } catch (Exception e) { tv1.setText("convert error"); } 需要將顯示圖示的程式碼變成成員函數
layout <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:text="" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
showlocation private void showlocation(int lat,int lng){ List<Overlay> mapOverlays=mapView.getOverlays(); Drawable drawable=this.getResources().getDrawable(R.drawable.ic_launcher); //要顯示的小圖 MapsOverlay itemizedOverlay=new MapsOverlay(drawable,this); //將小圖加入圖層 GeoPoint point=new GeoPoint(lat,lng); //座標點 OverlayItem overlayitem=new OverlayItem(point,"Hello","I'm in Athens, Greece!"); //點圖時要顯示的字 itemizedOverlay.addOverlay(overlayitem); //將文字加入圖層 mapOverlays.add(itemizedOverlay); //將圖層加入地圖 MapController mapcontroller=mapView.getController(); //建立地圖控制物件 mapcontroller.animateTo(point); //將小圖顯示在正中央 mapcontroller.setZoom(10); //預設圖的縮放比例大小 }
AVD多數執行有問題, 最好使用手機測試 1600 Amphitheatre Parkway, Mountain View, CA Android 2.2
輸入地址 轉換地址成座標 座標 顯示座標點
利用Intent 玩Google Maps • 建立新專案: IntentMaps
顯示Google Maps地圖 要取消
code Uri uri=Uri.parse("geo:37.985339,23.716735"); Intent it=new Intent(Intent.ACTION_VIEW,uri); startActivity(it);
利用Intent 玩Google Maps • AVD也要對應具備Google APIs功能
利用Intent 玩Google Maps • 增加 <uses-permission android:name="android.permission.INTERNET" />
更多Google Maps • Google MapsURI 格式:geo:latitude,longitude<< 沒有小圖示 geo:0,0?q=latitude,longitude << 出現圖示geo:latitude,longitude?z=zoom<<目前沒作用geo:0,0?q=my+street+address<< 出現有註冊的位置(my已取消)geo:0,0?q=business+near+city • Google StreetviewURI 格式:google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom 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("geo:38.899533,-77.036476"); Intent it = new Intent(Intent.ACTION_VIEW, uri); startActivity(it); • 路徑規劃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
AndroidManiFest.xml 建立一個新專案HelloGPS • 需要開放以下權限 • <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> • <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
偵測是否開啟GPS //如果沒有開啟GPS--------------------- LocationManager status=(LocationManager)(this.getSystemService(Context.LOCATION_SERVICE)); if(status.isProviderEnabled(LocationManager.GPS_PROVIDER) || status.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