編輯:關於Android編程
效果預覽
Send:
Click LocationMessage:
實現
1:注冊高德地圖開發者賬號,創建應用、獲取高德地圖的 appkey
2: jar 包建議直接從 融雲 demo 中拷貝。因為某地圖廠商的版本兼容做的不好。可能你下載的新版本的 jar. 在老版本的實現代碼中就找不到這個接口。或者那個接口變動了
3: 參考 demo 代碼 在 RongCloudEvent.java 上實現了 地理位置提供者接口 。 onStartLocation 方法中點擊開啟 地圖的 Activity
@Override
public void onStartLocation(Context context, LocationCallback locationCallback) {
/**
* demo 代碼 開發者需替換成自己的代碼。
*/
DemoContext.getInstance().setLastLocationCallback(locationCallback);
Intent intent = new Intent(context, AMAPLocationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
code:
public class AMAPLocationActivity extends ActionBarActivity implements View.OnClickListener, LocationSource, GeocodeSearch.OnGeocodeSearchListener, AMapLocationListener, AMap.OnCameraChangeListener {
private MapView mapView;
private AMap aMap;
private LocationManagerProxy mLocationManagerProxy;
private Handler handler = new Handler();
private LocationSource.OnLocationChangedListener listener;
private LatLng myLocation = null;
private Marker centerMarker;
private boolean isMovingMarker = false;
private BitmapDescriptor successDescripter;
private GeocodeSearch geocodeSearch;
private LocationMessage mMsg;
private TextView tvCurLocation;
private boolean model = false;
private boolean isPerview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_amap);
getSupportActionBar().setTitle("地理位置");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.de_actionbar_back);
mapView = (MapView) findViewById(R.id.map);
mapView.onCreate(savedInstanceState);
initUI();
initAmap();
setUpLocationStyle();
}
private void initAmap() {
if (aMap == null) {
aMap = mapView.getMap();
}
if (getIntent().hasExtra("location")) {
isPerview = true;
mMsg = getIntent().getParcelableExtra("location");
tvCurLocation.setVisibility(View.GONE);
returns.setVisibility(View.GONE);
if (model) {
CameraPosition location = new CameraPosition.Builder()
.target(new LatLng(mMsg.getLat(), mMsg.getLng())).zoom(18).bearing(0).tilt(30).build();
show(location);
} else {
aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
.position(new LatLng(mMsg.getLat(), mMsg.getLng())).title(mMsg.getPoi())
.snippet(mMsg.getLat() + "," + mMsg.getLng()).draggable(false));
}
return;
}
aMap.setLocationSource(this);// 設置定位監聽
aMap.setMyLocationEnabled(true);
aMap.getUiSettings().setZoomControlsEnabled(false);
aMap.getUiSettings().setMyLocationButtonEnabled(false);
CameraUpdate cameraUpdate = CameraUpdateFactory.zoomTo(15);//設置縮放監聽
aMap.moveCamera(cameraUpdate);
successDescripter = BitmapDescriptorFactory.fromResource(R.drawable.icon_usecarnow_position_succeed);
geocodeSearch = new GeocodeSearch(this);
geocodeSearch.setOnGeocodeSearchListener(this);
}
private static final String MAP_FRAGMENT_TAG = "map";
private SupportMapFragment aMapFragment;
private void show(CameraPosition location) {
AMapOptions aOptions = new AMapOptions();
aOptions.zoomGesturesEnabled(true);
aOptions.scrollGesturesEnabled(false);
aOptions.camera(location);
if (aMapFragment == null) {
aMapFragment = SupportMapFragment.newInstance(aOptions);
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.add(android.R.id.content, aMapFragment,
MAP_FRAGMENT_TAG);
fragmentTransaction.commit();
}
}
private ImageView returns;
private void initUI() {
returns = (ImageView) findViewById(R.id.myLocation);
returns.setOnClickListener(this);
tvCurLocation = (TextView) findViewById(R.id.location);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.myLocation:
CameraUpdate update = CameraUpdateFactory.changeLatLng(myLocation);
aMap.animateCamera(update);
break;
default:
break;
}
}
@Override
public void activate(OnLocationChangedListener onLocationChangedListener) {
listener = onLocationChangedListener;
mLocationManagerProxy = LocationManagerProxy.getInstance(this);
mLocationManagerProxy.requestLocationData(
LocationProviderProxy.AMapNetwork, -1, 100, this);
}
@Override
public void deactivate() {
if (mLocationManagerProxy != null) {
mLocationManagerProxy.removeUpdates(this);
mLocationManagerProxy.destroy();
}
mLocationManagerProxy = null;
}
@Override
public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
if (i == 0) {
if (regeocodeResult != null && regeocodeResult.getRegeocodeAddress() != null) {
endAnim();
centerMarker.setIcon(successDescripter);
RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
String formatAddress = regeocodeResult.getRegeocodeAddress().getFormatAddress();
String shortAdd = formatAddress.replace(regeocodeAddress.getProvince(), "").replace(regeocodeAddress.getCity(), "").replace(regeocodeAddress.getDistrict(), "");
tvCurLocation.setText(shortAdd);
double latitude = regeocodeResult.getRegeocodeQuery().getPoint().getLatitude();
double longitude = regeocodeResult.getRegeocodeQuery().getPoint().getLongitude();
mMsg = LocationMessage.obtain(latitude, longitude, shortAdd, getMapUrl(latitude, longitude));
NLog.e("LocationChange", shortAdd + latitude + "----" + longitude);
} else {
NToast.shortToast(AMAPLocationActivity.this, "沒有搜索到結果");
}
} else {
NToast.shortToast(AMAPLocationActivity.this, "搜索失敗,請檢查網絡");
}
}
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
}
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation != null && aMapLocation.getAMapException().getErrorCode() == 0) {
if (listener != null) {
listener.onLocationChanged(aMapLocation);// 顯示系統小藍點
}
myLocation = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());//獲取當前位置經緯度
tvCurLocation.setText(aMapLocation.getRoad() + aMapLocation.getStreet() + aMapLocation.getPoiName());//當前位置信息
double latitude = aMapLocation.getLatitude();
double longitude = aMapLocation.getLongitude();
mMsg = LocationMessage.obtain(latitude, longitude, aMapLocation.getRoad() + aMapLocation.getStreet() + aMapLocation.getPoiName(), getMapUrl(latitude, longitude));
NLog.e("LocationInit", aMapLocation.getRoad() + aMapLocation.getStreet() + aMapLocation.getPoiName() + latitude + "----" + longitude);
addChooseMarker();
}
}
private void addChooseMarker() {
//加入自定義標簽
MarkerOptions centerMarkerOption = new MarkerOptions().position(myLocation).icon(successDescripter);
centerMarker = aMap.addMarker(centerMarkerOption);
centerMarker.setPositionByPixels(mapView.getWidth() / 2, mapView.getHeight() / 2);
handler.postDelayed(new Runnable() {
@Override
public void run() {
CameraUpdate update = CameraUpdateFactory.zoomTo(17f);
aMap.animateCamera(update, 1000, new AMap.CancelableCallback() {
@Override
public void onFinish() {
aMap.setOnCameraChangeListener(AMAPLocationActivity.this);
}
@Override
public void onCancel() {
}
});
}
}, 1000);
}
private void setMovingMarker() {
if (isMovingMarker)
return;
isMovingMarker = true;
centerMarker.setIcon(successDescripter);
hideLocationView();
}
@Override
public void onCameraChange(CameraPosition cameraPosition) {
if (centerMarker != null) {
setMovingMarker();
}
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
LatLonPoint point = new LatLonPoint(cameraPosition.target.latitude, cameraPosition.target.longitude);
RegeocodeQuery query = new RegeocodeQuery(point, 50, GeocodeSearch.AMAP);
geocodeSearch.getFromLocationAsyn(query);
if (centerMarker != null) {
animMarker();
}
showLocationView();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
deactivate();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
@Override
protected void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
private ValueAnimator animator = null;
private void animMarker() {
isMovingMarker = false;
if (animator != null) {
animator.start();
return;
}
animator = ValueAnimator.ofFloat(mapView.getHeight() / 2, mapView.getHeight() / 2 - 30);
animator.setInterpolator(new DecelerateInterpolator());
animator.setDuration(150);
animator.setRepeatCount(1);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = (Float) animation.getAnimatedValue();
centerMarker.setPositionByPixels(mapView.getWidth() / 2, Math.round(value));
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
centerMarker.setIcon(successDescripter);
}
});
animator.start();
}
private void endAnim() {
if (animator != null && animator.isRunning())
animator.end();
}
private void hideLocationView() {
ObjectAnimator animLocation = ObjectAnimator.ofFloat(tvCurLocation, "TranslationY", -tvCurLocation.getHeight() * 2);
animLocation.setDuration(200);
animLocation.start();
}
private void showLocationView() {
ObjectAnimator animLocation = ObjectAnimator.ofFloat(tvCurLocation, "TranslationY", 0);
animLocation.setDuration(200);
animLocation.start();
}
private void setUpLocationStyle() {
// 自定義系統定位藍點
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.
fromResource(R.drawable.img_location_now));
myLocationStyle.strokeWidth(0);
myLocationStyle.strokeColor(R.color.main_theme_color);
myLocationStyle.radiusFillColor(Color.TRANSPARENT);
aMap.setMyLocationStyle(myLocationStyle);
}
private Uri getMapUrl(double x, double y) {
String url = "http://restapi.amap.com/v3/staticmap?location=" + y + "," + x +
"&zoom=17&scale=2&size=150*150&markers=mid,,A:" + y + ","
+ x + "&key=" + "ee95e52bf08006f63fd29bcfbcf21df0";
NLog.e("getMapUrl", url);
return Uri.parse(url);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.de_location_menu, menu);
if (isPerview) {
menu.getItem(0).setVisible(false);
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.send_location:
if (mMsg != null) {
DemoContext.getInstance().getLastLocationCallback().onSuccess(mMsg);
DemoContext.getInstance().setLastLocationCallback(null);
finish();
} else {
DemoContext.getInstance().getLastLocationCallback()
.onFailure("定位失敗");
}
break;
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
}
xml:
<framelayout android:layout_height="match_parent" android:layout_width="match_parent">
</framelayout>
將代碼拷貝 和 相關資源文件拷貝以後就能實現。下面對代碼邏輯做一下介紹
代碼整體分兩部分 一部分是發送位置邏輯 一部分是從會話界面地理位置消息點擊進來邏輯。主要邏輯是 發送位置邏輯
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation != null && aMapLocation.getAMapException().getErrorCode() == 0) {
如果卡在這個 if 判斷沒有進來那說明你配置的高德相關的 jar 、key 、storeFile(此處在 gradle 配置) 配置高德環境有問題。此處具體咨詢高德地圖
另外需要值得注意的一點是獲取靜態縮略圖的問題
private Uri getMapUrl(double x, double y) {
String url = "http://restapi.amap.com/v3/staticmap?location=" + y + "," + x +
"&zoom=17&scale=2&size=150*150&markers=mid,,A:" + y + ","
+ x + "&key=" + "ee95e52bf08006f63fd29bcfbcf21df0";
NLog.e("getMapUrl", url);
return Uri.parse(url);
}
最後組拼的 key.在高德官網解釋是說需要配置自己的 高德key.這裡是個坑,我拿著自己的 key 去浏覽器中解析 返回錯誤碼 10009
當時給愁壞了。後來朋友提示隨意拿個別人的 key 綁定了 web api 的去使用試試。結果還真行。所以在此處參考博文的小伙伴直接用上面 demo 提供的 key 即可。
點擊地理位置消息預覽的邏輯 在 RongCloudEvent.java 重寫消息點擊事件
if (message.getContent() instanceof LocationMessage) {
Intent intent = new Intent(context, AMAPLocationActivity.class);
intent.putExtra("location", message.getContent());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
在 AMAPLocationActivity 截取並且判斷這個 intent
if (getIntent().hasExtra("location")) {
isPerview = true;
mMsg = getIntent().getParcelableExtra("location");
tvCurLocation.setVisibility(View.GONE);
returns.setVisibility(View.GONE);
if (model) {
CameraPosition location = new CameraPosition.Builder()
.target(new LatLng(mMsg.getLat(), mMsg.getLng())).zoom(18).bearing(0).tilt(30).build();
show(location);
} else {
aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
.position(new LatLng(mMsg.getLat(), mMsg.getLng())).title(mMsg.getPoi())
.snippet(mMsg.getLat() + "," + mMsg.getLng()).draggable(false));
}
return;
}
最後的 return 不繼續執行代碼。完成當前位置的預覽即結束
發送地理位置&高德地圖結束 有任何疑問可以在下方留言。高德地圖相關的問題可登陸高德地圖官網進行咨詢
一、圖片預覽:一、實現功能:需求要實現布局中為圓形圖片,圖片背景與圖標分開且合並到一個ImageView。二、具體實現:XML中布局中定義ImageView,關健設置兩個
百度了下,好像都沒找到想要的,或許是我百度錯了關鍵字吧。我這就介紹一種我現在剛學的方法。首先web端費給我們一個接口文檔。我這就接觸到兩塊內容:(1)通過接口傳遞單純的數
點擊浏覽器中的URL鏈接,啟動特定的App。 首先做成HTML的頁面,頁面內容格式如下: 啟動應用程序 這一句就可以了。 各個項目含義如下
仿QQ側滑刪除效果圖1.自定義listviewpublic class DragDelListView extends ListView { private boole