一、元件開發前準備
首先,建立高德地圖開發者賬号,擷取地圖的key。
進入自己的高德開發賬号,點選‘建立新應用’

建立應用完成點選右上角的添加新key
釋出版SHA1以及調試版SHA1擷取:
1、打開android studio 找到Terminal并打開,或者在最下面找到Terminal 如下圖:
2、 輸入指令 C: 進入c盤;
3、接着 輸入指令 cd Users\Administrator 其中Administrator是自己的使用者名 Administrator檔案下有個.adnroid檔案, 輸入指令 cd .android,最後就找到了.android,如圖:
4、輸入指令 keytool -list -v -keystore debug.keystore 其中debug.keystore是studio預設的keystore,按回車,然後輸入秘鑰:android(系統預設) 回車(秘鑰庫密碼是看不到的)如下圖:
這樣就成功擷取到開發版的SHA1值了
二、擷取釋出版的SHA1:
擷取釋出版的SHA1,跟擷取開發版的SHA1的1、2、3步驟一樣,不一樣的地方就是第4步稍微不同而已。
1、同上;
2、同上;
3、同上;
4、輸入指令 keytool -list -v -keystore 檔案目錄\自己的簽名檔案 比如我的:keytool -list -v -keystore E:\簽名檔案\android.keystore ,接着按回車,然後輸入秘鑰:(我隻知道我的,哈哈) 回車(秘鑰庫密碼是看不到的)如下圖:
這樣就成功擷取到釋出版的SHA1值了
在AndroidManifest.xml中添加相應的權限
<!-- 允許程式打開網絡套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允許程式設定内置sd卡的寫權限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允許程式擷取網絡狀 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 允許程式通路WiFi網絡資訊-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允許程式讀寫手機狀态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 允許程式通路CellID或WiFi熱點來擷取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
添加高德地圖的apiKey
在app的build.gradle中添加相關依賴:
二、元件開發
1、自定義MapView控件
建立布局檔案location_layout.xml。布局檔案裡主要放了一個mapView控件。
建立WeexMapView繼承LinearLayout類,開發一個自定義的組合元件。
public void setMapModel(int model){
switch (model){
case 1://連續定位、藍點不會移動到地圖中心點,定位點依照裝置方向旋轉,并且藍點會跟随裝置移動。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
break;
case 2://連續定位、且将視角移動到地圖中心點,定位藍點跟随裝置移動。(1秒1次定位)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
break;
case 3://連續定位、且将視角移動到地圖中心點,地圖依照裝置方向旋轉,定位點會跟随裝置移動。(1秒1次定位)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);
break;
case 4://連續定位、且将視角移動到地圖中心點,定位點依照裝置方向旋轉,并且會跟随裝置移動。(1秒1次定位)預設執行此種模式。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
break;
}
aMap.setMyLocationStyle(myLocationStyle);
}
//設定預設定位按鈕是否顯示,非必需設定。
public void showLocationButton(boolean isShow){
aMap.getUiSettings().setMyLocationButtonEnabled(isShow);
}
// 設定為true表示啟動顯示定位藍點,false表示隐藏定位藍點并不進行定位,預設是false。
public void showLocationPoint(boolean isShow){
aMap.setMyLocationEnabled(isShow);
}
public void setMapType(int type){
switch (type){
case 1:
aMap.setMapType(AMap.MAP_TYPE_NORMAL);// 設定普通地圖模式
break;
case 2:
aMap.setMapType(AMap.MAP_TYPE_NAVI);// 設定導航地圖模式
break;
case 3:
aMap.setMapType(AMap.MAP_TYPE_NIGHT);// 設定夜景地圖模式
break;
case 4:
aMap.setMapType(AMap.MAP_TYPE_SATELLITE);// 設定衛星地圖模式
break;
}
}
public void onDestroy(){
mapView.onDestroy();
}
public void onResume(){
mapView.onResume();
}
public void onPause(){
mapView.onPause();
}
public void onCreate(Bundle outState){
mapView.onCreate(outState);
}
public void onSaveInstanceState(Bundle outState){
mapView.onSaveInstanceState(outState);
}
2、開發WXMapComponent元件
建立WXMapComponent繼承 WXComponent<WeexMapView>
WXMapComponent.java代碼如下:
public class WXMapComponent extends WXComponent<WeexMapView> {
WeexMapView mapView;
WXSDKInstance wxInstance; //weex執行個體對象,用于獲得上下文
boolean clicked=false;
//兩個不同參數的構造方法
public WXMapComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {
super(instance, dom, parent);
wxInstance = instance;
}
public WXMapComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, int type) {
super(instance, dom, parent, type);
wxInstance = instance;
}
@Override
protected WeexMapView initComponentHostView(@NonNull Context context) {
//獲得WeexMapView的對象
this.mapView = new WeexMapView(context);
return this.mapView;
}
@Override
protected void onCreate() {
super.onCreate();
}
@Override
public void onActivityDestroy() {
super.onActivityDestroy();
}
@WXComponentProp(name = "model")
public void setMapModel(int model) {
mapView.setMapModel(model);
}
//設定預設定位按鈕是否顯示,非必需設定。
@WXComponentProp(name = "showLocationButton")
public void showLocationButton(boolean isShow){
mapView.showLocationButton(isShow);
}
// 設定為true表示啟動顯示定位藍點,false表示隐藏定位藍點并不進行定位,預設是false。
@WXComponentProp(name = "showLocationPoint")
public void showLocationPoint(boolean isShow)
{
mapView.showLocationPoint(isShow);
}
@WXComponentProp(name = "mapType")
public void setMapType(int type){
mapView.setMapType(type);
}
@JSMethod(uiThread = true)
public void addMarker(float lnt, float lat, String title, String content,
boolean draggable, boolean setFlat, boolean isAnimation, long duration,
JSCallback clickCallback,JSCallback dragCallback) {
LatLng latLng = new LatLng(lnt,lat);
MarkerOptions markerOption = new MarkerOptions();
markerOption.position(latLng);
markerOption.title(title).snippet(content);
markerOption.draggable(draggable);//設定Marker可拖動
markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
.decodeResource(wxInstance.getContext().getResources(), R.drawable.cercle)));
// 将Marker設定為貼地顯示,可以雙指下拉地圖檢視效果
markerOption.setFlat(setFlat);//設定marker平貼地圖效果
Marker marker=mapView.getaMap().addMarker(markerOption);
if(isAnimation){
Animation animation = new RotateAnimation(marker.getRotateAngle(),marker.getRotateAngle()+180,0,0,0);
animation.setDuration(duration);
animation.setInterpolator(new LinearInterpolator());
marker.setAnimation(animation);
marker.startAnimation();
}
mapView.getaMap().setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
marker.showInfoWindow();
return true;
}
});
mapView.getaMap().setOnMarkerDragListener(new AMap.OnMarkerDragListener() {
@Override
public void onMarkerDragStart(Marker marker) {
}
@Override
public void onMarkerDrag(Marker marker) {
}
@Override
public void onMarkerDragEnd(Marker marker) {
}
});
}
@JSMethod(uiThread = true)
public void addCircle(float lat,float lng,int radius,int strokeWidth){
LatLng latLng=new LatLng(lat,lng);
mapView.getaMap().addCircle(new CircleOptions().
center(latLng).radius(radius).fillColor(Color.BLUE).
strokeColor(Color.RED).strokeWidth(strokeWidth));
}
@JSMethod(uiThread = true)
public void addLine(ArrayList list) throws JSONException {
ArrayList<LatLng> latLngList=new ArrayList<LatLng>();
for(int i=0;i<list.size();i++){
com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);
BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");
BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");
float lat=bigLat.floatValue();
float lng=bigLng.floatValue();
// Log.d(lat+"-"+lng,"經緯度");
LatLng latLng=new LatLng(lat,lng);
latLngList.add(latLng);
}
mapView.getaMap().addPolyline(new PolylineOptions().addAll(latLngList).width(10).color(Color.BLUE));
}
@JSMethod(uiThread = true)
public void addTileOverlay(ArrayList list){
ArrayList<LatLng> latLngList=new ArrayList<LatLng>();
for(int i=0;i<list.size();i++){
com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);
BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");
BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");
float lat=bigLat.floatValue();
float lng=bigLng.floatValue();
// Log.d(lat+"-"+lng,"經緯度");
LatLng latLng=new LatLng(lat,lng);
latLngList.add(latLng);
}
// 建構熱力圖 HeatmapTileProvider
HeatmapTileProvider.Builder builder = new HeatmapTileProvider.Builder();
builder.data(latLngList); // 設定熱力圖繪制的資料
// .gradient(A); // 設定熱力圖漸變,有預設值 DEFAULT_GRADIENT,可不設定該接口
// Gradient 的設定可見參考手冊
// 構造熱力圖對象
HeatmapTileProvider heatmapTileProvider = builder.build();
// 初始化 TileOverlayOptions
TileOverlayOptions tileOverlayOptions = new TileOverlayOptions();
tileOverlayOptions.tileProvider(heatmapTileProvider); // 設定瓦片圖層的提供者
// 向地圖上添加 TileOverlayOptions 類對象
mapView.getaMap().addTileOverlay(tileOverlayOptions);
}
@JSMethod(uiThread = true)
public void setInfoWindowAdapter(){
mapView.getaMap().setInfoWindowAdapter(new AMap.InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker marker) {
return null;
}
View infoWindow = null;
@Override
public View getInfoContents(Marker marker) {
if(infoWindow == null) {
infoWindow = LayoutInflater.from(wxInstance.getContext()).inflate(
R.layout.custom_info_window, null);
}
// render(marker, infoWindow);
return infoWindow;
//加載custom_info_window.xml布局檔案作為InfoWindow的樣式
}
});
mapView.getaMap().setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
String content=marker.getSnippet().toString();
Toast.makeText(wxInstance.getContext(),content,Toast.LENGTH_LONG).show();
}
});
}
}
值得注意的一點是在H5界面的json數組通過元件的接口傳到原生需要用ArrayList接收,在把ArrayList中的每一個元素轉換成com.alibaba.fastjson.JSONObject。通過JSONObject的get("JsonName"),可以獲得存在json中的值。
for(int i=0;i<list.size();i++){
com.alibaba.fastjson.JSONObject jsonObj=(com.alibaba.fastjson.JSONObject) list.get(i);
BigDecimal bigLat= (BigDecimal) jsonObj.get("latitude");
BigDecimal bigLng= (BigDecimal) jsonObj.get("longitude");
float lat=bigLat.floatValue();
float lng=bigLng.floatValue();
// Log.d(lat+"-"+lng,"經緯度");
LatLng latLng=new LatLng(lat,lng);
latLngList.add(latLng);
}
3、開發WXMapModule元件
建立WXLocationModule 繼承WXModule類,其中添加@JSMethod的方法可以在H5界面調用。
public class WXLocationModule extends WXModule{
@JSMethod
public void getLocationInfo(float longitude,float latitude,final JSCallback callback) {
GeocodeSearch geocoderSearch = new GeocodeSearch(mWXSDKInstance.getContext());//位置搜對象
LatLonPoint point=new LatLonPoint(longitude,latitude);//坐标
float range=200;//範圍
RegeocodeQuery query=new RegeocodeQuery(point,200,GeocodeSearch.AMAP);
geocoderSearch.getFromLocationAsyn(query);
geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
@Override
public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {//獲得位置資訊的回調方法
Map<String, Object> map = new HashMap<>();
map.put("locationInfo", regeocodeResult);
callback.invokeAndKeepAlive(map);
}
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
}
});
}
@JSMethod
public void getLocationByName(String name,String cityCode,final JSCallback callback){
GeocodeSearch geocoderSearch = new GeocodeSearch(mWXSDKInstance.getContext());//位置搜對象
// name表示位址,第二個參數表示查詢城市,中文或者中文全拼,citycode、adcode
GeocodeQuery query = new GeocodeQuery(name,cityCode);
geocoderSearch.getFromLocationNameAsyn(query);
geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
@Override
public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
}
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
Map<String, Object> map = new HashMap<>();
map.put("location", geocodeResult);
callback.invokeAndKeepAlive(map);
}
});
}
@JSMethod
public void getWeatherInfo(String pace,String type){
//檢索參數為城市和天氣類型,實況天氣為WEATHER_TYPE_LIVE、天氣預報為WEATHER_TYPE_FORECAST
}
@JSMethod
public void getDistance(LatLng latLng1,LatLng latLng2){
float distance = AMapUtils.calculateLineDistance(latLng1,latLng2);
}
@JSMethod
public void downloadMapOffline(String cityname) throws AMapException {
//構造OfflineMapManager對象
amapManager = new OfflineMapManager(mWXSDKInstance.getContext(), new OfflineMapManager.OfflineMapDownloadListener() {
@Override
public void onDownload(int i, int i1, String s) {
}
@Override
public void onCheckUpdate(boolean b, String s) {
}
@Override
public void onRemove(boolean b, String s, String s1) {
}
});
//按照citycode下載下傳
// amapManager.downloadByCityCode(String citycode);
//按照cityname下載下傳
amapManager.downloadByCityName(cityname);
// amapManager.pause();
// amapManager.stop();
// 設定應用單獨的地圖存儲目錄
// MapsInitializer.sdcardDir = "自定義的目錄";
}
@JSMethod
public void updateOfflineCityByName(String cityname) throws AMapException {
//通過updateOfflineCityByName方法判斷離線地圖資料是否存在更新
amapManager.updateOfflineCityByName(cityname);
}
public void deleteOfflineCityByName(String cityName){
//删除某一城市的離線地圖包
amapManager.remove(cityName);
}
@JSMethod
public void getDownloadOfflineMapCityList(){
// 擷取城市清單
ArrayList<OfflineMapCity> offlineMapCityList = amapManager.getOfflineMapCityList();
// 擷取省清單
ArrayList<OfflineMapProvince> offlineMapProvinceList = amapManager.getOfflineMapProvinceList();
// 擷取已下載下傳城市清單
ArrayList<OfflineMapCity> downloadOfflineMapCityList = amapManager.getDownloadOfflineMapCityList();
// 擷取正在或等待下載下傳城市清單
ArrayList<OfflineMapCity> downloadingCityList = amapManager.getDownloadingCityList();
}
}
4、注冊Component和Module
在建立myAplication繼承Application,在其onCreate()方法中注冊元件。
三、元件主要功能及使用方法
1)WXlocationModule使用
在H5中引入元件:
var location=weex.requireModule('Location');
1、根據描述和城市編碼獲得坐标資訊
location.getLocationByName('廊坊市廣陽區新奧科技園B座','0316',function (res) {
self.point=res.location.geocodeAddressList[0].latLonPoint;//獲得坐标資訊
});
2、根據坐标獲得位置資訊
location.getLocationInfo(lat,lnt,function (res) {
var info=res;
});
3、獲得天氣資訊
location.getWeatherInfo('北京市','now',function (res) {
var weatherInfo=res;
});
4、得到兩個坐标點之間的距離
location.getDistance(latLng1,latLng2,function (res) {
var distance=res;
});
5、離線地圖相關
location.downloadMapOffline(cityname);//下載下傳離線地圖,可設定下載下傳路徑
location.deleteOfflineCityByName(cityName);//删除離線地圖
location.getDownloadOfflineMapCityList()//獲得離線地圖清單
2)WXMapComponent使用
在H5中使用元件:
<map ref="myMap" style="width: 750px;height: 1300px" showLocationButton="true" model="1" showLocationPoint="true" mapType="1">
</map>
showLocationButton:是否顯示定位按鈕
Model:定位方式
mapType:地圖模式(衛星圖,夜間圖等)
showLocationPoint:是否顯示目前所在點的标示圖
1、顯示地圖上某個坐标處的标示,點選顯示提示資訊
this.$refs.myMap.addMarker(lat, lnt, '新奧科技園', '新奧科技園B座',
true, false, true, 1.00, //參數:經度、緯度、标題、内容、是否可拖動、是否平貼地圖、是否使用動畫、動畫時間
function (res) {//點選事件
modal.toast({message:'click'})
},function (res) {//拖動事件
modal.toast({message:'drag'})
});
2、以某個坐标點為圓心,畫一個圓形圖
self.$refs.myMap.addCircle(self.point.latitude,self.point.longitude,1000,20);
第一個和第二個參數分别為圓心的經度和緯度坐标,第三個參數為半徑,第四個參數為圓形的線的寬度
3、在地圖上繪制線
self.$refs.myMap.addLine(self.pointList);
參數是一個坐标點的集合
4、在地圖上繪制熱力圖層
self.$refs.myMap.addTileOverlay(self.pointList);
參數是一個坐标的集合