編輯:關於Android編程
上周學習了高德地圖和極光推送的SDK,需要在項目中用到,不過學習起來還是費了一番功夫去看文檔和Demo代碼的。(不得不吐槽部分文檔真的無厘頭,只有簡單的實例程序注釋都沒有,上下文還不對接,真是醉了),所以打算把最直白的步驟寫在博客中,也希望能幫到還不會用這兩種SDK的小伙伴們,少走彎路,提高工作效率。
本文主要介紹高德地圖SDK的使用步驟:
包括從獲取Key,到導包,到布局文件,以及編碼實現。
還有兩個最常用的功能:
實現定位自身。
根據地名或者坐標實現搜索定位並顯示小藍點。
一、獲取高德Key:
進入高德控制台,點擊創建應用,輸入應用名稱和應用類型。

應用創建完成後,點擊添加key開始添加新key:

SHA1碼的獲取方式有兩種:
1、Eclipse可以直接從Preferances -> Android -> Build查看當前應用的SHA1值。
2、AndroidStudio用戶有兩種方式,第一種通過命令行語句獲得,不過這樣子還要簽名要費一番周折,第二種方式最簡單直接用一個方法輸出當前應用的SHA1值,復制下來就可以了,方法如下(高德文檔提供):
public static String sHA1(Context context) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(
context.getPackageName(), PackageManager.GET_SIGNATURES);
byte[] cert = info.signatures[0].toByteArray();
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] publicKey = md.digest(cert);
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < publicKey.length; i++) {
String appendString = Integer.toHexString(0xFF & publicKey[i])
.toUpperCase(Locale.US);
if (appendString.length() == 1)
hexString.append("0");
hexString.append(appendString);
hexString.append(":");
}
String result = hexString.toString();
Log.d("xiaojingyu", result);
return result.substring(0, result.length() - 1);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
之後提交,就會得到一串類似於38bcab8bxxxxxx5bed57ba835e1的字符,這就是我們開發所需要的key了。
二、導包:
eclipse就不說了,直接把包放到libs裡就可以了。
AndroidStudio復雜一點,但也就是放到libs裡再add 到library就行了。
如下幾個是需要用到的包:

以及包下載地址
三、獲取權限:
需要的權限都要添加進AndroidMainfest.xml文件中:
四、編碼實現:
首先是布局文件:
設置高德sdk指定的MapView:
MapView mMapView = null;那這個MapView的作用是什麼呢?讀完代碼(文檔並不會告訴你)我們可以發現它是地圖的View,需要實現地圖的生命周期管理:
mMapView = (MapView) v.findViewById(R.id.map);
//在activity執行onCreate時執行mMapView.onCreate(savedInstanceState),實現地圖生命周期管理
mMapView.onCreate(savedInstanceState);
當然起到控制作用的還有一個關鍵類AMap,起到對地圖的一些基本管理以及控制接口作用,我們可以在初始化的時候進行如下操作來初始化amap實例:
if (aMap == null) {
aMap = mMapView.getMap();
aMap.moveCamera(CameraUpdateFactory.zoomTo(0)); //設置縮放為0,則一進來就顯示整個中國大陸
aMap.setLocationSource(this);// 設置定位監聽
aMap.getUiSettings().setMyLocationButtonEnabled(true);// 設置默認定位按鈕是否顯示
aMap.setMyLocationEnabled(true);// 設置為true表示顯示定位層並可觸發定位,false表示隱藏定位層並不可觸發定位,默認是false
// 設置定位的類型為定位模式 ,可以由定位、跟隨或地圖根據面向方向旋轉幾種
aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
}
實現當前位置系統小藍點:
我們可以用當前Activity實現AMap定位監聽AMapLocationListener,並重寫它的定位方法:
@Override
public void onLocationChanged(AMapLocation amapLocation) {
if (mListener != null && amapLocation != null) {
if (amapLocation != null
&& amapLocation.getErrorCode() == 0) {
mListener.onLocationChanged(amapLocation);// 顯示系統小藍點
} else {
String errText = "定位失敗," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
Log.e("AmapErr", errText);
}
}
}
這裡還要用到一個位置改變監聽:OnLocationChangedListener,通過它的方法onLocationChanged(amaplocation)來實現地圖上位置的改變!
實現響應地理編碼(輸入地名定位到具體位置):
可以看到在Amap的初始化的代碼中需要設置定位監聽,所以需要當前Activity實現LocationSource接口,並重寫激活定位以及停止定位兩個接口方法:
/**
* 激活定位
*/
@Override
public void activate(OnLocationChangedListener listener) {
Log.d("xiaojingyu", "activate");
mListener = listener;
if (mLocationClient == null) {
mLocationClient = new AMapLocationClient(getActivity());
mLocationOption = new AMapLocationClientOption();
//設置定位監聽
mLocationClient.setLocationListener(this);
//設置為高精度定位模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//設置定位參數
mLocationClient.setLocationOption(mLocationOption);
// 此方法為每隔固定時間會發起一次定位請求,為了減少電量消耗或網絡流量消耗,
// 注意設置合適的定位時間的間隔(最小間隔支持為2000ms),並且在合適時間調用stopLocation()方法來取消定位請求
// 在定位結束後,在合適的生命周期調用onDestroy()方法
// 在單次定位情況下,定位無論成功與否,都無需調用stopLocation()方法移除請求,定位sdk內部會移除
mLocationClient.startLocation();
}
}
/**
* 停止定位
*/
@Override
public void deactivate() {
Log.d("xiaojingyu", "deactivate");
mListener = null;
if (mLocationClient != null) {
mLocationClient.stopLocation();
mLocationClient.onDestroy();
}
mLocationClient = null;
}
這裡需要用到一個定位的Client對象,以及一個Option位置對象
記得申明:
public AMapLocationClient mLocationClient = null;
public AMapLocationClientOption mLocationOption = null;
接下來我們需要申明並初始化兩個搜索組件:
//搜索組件 private GeocodeSearch geocoderSearch; private Marker geoMarker;
geocoderSearch = new GeocodeSearch(getActivity());
geocoderSearch.setOnGeocodeSearchListener(this);
geoMarker = aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
其中geoMarker是用來顯示定位成功之後的小藍點。
/**
* 響應地理編碼
*/
public void getLatlon(final String name) {
//showDialog();
GeocodeQuery query = new GeocodeQuery(name, "0086");// 第一個參數表示地址,第二個參數表示查詢城市,中文或者中文全拼,citycode、adcode,
geocoderSearch.getFromLocationNameAsyn(query);// 設置同步地理編碼請求
}
其中第二個參數我設置成0086是中國的區號,這樣可以實現全國范圍內查找。比如我只設置成長沙的區號0731,那麼我只能輸入長沙的地名進行查找,再查比如岳陽是查不到的。
之後會回調geocoderSearch的監聽方法實現定位:
@Override
public void onGeocodeSearched(GeocodeResult result, int rCode) {
//dismissDialog();
if (rCode == 1000) {
if (result != null && result.getGeocodeAddressList() != null
&& result.getGeocodeAddressList().size() > 0) {
GeocodeAddress address = result.getGeocodeAddressList().get(0);
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
AMapUtil.convertToLatLng(address.getLatLonPoint()), 15));
geoMarker.setPosition(AMapUtil.convertToLatLng(address
.getLatLonPoint()));
addressName = "經緯度值:" + address.getLatLonPoint() + "\n位置描述:"
+ address.getFormatAddress();
// ToastUtil.show(getActivity(), addressName);
} else {
ToastUtil.show(getActivity(), "沒有查詢到結果~!");
}
} else {
ToastUtil.showerror(getActivity(), rCode);
}
}
用到的功能大概就是這些,如果還需要其他的功能可以參考高德SDK官方文檔:
http://lbs.amap.com/api/android-location-sdk/guide/android-location/getlocation/
最後是我最後實現的效果動圖:

因為涉及項目相關,所以不能把全部源碼貼上來了。
有問題的朋友在評論區留言,我會一一解答。
*************************分隔線*********************
應評論區朋友的要求,在這裡貼上響應逆地理編碼的代碼:
/**
* 響應逆地理編碼
*/
public void getAddress(final LatLonPoint latLonPoint) {
showDialog();
RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200,
GeocodeSearch.AMAP);// 第一個參數表示一個Latlng,第二參數表示范圍多少米,第三個參數表示是火系坐標系還是GPS原生坐標系
geocoderSearch.getFromLocationAsyn(query);// 設置同步逆地理編碼請求
}
/**
* 逆地理編碼回調
*/
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
dismissDialog();
if (rCode == 1000) {
if (result != null && result.getRegeocodeAddress() != null
&& result.getRegeocodeAddress().getFormatAddress() != null) {
addressName = result.getRegeocodeAddress().getFormatAddress()
+ "附近";
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
AMapUtil.convertToLatLng(latLonPoint), 15));
regeoMarker.setPosition(AMapUtil.convertToLatLng(latLonPoint));
ToastUtil.show(GeocoderActivity.this, addressName);
} else {
ToastUtil.show(GeocoderActivity.this, R.string.no_result);
}
} else {
ToastUtil.showerror(this, rCode);
}
}
了解android7:通知直接回復
這是<是時候來了解android7>系列的第三篇文章了, 前面兩篇分別介紹了多窗口模式和shortcut功能, 今天我們來點簡單的, 說一說通知直接回復功能.
詳細分析Android中onTouch事件傳遞機制
onTach介紹ontach是Android系統中整個事件機制的基礎。Android中的其他事件,如onClick、onLongClick等都是以onTach為基礎的。o
Android API Guides---OpenGL ES
OpenGL ESAndroid包括高性能2D和3D圖形開放圖形庫(OpenGL?的),具體而言,OpenGL ES的API支持。 OpenGL是一個跨平台的圖形API,
Android自定義控件——自定義組合控件
前面幾篇博文介紹了Android如何自定義控件,其實就是講一下如何“從無到有”的自定義一個全新的控件,繼承View或者繼承ViewG