高德地圖定位和附近功能
阿新 • • 發佈:2019-01-22
配置
ndk {
//選擇要新增的對應cpu型別的.so庫。
abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
compile files('libs/AMap3DMap_5.1.0_AMapSearch_5.1.0_AMapLocation_3.4.0_20170518.jar')
許可權
<uses-sdk
android:minSdkVersion ="9"
android:targetSdkVersion="21"
tools:ignore="OldTargetApi" />
<!--高德地圖-->
<!--用於進行網路定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--用於訪問GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--獲取運營商資訊,用於支援提供運營商資訊相關的介面-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--用於訪問wifi網路資訊,wifi資訊會用於進行網路定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--這個許可權用於獲取wifi的獲取許可權,wifi資訊會用來進行網路定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--用於訪問網路,網路定位需要上網-->
<uses-permission android:name="android.permission.INTERNET" />
<!--用於讀取手機當前的狀態-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--寫入擴充套件儲存,向擴充套件卡寫入資料,用於寫入快取定位資料-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--用於申請呼叫A-GPS模組-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!--用於申請獲取藍芽資訊進行室內定位-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
key和service
<meta-data android:name="com.amap.api.v2.apikey"
android:value="申請的key"/>
<service android:name="com.amap.api.location.APSService"/>
程式碼
MainActivity
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.SHAir.qualitytech.cn.R;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, TextWatcher {
private TextView tv_default_address;//預設位置
private EditText et_input_address;//輸入位置
private ImageView iv_input_delete;//刪除按鈕
private TextView tv_reload_address;//當前位置
private TextView tv_reload_location;//重新定位
private RecyclerView recycleView;
private TextView tv_current;
private TextView tv_nearby;
private LinearLayout ll_reload_location;
private ImageView iv_reload;
private ProgressBar progressBar;
//宣告AMapLocationClient類物件
public AMapLocationClient mLocationClient = null;
//宣告AMapLocationClientOption物件
public AMapLocationClientOption mLocationOption = null;
private static double latitude;
private static double longitude;
private static String city;
private static String newText;
private static String cityCode;
private Ada_Change_Location adapter;
private ArrayList<ChangeLocation> inputList;
private ArrayList<ChangeLocation> nearByList;
private String itemAddress;
private String formatAddress;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView((R.layout.fragment_change_address);
adapter = new Ada_Change_Location(getActivity());
initWidget();
initLocationParam();
startLocate();
}
private void startLocate() {
//啟動定位
mLocationClient.startLocation();
iv_reload.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}
public void initWidget() {
tv_default_address = (TextView) getView().findViewById(R.id.tv_default_address);
et_input_address = (EditText) getView().findViewById(R.id.et_input_address);
iv_input_delete = (ImageView) getView().findViewById(R.id.iv_input_delete);
tv_reload_address = (TextView) getView().findViewById(R.id.tv_reload_address);
tv_reload_location = (TextView) getView().findViewById(R.id.tv_reload_location);
recycleView = (RecyclerView) getView().findViewById(R.id.recyclerView_location);
tv_current = (TextView) getView().findViewById(R.id.tv_current);
tv_nearby = (TextView) getView().findViewById(R.id.tv_nearby);
ll_reload_location = (LinearLayout) getView().findViewById(R.id.ll_reload_location);
iv_reload = (ImageView) getView().findViewById(R.id.iv_reload);
progressBar= (ProgressBar) getView().findViewById(R.id.progressBar);
tv_reload_location.setOnClickListener(this);
et_input_address.addTextChangedListener(this);
iv_input_delete.setOnClickListener(this);
recycleView.setLayoutManager(new LinearLayoutManager(getActivity()));
recycleView.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL));
}
/**
* 初始化定位相關配置
*/
private void initLocationParam() {
//初始化定位
mLocationClient = new AMapLocationClient(getContext());
mLocationOption = getDefaultOption();
//給定位客戶端物件設定定位引數
mLocationClient.setLocationOption(mLocationOption);
//設定定位回撥監聽
mLocationClient.setLocationListener(mLocationListener);
//初始化AMapLocationClientOption物件
mLocationOption = new AMapLocationClientOption();
}
/**
* 預設的定位引數
*/
private AMapLocationClientOption getDefaultOption() {
AMapLocationClientOption mOption = new AMapLocationClientOption();
mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可選,設定定位模式,可選的模式有高精度、僅裝置、僅網路。預設為高精度模式
mOption.setHttpTimeOut(30000);//可選,設定網路請求超時時間。預設為30秒。在僅裝置模式下無效
mOption.setNeedAddress(true);//可選,設定是否返回逆地理地址資訊。預設是true
AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可選, 設定網路請求的協議。可選HTTP或者HTTPS。預設為HTTP
mOption.setLocationCacheEnable(true); //可選,設定是否使用快取定位,預設為true
mOption.setWifiScan(true); //可選,設定是否開啟wifi掃描。預設為true,如果設定為false會同時停止主動重新整理,停止以後完全依賴於系統重新整理,定位位置可能存在誤差
return mOption;
}
/**
* 宣告定位回撥監聽器
*/
private AMapLocationListener mLocationListener = new AMapLocationListener() {
public String address;
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (null != aMapLocation) {
if (aMapLocation.getErrorCode() == 0) {
iv_reload.setVisibility(View.VISIBLE);
iv_reload.setImageResource(R.mipmap.layer_4);
latitude = aMapLocation.getLatitude();//緯度
longitude = aMapLocation.getLongitude();//精度
final String province = aMapLocation.getProvince();//省資訊
city = aMapLocation.getCity();//城市
cityCode = aMapLocation.getCityCode();//城市編碼
final String district = aMapLocation.getDistrict();//城區資訊
final String street = aMapLocation.getStreet();//街道資訊
final String streetNum = aMapLocation.getStreetNum();//街道門牌號資訊
final String aoiName = aMapLocation.getAoiName();//獲取當前定位點的AOI資訊
LatLonPoint latLonPoint = new LatLonPoint(latitude, longitude);
address = geocodeToAddress(latLonPoint);
progressBar.setVisibility(View.GONE);
if (address != null && province != null) {
tv_default_address.setText(province);
tv_reload_address.setText(address);
} else if (province != null && district != null && street != null && streetNum != null & aoiName != null) {
tv_default_address.setText(province);
tv_reload_address.setText(province + district + street + streetNum + aoiName);
} else {
tv_default_address.setText("定位失敗");
tv_reload_address.setText("定位失敗,請檢查手機設定");
}
getNearBy();
} else {
tv_default_address.setText("定位失敗");
tv_reload_address.setText("定位失敗,請檢查手機設定");
//定位失敗時,可通過ErrCode(錯誤碼)資訊來確定失敗的原因,errInfo是錯誤資訊,詳見錯誤碼錶。
Log.e("AmapError", "location Error, ErrCode:"
+ aMapLocation.getErrorCode() + ", errInfo:"
+ aMapLocation.getErrorInfo());
}
} else {
tv_default_address.setText("定位失敗");
tv_reload_address.setText("定位失敗,請檢查手機設定");
}
}
};
/**
* 獲取附近位置
*/
private void getNearBy() {
//搜尋附近
initNearByParam();
adapter.setOnItemListener(new Ada_Change_Location.RecOnitem() {
@Override
public void OnChangeLocationClick(int position) {
if (nearByList != null && nearByList.size() > 0) {
String name = nearByList.get(position).name;
String nearBy = nearByList.get(position).address;
postAddress(name, nearBy);
}
}
});
}
/**
* 逆地理轉換
*
* @return
*/
private String geocodeToAddress(LatLonPoint latLonPoint) {
//逆地理轉換:經緯度轉換為地址
GeocodeSearch geocoderSearch = new GeocodeSearch(getActivity());
geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
@Override
public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int resultCode) {
if (resultCode == 1000 && regeocodeResult != null) {
RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
formatAddress = regeocodeAddress.getFormatAddress();
}
}
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
}
});
RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP);
geocoderSearch.getFromLocationAsyn(query);
return formatAddress;
}
/**
* 附件位置相關配置
*/
private void initNearByParam() {
if (cityCode != null) {
PoiSearch.Query query = new PoiSearch.Query("", "", cityCode);
query.setPageSize(30);
PoiSearch poiSearch = new PoiSearch(getContext(), query);
poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
@Override
public void onPoiSearched(PoiResult poiResult, int rCode) {
if (rCode == 1000 && poiResult != null && poiResult.getPois().size() > 0) {
ArrayList<PoiItem> pois = poiResult.getPois();
nearByList = new ArrayList<ChangeLocation>();
recycleView.setAdapter(adapter);
Collections.reverse(nearByList);
for (int i = 0; i < pois.size(); i++) {
String address = pois.get(i).getSnippet();
nearByList.add(new ChangeLocation(pois.get(i).getTitle(), address));
}
adapter.setdata(nearByList);
mLocationClient.stopLocation();//停止定位後,本地定位服務並不會被銷燬
} else {
Log.i("附件=====", "搜尋附近失敗");
}
}
@Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
}
});
poiSearch.searchPOIAsyn();
poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(latitude, longitude), 1000));//設定周邊搜尋的中心點以及半徑
}else{
ToastUtil.showToastShort(getContext(),"定位失敗,無法獲取附近位置");
}
}
/**
* 根據輸入內容提示地址
*
* @param s
* @param start
* @param before
* @param count
*/
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (nearByList != null && nearByList.size() > 0) {
nearByList.clear();
}
tv_current.setVisibility(View.GONE);
ll_reload_location.setVisibility(View.GONE);
tv_nearby.setVisibility(View.GONE);
iv_input_delete.setVisibility(View.VISIBLE);
newText = s.toString().trim();
if (s != null && s.length() > 0) {
InputtipsQuery inputquery = new InputtipsQuery(newText, city);
inputquery.setCityLimit(true);
Inputtips inputTips = new Inputtips(getActivity(), inputquery);
inputTips.setInputtipsListener(new Inputtips.InputtipsListener() {
@Override
public void onGetInputtips(List<Tip> tipList, int rCode) {
if (rCode == AMapException.CODE_AMAP_SUCCESS && tipList.size() > 0) {
inputList = new ArrayList<ChangeLocation>();
recycleView.setAdapter(adapter);
Collections.reverse(inputList);
for (int i = 0; i < tipList.size(); i++) {
inputList.add(new ChangeLocation(tipList.get(i).getName(), tipList.get(i).getAddress()));
}
adapter.setdata(inputList);
} else {
Log.e("InputtipsQuery==", rCode + "");
}
}
});
inputTips.requestInputtipsAsyn();
} else {
getNearBy();
tv_current.setVisibility(View.VISIBLE);
ll_reload_location.setVisibility(View.VISIBLE);
tv_nearby.setVisibility(View.VISIBLE);
iv_input_delete.setVisibility(View.GONE);
}
}
@Override
public void afterTextChanged(Editable s) {
String string = s.toString();
if (!TextUtils.isEmpty(string)) {
adapter.setOnItemListener(new Ada_Change_Location.RecOnitem() {
@Override
public void OnChangeLocationClick(int position) {
if (inputList != null && inputList.size() > 0) {
String name = inputList.get(position).name;
itemAddress = inputList.get(position).address;
postAddress(name, itemAddress);
}
}
});
} else {
getNearBy();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_reload_location:
//重新定位
startLocate();
break;
case R.id.iv_input_delete:
et_input_address.setText("");
iv_input_delete.setVisibility(View.GONE);
getNearBy();
break;
}
}
/**
* 上傳地址
*
* @param address
*/
private void postAddress(final String name, final String address) {
if (TextUtils.isEmpty(address)) {
Toast.makeText(this, "地址不能為空",Toast.SHROT_LENGTH).show();
} else {
//上傳程式碼
}
}
@Override
public void onDestroy() {
super.onDestroy();
mLocationClient.onDestroy();//銷燬定位客戶端,同時銷燬本地定位服務。
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
}
Ada_Change_Location
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.SHAir.qualitytech.cn.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by QualityTech on 2017/6/3.
*/
public class Ada_Change_Location extends RecyclerView.Adapter<Ada_Change_Location.ChangeLocationHolder> {
Context context;
RecOnitem recOnitem;
List<ChangeLocation> list = new ArrayList<>();
private ChangeLocationHolder changeHoder;
public void setdata(List<ChangeLocation> list) {
this.list.clear();
this.list = list;
notifyDataSetChanged();
}
public void setOnItemListener(RecOnitem recOnitem) {
this.recOnitem = recOnitem;
}
public Ada_Change_Location(Context context) {
this.context = context;
}
@Override
public ChangeLocationHolder onCreateViewHolder(ViewGroup parent, int viewType) {
changeHoder = new ChangeLocationHolder(LayoutInflater.from(context).inflate(R.layout.gaode_item_layout, null));
return changeHoder;
}
@Override
public void onBindViewHolder(ChangeLocationHolder holder, final int position) {
holder.poi_field_id.setText(list.get(position).name);
holder.poi_value_id.setText(list.get(position).address);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
recOnitem.OnChangeLocationClick(position);
}
});
}
@Override
public int getItemCount() {
return list.size();
}
class ChangeLocationHolder extends RecyclerView.ViewHolder {
ImageView iv_nearyby_layer;
TextView poi_field_id;
TextView poi_value_id;
public ChangeLocationHolder(View view) {
super(view);
iv_nearyby_layer = (ImageView) view.findViewById(R.id.iv_nearyby_layer);
poi_field_id = (TextView) view.findViewById(R.id.poi_field_id);
poi_value_id = (TextView) view.findViewById(R.id.poi_value_id);
}
}
public interface RecOnitem {
public void OnChangeLocationClick(int position);
}
}
ChangeLocation
public class ChangeLocation {
public String name;
public String address;
public ChangeLocation(String name, String address) {
this.name = name;
this.address = address;
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<RelativeLayout
android:id="@+id/ll_input_location"
android:layout_width="match_parent"
android:layout_height="125px"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20px">
<ImageView
android:id="@+id/iv_load"
android:layout_width="26px"
android:layout_height="39px"
android:src="@mipmap/layer_1"
android:layout_centerVertical="true"/>
<TextView
android:id="@+id/tv_default_address"
android:layout_width="130px"
android:layout_height="61px"
android:layout_centerVertical="true"
android:paddingLeft="10px"
android:singleLine="true"
android:textColor="#000000"
android:gravity="center_vertical"
android:textSize="32px"
android:layout_toRightOf="@+id/iv_load"/>
<EditText
android:id="@+id/et_input_address"
android:layout_width="match_parent"
android:layout_height="71px"
android:background="@drawable/location_shape"
android:layout_centerVertical="true"
android:hint="清輸入您的新地址"
android:textColor="#80000000"
android:textSize="32px"
android:singleLine="true"
android:layout_toRightOf="@+id/tv_default_address"
android:paddingLeft="15px"
android:paddingRight="50px"
android:layout_marginRight="15px"/>
<ImageView
android:id="@+id/iv_input_delete"
android:layout_width="80px"
android:layout_height="80px"
android:src="@mipmap/layer_2"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:paddingRight="14px"
android:visibility="gone"/>
</RelativeLayout>
<TextView
android:id="@+id/tv_current"
android:layout_width="match_parent"
android:layout_height="70px"
android:layout_below="@+id/ll_input_location"
android:background="#E7E7E7"
android:text="當前地址"
android:padding="20px"
android:textSize="28px"
android:textColor="#3a3a3a"
android:gravity="center_vertical"/>
<LinearLayout
android:id="@+id/ll_reload_location"
android:layout_below="@+id/tv_current"
android:layout_width="match_parent"
android:layout_height="90px"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_reload_address"
android:layout_weight="7"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingLeft="30px"
android:textSize="28px"
android:singleLine="true"
/>
<ImageView
android:id="@+id/iv_reload"
android:layout_width="40px"
android:layout_height="match_parent"
android:src="@mipmap/layer_4"
android:layout_marginLeft="20px"
android:layout_toRightOf="@+id/tv_reload_address"
android:layout_centerVertical="true"
android:visibility="gone"/>
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="40px"
android:layout_height="match_parent"
android:src="@mipmap/layer_4"
android:layout_marginLeft="20px"
android:layout_toRightOf="@+id/tv_reload_address"
android:layout_centerVertical="true"/>
<TextView
android:id="@+id/tv_reload_location"
android:layout_width="150px"
android:layout_height="38px"
android:textSize="30px"
android:textColor="#1ad7b1"
android:text="重新定位"
android:layout_toRightOf="@+id/iv_reload"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_marginLeft="10px"
/>
</LinearLayout>
<TextView
android:id="@+id/tv_nearby"
android:layout_below="@+id/ll_reload_location"
android:layout_width="match_parent"
android:layout_height="70px"
android:textSize="28px"
android:text="附近地址"
android:textColor="#3a3a3a"
android:gravity="center_vertical"
android:padding="20px"
android:background="#E7E7E7"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView_location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_nearby"
android:scrollbars="none"/>
</RelativeLayout>
gaode_item_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/iv_nearyby_layer"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@mipmap/layer_3"
android:layout_marginTop="2dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="10dp">
<TextView
android:id="@+id/poi_field_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="15sp" />
<TextView
android:id="@+id/poi_value_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:textColor="@android:color/darker_gray"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
location_shape
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorAccent">
<corners android:radius="45dp" />
<stroke
android:width="0.5px"
android:color="#1199EF" />
<solid android:color="@android:color/white" />
</shape>
用到的圖片資源
依次為layer_1-4.png