先看一下效果 android
其實高德地圖示例中心已經有不少現成的demo了,能夠根據項目需求,下載demo自行查看git
高德地圖android API地址:lbs.amap.com/api/android…api
高德地圖示例中心:lbs.amap.com/dev/demo數組
由於公司目前開發的項目,地圖模塊並非側重點,因此定位地址作得很簡易化。需求包括:定位當前位置,自動搜索周邊,搜索位置,選擇位置。下面會對代碼進行說明。安全
1.固然,首先得去高德地圖開放平臺中註冊帳號,建立應用bash
其中發佈版安全碼SHA1的獲取方式,請點擊高德地圖官方說明自行查看: lbs.amap.com/faq/android…2.在app的build.gradle文件中引入地圖包,這邊我使用的是3d地圖,包括基礎地圖包、定位地圖包和搜索地圖包網絡
dependencies {
//高德地圖 3D地圖
implementation 'com.amap.api:location:latest.integration'
implementation 'com.amap.api:search:latest.integration'
implementation 'com.amap.api:3dmap:latest.integration'
}
複製代碼
3.在AndroidManifest.xml清單文件中,application裏面配置以下app
<!--高德地圖-->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="申請應用的Key值"/>
複製代碼
接下來就能夠正式開發了ide
4.頂部的透明浮窗效果shape_map_top_bg.xml,定義一個漸變的透明度背景函數
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<item android:gravity="center">
<shape>
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"/>
<gradient
android:angle="270"
android:startColor="#6C000000"
android:endColor="#00000000"
android:type="linear" />
</shape>
</item>
</layer-list>
複製代碼
5.定義Activity的佈局文件activity_map_layout1.xml,頂部的搜索框佈局layout_edit,後面我會在代碼中動態設置其高度
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.amap.api.maps.MapView
android:id="@+id/mMapView"
android:layout_above="@+id/layout_bottom"
android:layout_marginBottom="-20dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:paddingTop="25dp"
android:background="@drawable/shape_map_top_bg">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--@mipmap/icon_map_top_bg-->
<TextView
android:id="@+id/tv_cancle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:gravity="center"
android:textColor="@color/colorWhite"
android:text="取消"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="13dp"
android:paddingRight="13dp"
android:paddingTop="8.5dp"
android:paddingBottom="8.5dp"
android:layout_centerVertical="true"
android:gravity="center"
android:layout_marginRight="15dp"
android:layout_alignParentRight="true"
android:textColor="@color/colorWhite"
android:background="@drawable/btn_bg"
android:text="肯定"
android:textSize="16sp" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/layout_location"
android:layout_width="48dp"
android:layout_height="48dp"
android:gravity="center"
android:layout_above="@+id/layout_bottom"
android:layout_alignParentRight="true"
android:layout_marginRight="22dp"
android:layout_marginBottom="43dp"
android:background="@drawable/shape_map_location_bg">
<TextView
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@mipmap/icon_map_location"/>
</LinearLayout>
<LinearLayout
android:id="@+id/layout_bottom"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="vertical"
android:background="@drawable/shape_white_bg_top"
android:layout_alignParentBottom="true"
android:minWidth="280dp">
<RelativeLayout
android:id="@+id/layout_edit"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="15dp"
android:background="@drawable/search_map_bg"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_search"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:src="@mipmap/icon_map_search" />
<AutoCompleteTextView
android:id="@+id/keyWord"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10.5dp"
android:layout_toRightOf="@+id/iv_search"
android:background="@null"
android:layout_marginRight="15dp"
android:hint="搜索地點"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="@color/color_333333"
android:textColorHint="@color/color_666666"
android:textSize="17sp" />
</RelativeLayout>
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:scrollbars="none"
android:fadingEdge="none"
android:overScrollMode="never"
android:cacheColorHint="#00000000"
android:listSelector="@android:color/transparent" />
</LinearLayout>
</RelativeLayout>
</layout>
複製代碼
6.爲了防止地圖的搜索框,在觸發鍵盤後,由於高度不夠而被輸入法蓋住了,因此選擇動態控制底部搜索框的高度,代碼以下:
RelativeLayout.LayoutParams linearParams = (RelativeLayout.LayoutParams) bindingView.layoutBottom.getLayoutParams(); //取控件textView當前的佈局參數
int height = DensityUtil.getDisplayHeight() / 5 * 3;
linearParams.height = height;// 控件的高強制設成
bindingView.layoutBottom.setLayoutParams(linearParams); //使設置好的佈局參數應用到控件
複製代碼
7.請求權限的相關代碼(作android6.0以上的適配)
//是否須要檢測後臺定位權限,設置爲true時,若是用戶沒有給予後臺定位權限會彈窗提示
private boolean needCheckBackLocation = false;
//若是設置了target > 28,須要增長這個權限,不然不會彈出"始終容許"這個選擇框
private static String BACK_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION";
/*************************************** 權限檢查******************************************************/
/**
* 須要進行檢測的權限數組
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
// Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
private static final int PERMISSON_REQUESTCODE = 0;
/**
* 判斷是否須要檢測,防止不停的彈框
*/
private boolean isNeedCheck = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT > 28
&& getApplicationContext().getApplicationInfo().targetSdkVersion > 28) {
needPermissions = new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
needCheckBackLocation = true;
}
}
/**
* 方法必須重寫
*/
@Override
protected void onResume() {
try {
super.onResume();
bindingView.mMapView.onResume();
if (Build.VERSION.SDK_INT >= 23) {
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* @param
* @since 2.5.0
*/
@TargetApi(23)
private void checkPermissions(String... permissions) {
try {
if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) {
List<String> needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
try {
String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]);
Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class, int.class});
method.invoke(this, array, 0);
} catch (Throwable e) {
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 獲取權限集中須要申請權限的列表
*
* @param permissions
* @return
* @since 2.5.0
*/
@TargetApi(23)
private List<String> findDeniedPermissions(String[] permissions) {
try {
List<String> needRequestPermissonList = new ArrayList<String>();
if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) {
for (String perm : permissions) {
if (checkMySelfPermission(perm) != PackageManager.PERMISSION_GRANTED
|| shouldShowMyRequestPermissionRationale(perm)) {
if (!needCheckBackLocation
&& BACK_LOCATION_PERMISSION.equals(perm)) {
continue;
}
needRequestPermissonList.add(perm);
}
}
}
return needRequestPermissonList;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
private int checkMySelfPermission(String perm) {
try {
Method method = getClass().getMethod("checkSelfPermission", new Class[]{String.class});
Integer permissionInt = (Integer) method.invoke(this, perm);
return permissionInt;
} catch (Throwable e) {
}
return -1;
}
private boolean shouldShowMyRequestPermissionRationale(String perm) {
try {
Method method = getClass().getMethod("shouldShowRequestPermissionRationale", new Class[]{String.class});
Boolean permissionInt = (Boolean) method.invoke(this, perm);
return permissionInt;
} catch (Throwable e) {
}
return false;
}
/**
* 檢測是否說有的權限都已經受權
*
* @param grantResults
* @return
* @since 2.5.0
*/
private boolean verifyPermissions(int[] grantResults) {
try {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return true;
}
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] paramArrayOfInt) {
try {
if (Build.VERSION.SDK_INT >= 23) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) {
showMissingPermissionDialog();
isNeedCheck = false;
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 顯示提示信息
*
* @since 2.5.0
*/
private void showMissingPermissionDialog() {
try {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("當前應用缺乏必要權限。\\n\\n請點擊\\\"設置\\\"-\\\"權限\\\"-打開所需權限");
// 拒絕, 退出應用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
finish();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("設置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
startAppSettings();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setCancelable(false);
builder.show();
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 啓動應用的設置
*
* @since 2.5.0
*/
private void startAppSettings() {
try {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
} catch (Throwable e) {
e.printStackTrace();
}
}
複製代碼
8.顯示地圖的方式,請查看高德地圖官方說明 lbs.amap.com/api/android…
9.接下來我要說明的是我遇到的一種狀況:手機定位關閉後再次開啓,locationManager.getLastKnownLocation(provider)=null,我是這樣解決的:
首先,在oncreate初始化時,依然獲取最後一次定位的位置,並記下當前的最後一次位置lastLocation;
爲locationManager設置LocationListener監聽,包括GPS和NETWORK監聽;
一旦監聽到位置後,就會觸發onLocationChanged方法,這時候判斷lastLocation=null,就更新當前位置;
這樣就能夠解決位置關閉後開啓沒有辦法定位,又能防止搜索位置後,一直要定位到當前的這種狀況
好了,MapActivity的完整代碼以下:
public class MapActivity2 extends BaseActivity<AddressViewModel, ActivityMapLayout1Binding> implements LocationSource,
AMapLocationListener, GeocodeSearch.OnGeocodeSearchListener, PoiSearch.OnPoiSearchListener { // Inputtips.InputtipsListener
// private ListView listView;
// private SegmentedGroup mSegmentedGroup;
// private AutoCompleteTextView searchText;
private AMap aMap;
// private MapView mapView;
private OnLocationChangedListener mListener;
private AMapLocationClient mlocationClient;
private AMapLocationClientOption mLocationOption;
private String[] items = {"", "學校", "樓宇", "商場"};
private Marker locationMarker;
private ProgressDialog progDialog = null;
private GeocodeSearch geocoderSearch;
private int currentPage = 0;// 當前頁面,從0開始計數
private PoiSearch.Query query;// Poi查詢條件類
private PoiSearch poiSearch;
private List<PoiItem> poiItems;// poi數據
private String searchType = items[0];
private String searchKey = "";
private LatLonPoint searchLatlonPoint;
private List<PoiItem> resultData = new ArrayList<>();
private MapSearchResultAdapter searchResultAdapter;
private boolean isItemClickAction;
private List<Tip> autoTips;
private boolean isfirstinput = true;
private PoiItem firstItem;
//是否須要檢測後臺定位權限,設置爲true時,若是用戶沒有給予後臺定位權限會彈窗提示
private boolean needCheckBackLocation = false;
//若是設置了target > 28,須要增長這個權限,不然不會彈出"始終容許"這個選擇框
private static String BACK_LOCATION_PERMISSION = "android.permission.ACCESS_BACKGROUND_LOCATION";
/*************************************** 權限檢查******************************************************/
/**
* 須要進行檢測的權限數組
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
// Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
private static final int PERMISSON_REQUESTCODE = 0;
/**
* 判斷是否須要檢測,防止不停的彈框
*/
private boolean isNeedCheck = true;
// private String searchCity = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT > 28
&& getApplicationContext().getApplicationInfo().targetSdkVersion > 28) {
needPermissions = new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
BACK_LOCATION_PERMISSION
};
needCheckBackLocation = true;
}
setContentView(R.layout.activity_map_layout1);
showContentView();
// if (getIntent() != null && getIntent().getExtras() != null){
// searchCity = getIntent().getExtras().getString("searchCity");
// }
boolean is = isLocationEnabled();
bindingView.mMapView.onCreate(savedInstanceState);
init();
initView();
}
private void initView() {
bindingView.tvCancle.setOnClickListener(view -> {
finish();
});
RelativeLayout.LayoutParams linearParams = (RelativeLayout.LayoutParams) bindingView.layoutBottom.getLayoutParams(); //取控件textView當前的佈局參數
int height = DensityUtil.getDisplayHeight() / 5 * 3;
linearParams.height = height;// 控件的高強制設成
bindingView.layoutBottom.setLayoutParams(linearParams); //使設置好的佈局參數應用到控件
bindingView.tvConfirm.setOnClickListener(view -> {
PoiItem item = resultData.get(searchResultAdapter.getSelectedPosition());
Intent intent = new Intent();
intent.putExtra("PoiItem", item);
setResult(1, intent);
finish();
});
bindingView.layoutLocation.setOnClickListener(view -> {
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(lastLatLng, 16));
});
searchResultAdapter = new MapSearchResultAdapter(MapActivity2.this);
bindingView.listview.setAdapter(searchResultAdapter);
bindingView.listview.setOnItemClickListener(onItemClickListener);
bindingView.keyWord.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String newText = s.toString().trim();
if (newText.length() > 0) {
InputtipsQuery inputquery = new InputtipsQuery(newText, "");//searchCity
Inputtips inputTips = new Inputtips(MapActivity2.this, inputquery);
inputquery.setCityLimit(true);
inputTips.setInputtipsListener(inputtipsListener);
inputTips.requestInputtipsAsyn();
}
// else {
// doSearchQuery();
// }
}
@Override
public void afterTextChanged(Editable s) {
}
});
// bindingView.keyWord.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @Override
// public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Log.i("MY", "setOnItemClickListener");
// if (autoTips != null && autoTips.size() > position) {
// Tip tip = autoTips.get(position);
// searchPoi(tip);
// }
// }
// });
geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(this);
progDialog = new ProgressDialog(this);
// hideSoftKey(bindingView.keyWord);
}
/**
* 初始化
*/
private void init() {
if (aMap == null) {
aMap = bindingView.mMapView.getMap();
setUpMap();
}
aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
searchLatlonPoint = new LatLonPoint(cameraPosition.target.latitude, cameraPosition.target.longitude);
if (!isItemClickAction && !isInputKeySearch) {
geoAddress();
startJumpAnimation();
}
isInputKeySearch = false;
isItemClickAction = false;
}
});
aMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
@Override
public void onMapLoaded() {
addMarkerInScreenCenter(null);
}
});
setLocalLocation();
}
/**
* 顯示當前定位
*/
private LocationManager locationManager;
private void setLocalLocation() {
// 調用getSystemService()方法來獲取LocationManager對象
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//locationManager.setTestProviderEnabled("gps", true);
// 指定LocationManager的定位方法
// String provider = LocationManager.GPS_PROVIDER;
// 調用getLastKnownLocation()方法獲取當前的位置信息
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, mLocationListener01);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0, mLocationListener01);
lastLocation = getLastKnownLocation();
updateToNewLocation(lastLocation);
}
private Location lastLocation;
// 設置監聽器,自動更新的最小時間爲間隔N秒(1秒爲1*1000,這樣寫主要爲了方便)或最小位移變化超過N米
public final LocationListener mLocationListener01 = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// if (!isLocationEnabled()){
// ToastUtil.showToast("位置信息關閉,請開啓");
// }
if (lastLocation == null) {//防止定位關閉開啓後定位不了
lastLocation = location;
updateToNewLocation(location);
}
// Location location = locationManager.getLastKnownLocation(provider);
// Location location = getLastKnownLocation();
}
@Override
public void onProviderDisabled(String provider) {
// updateToNewLocation(null);
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
/**
* 獲取數據和監聽器
* 經過location獲取當前設備的具體位置
*
* @param location
* @return
*/
private void updateToNewLocation(Location location) {
if (location != null) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());//構造一個位置
lastLatLng = latLng;
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
} else {
LatLng latLng = new LatLng(39.904989, 116.405285);// 北京市經緯度
lastLatLng = latLng;
isInputKeySearch = false;
isItemClickAction = false;
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
}
}
/**
* 判判定位服務是否開啓
*
* @param
* @return true 表示開啓
*/
public boolean isLocationEnabled() {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
locationMode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return false;
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
private Location getLastKnownLocation() {
// locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = locationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return null;
}
Location l = locationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l); bestLocation = l; } } return bestLocation; } private LatLng lastLatLng; /** * 設置一些amap的屬性 */ private void setUpMap() { aMap.getUiSettings().setZoomControlsEnabled(false); aMap.setLocationSource(this);// 設置定位監聽 aMap.getUiSettings().setMyLocationButtonEnabled(true);// 設置默認定位按鈕是否顯示 aMap.setMyLocationEnabled(false);// 設置爲true表示顯示定位層並可觸發定位,false表示隱藏定位層並不可觸發定位,默認是false aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE); } /** * 方法必須重寫 */ @Override protected void onResume() { try { super.onResume(); bindingView.mMapView.onResume(); if (Build.VERSION.SDK_INT >= 23) { if (isNeedCheck) { checkPermissions(needPermissions); } } } catch (Throwable e) { e.printStackTrace(); } } /** * 方法必須重寫 */ @Override protected void onPause() { super.onPause(); bindingView.mMapView.onPause(); deactivate(); } /** * 方法必須重寫 */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); bindingView.mMapView.onSaveInstanceState(outState); } /** * 方法必須重寫 */ @Override public void onDestroy() { super.onDestroy(); bindingView.mMapView.onDestroy(); if (null != mlocationClient) { mlocationClient.onDestroy(); } locationManager.removeUpdates(mLocationListener01); // locationManager.setTestProviderEnabled(provider, false); } /** * 定位成功後回調函數 */ @Override public void onLocationChanged(AMapLocation amapLocation) { // Log.i("MY", "onLocationChanged"); if (mListener != null && amapLocation != null) { if (amapLocation != null && amapLocation.getErrorCode() == 0) { mListener.onLocationChanged(amapLocation); LatLng curLatlng = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude()); searchLatlonPoint = new LatLonPoint(curLatlng.latitude, curLatlng.longitude); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f)); isInputKeySearch = false; bindingView.keyWord.setText(""); } else { String errText = "定位失敗," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo(); Log.e("AmapErr", errText); } } } /** * 激活定位 */ @Override public void activate(OnLocationChangedListener listener) { mListener = listener; if (mlocationClient == null) { mlocationClient = new AMapLocationClient(this); mLocationOption = new AMapLocationClientOption(); //設置定位監聽 mlocationClient.setLocationListener(this); //設置爲高精度定位模式 mLocationOption.setOnceLocation(true); mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); //設置定位參數 mlocationClient.setLocationOption(mLocationOption); // 此方法爲每隔固定時間會發起一次定位請求,爲了減小電量消耗或網絡流量消耗, // 注意設置合適的定位時間的間隔(最小間隔支持爲2000ms),而且在合適時間調用stopLocation()方法來取消定位請求 // 在定位結束後,在合適的生命週期調用onDestroy()方法 // 在單次定位狀況下,定位不管成功與否,都無需調用stopLocation()方法移除請求,定位sdk內部會移除 mlocationClient.startLocation(); } } /** * 中止定位 */ @Override public void deactivate() { mListener = null; if (mlocationClient != null) { mlocationClient.stopLocation(); mlocationClient.onDestroy(); } mlocationClient = null; } /** * 響應逆地理編碼 */ public void geoAddress() { // Log.i("MY", "geoAddress"+ searchLatlonPoint.toString()); // showDialog(); bindingView.keyWord.setText(""); if (searchLatlonPoint != null) { RegeocodeQuery query = new RegeocodeQuery(searchLatlonPoint, 200, GeocodeSearch.AMAP);// 第一個參數表示一個Latlng,第二參數表示範圍多少米,第三個參數表示是火系座標系仍是GPS原生座標系 geocoderSearch.getFromLocationAsyn(query); } } /** * 開始進行poi搜索 */ /** * 開始進行poi搜索 */ protected void doSearchQuery() { // Log.i("MY", "doSearchQuery"); currentPage = 0; query = new PoiSearch.Query(searchKey, searchType, "");// 第一個參數表示搜索字符串,第二個參數表示poi搜索類型,第三個參數表示poi搜索區域(空字符串表明全國) query.setCityLimit(true); query.setPageSize(20); query.setPageNum(currentPage); if (searchLatlonPoint != null) { poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(this); poiSearch.setBound(new PoiSearch.SearchBound(searchLatlonPoint, 1000, true));// poiSearch.searchPOIAsyn(); } } @Override public void onRegeocodeSearched(RegeocodeResult result, int rCode) { // dismissDialog(); if (rCode == AMapException.CODE_AMAP_SUCCESS) { if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) { String address = result.getRegeocodeAddress().getProvince() + result.getRegeocodeAddress().getCity() + result.getRegeocodeAddress().getDistrict() + result.getRegeocodeAddress().getTownship(); firstItem = new PoiItem("regeo", searchLatlonPoint, address, address); doSearchQuery(); } } else { // Toast.makeText(MapActivity2.this, "error code is " + rCode, Toast.LENGTH_SHORT).show(); } } @Override public void onGeocodeSearched(GeocodeResult result, int rCode) { if (rCode == AMapException.CODE_AMAP_SUCCESS) { if (result != null && result.getGeocodeAddressList() != null && result.getGeocodeAddressList() != null) { String address = result.getGeocodeAddressList().get(0).getProvince() + result.getGeocodeAddressList().get(0).getCity() + result.getGeocodeAddressList().get(0).getDistrict() + result.getGeocodeAddressList().get(0).getTownship(); firstItem = new PoiItem("regeo", searchLatlonPoint, address, address); doSearchQuery(); } } else { // Toast.makeText(MapActivity2.this, "error code is " + rCode, Toast.LENGTH_SHORT).show(); } } /** * POI搜索結果回調 * * @param poiResult 搜索結果 * @param resultCode 錯誤碼 */ @Override public void onPoiSearched(PoiResult poiResult, int resultCode) { if (resultCode == AMapException.CODE_AMAP_SUCCESS) { if (poiResult != null && poiResult.getQuery() != null) { if (poiResult.getQuery().equals(query)) { poiItems = poiResult.getPois(); if (poiItems != null && poiItems.size() > 0) { updateListview(poiItems); } else { // Toast.makeText(MapActivity2.this, "無搜索結果", Toast.LENGTH_SHORT).show(); } } } else { // Toast.makeText(MapActivity2.this, "無搜索結果", Toast.LENGTH_SHORT).show(); } } } /** * 更新列表中的item * * @param poiItems */ private void updateListview(List<PoiItem> poiItems) { resultData.clear(); searchResultAdapter.setSelectedPosition(0); resultData.add(firstItem); resultData.addAll(poiItems); searchResultAdapter.setData(resultData); searchResultAdapter.notifyDataSetChanged(); } @Override public void onPoiItemSearched(PoiItem poiItem, int i) { } AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (position != searchResultAdapter.getSelectedPosition()) { PoiItem poiItem = (PoiItem) searchResultAdapter.getItem(position); LatLng curLatlng = new LatLng(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude()); isItemClickAction = true; aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f)); searchResultAdapter.setSelectedPosition(position); searchResultAdapter.notifyDataSetChanged(); } } }; public void showDialog() { progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progDialog.setIndeterminate(false); progDialog.setCancelable(true); progDialog.setMessage("正在加載..."); progDialog.show(); } public void dismissDialog() { if (progDialog != null) { progDialog.dismiss(); } } private void addMarkerInScreenCenter(LatLng locationLatLng) { LatLng latLng = aMap.getCameraPosition().target; Point screenPosition = aMap.getProjection().toScreenLocation(latLng); locationMarker = aMap.addMarker(new MarkerOptions() .anchor(0.5f, 0.5f) .icon(BitmapDescriptorFactory.fromResource(R.mipmap.purple_pin))); //設置Marker在屏幕上,不跟隨地圖移動 locationMarker.setPositionByPixels(screenPosition.x, screenPosition.y); locationMarker.setZIndex(1); } /** * 屏幕中心marker 跳動 */ public void startJumpAnimation() { if (locationMarker != null) { //根據屏幕距離計算須要移動的目標點 final LatLng latLng = locationMarker.getPosition(); Point point = aMap.getProjection().toScreenLocation(latLng); point.y -= dip2px(this, 125); LatLng target = aMap.getProjection() .fromScreenLocation(point); //使用TranslateAnimation,填寫一個須要移動的目標點 Animation animation = new TranslateAnimation(target); animation.setInterpolator(new Interpolator() { @Override public float getInterpolation(float input) { // 模擬重加速度的interpolator if (input <= 0.5) { return (float) (0.5f - 2 * (0.5 - input) * (0.5 - input)); } else { return (float) (0.5f - Math.sqrt((input - 0.5f) * (1.5f - input))); } } }); //整個移動所須要的時間 animation.setDuration(600); //設置動畫 locationMarker.setAnimation(animation); //開始動畫 locationMarker.startAnimation(); } else { Log.e("ama", "screenMarker is null"); } } //dip和px轉換 private static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } private void searchAllPoi(Tip result) { isInputKeySearch = true; inputSearchKey = result.getName();//getAddress(); // + result.getRegeocodeAddress().getCity() + result.getRegeocodeAddress().getDistrict() + result.getRegeocodeAddress().getTownship(); searchLatlonPoint = result.getPoint(); firstItem = new PoiItem("tip", searchLatlonPoint, inputSearchKey, result.getAddress()); firstItem.setCityName(result.getDistrict()); firstItem.setAdName(""); searchResultAdapter.setSelectedPosition(0); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(searchLatlonPoint.getLatitude(), searchLatlonPoint.getLongitude()), 16f)); // hideSoftKey(bindingView.keyWord); doSearchQuery(); } Inputtips.InputtipsListener inputtipsListener = new Inputtips.InputtipsListener() { @Override public void onGetInputtips(List<Tip> list, int rCode) { if (rCode == AMapException.CODE_AMAP_SUCCESS) {// 正確返回 autoTips = list; resultData.clear(); if (autoTips != null && autoTips.size() != 0) { searchAllPoi(autoTips.get(0)); } // for (int i = 0; i < autoTips.size(); i++){ // Tip tip = autoTips.get(i); // searchAllPoi(autoTips.get(0)); // } // List<String> listString = new ArrayList<String>(); // for (int i = 0; i < list.size(); i++) { // listString.add(list.get(i).getName()); // } // ArrayAdapter<String> aAdapter = new ArrayAdapter<String>( // getApplicationContext(), // R.layout.route_inputs, listString); // bindingView.keyWord.setAdapter(aAdapter); // aAdapter.notifyDataSetChanged(); // if (isfirstinput) { // isfirstinput = false; // bindingView.keyWord.showDropDown(); // } } else { // Toast.makeText(MapActivity2.this, "erroCode " + rCode , Toast.LENGTH_SHORT).show(); } } }; private boolean isInputKeySearch; private String inputSearchKey; private void searchPoi(Tip result) { isInputKeySearch = true; inputSearchKey = result.getName();//getAddress(); // + result.getRegeocodeAddress().getCity() + result.getRegeocodeAddress().getDistrict() + result.getRegeocodeAddress().getTownship(); searchLatlonPoint = result.getPoint(); firstItem = new PoiItem("tip", searchLatlonPoint, inputSearchKey, result.getAddress()); firstItem.setCityName(result.getDistrict()); firstItem.setAdName(""); resultData.clear(); searchResultAdapter.setSelectedPosition(0); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(searchLatlonPoint.getLatitude(), searchLatlonPoint.getLongitude()), 16f)); // hideSoftKey(bindingView.keyWord); doSearchQuery(); } private void hideSoftKey(View view) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(view, InputMethodManager.SHOW_FORCED); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } /** * @param * @since 2.5.0 */ @TargetApi(23) private void checkPermissions(String... permissions) { try { if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) { List<String> needRequestPermissonList = findDeniedPermissions(permissions); if (null != needRequestPermissonList && needRequestPermissonList.size() > 0) { try { String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]); Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class, int.class}); method.invoke(this, array, 0); } catch (Throwable e) { } } } } catch (Throwable e) { e.printStackTrace(); } } /** * 獲取權限集中須要申請權限的列表 * * @param permissions * @return * @since 2.5.0 */ @TargetApi(23) private List<String> findDeniedPermissions(String[] permissions) { try { List<String> needRequestPermissonList = new ArrayList<String>(); if (Build.VERSION.SDK_INT >= 23 && getApplicationInfo().targetSdkVersion >= 23) { for (String perm : permissions) { if (checkMySelfPermission(perm) != PackageManager.PERMISSION_GRANTED || shouldShowMyRequestPermissionRationale(perm)) { if (!needCheckBackLocation && BACK_LOCATION_PERMISSION.equals(perm)) { continue; } needRequestPermissonList.add(perm); } } } return needRequestPermissonList; } catch (Throwable e) { e.printStackTrace(); } return null; } private int checkMySelfPermission(String perm) { try { Method method = getClass().getMethod("checkSelfPermission", new Class[]{String.class}); Integer permissionInt = (Integer) method.invoke(this, perm); return permissionInt; } catch (Throwable e) { } return -1; } private boolean shouldShowMyRequestPermissionRationale(String perm) { try { Method method = getClass().getMethod("shouldShowRequestPermissionRationale", new Class[]{String.class}); Boolean permissionInt = (Boolean) method.invoke(this, perm); return permissionInt; } catch (Throwable e) { } return false; } /** * 檢測是否說有的權限都已經受權 * * @param grantResults * @return * @since 2.5.0 */ private boolean verifyPermissions(int[] grantResults) { try { for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { return false; } } } catch (Throwable e) { e.printStackTrace(); } return true; } @TargetApi(23) public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] paramArrayOfInt) { try { if (Build.VERSION.SDK_INT >= 23) { if (requestCode == PERMISSON_REQUESTCODE) { if (!verifyPermissions(paramArrayOfInt)) { showMissingPermissionDialog(); isNeedCheck = false; } } } } catch (Throwable e) { e.printStackTrace(); } } /** * 顯示提示信息 * * @since 2.5.0 */ private void showMissingPermissionDialog() { try { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("提示"); builder.setMessage("當前應用缺乏必要權限。\\n\\n請點擊\\\"設置\\\"-\\\"權限\\\"-打開所需權限");
// 拒絕, 退出應用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
finish();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("設置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
startAppSettings();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
builder.setCancelable(false);
builder.show();
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 啓動應用的設置
*
* @since 2.5.0
*/
private void startAppSettings() {
try {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
複製代碼