融云&高德地图-实现地理位置发送

效果预览



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);

AMAPLocationActivity 为核心逻辑类。高德地图的展示 获取经纬度和定位的逻辑全在此处

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:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.amap.api.maps2d.MapView
            android:id="@+id/map"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>

        <TextView
            android:id="@+id/location"
            android:text="获取中……"
            android:drawableLeft="@drawable/schedule_end_icon"
            android:singleLine="true"
            android:ellipsize="end"
            android:padding="10dp"
            android:background="@drawable/bg_white"
            android:textColor="@android:color/secondary_text_light"
            android:textSize="15sp"
            android:drawablePadding="8dp"
            android:layout_margin="20dp"
            android:layout_gravity="center_horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <ImageView
            android:id="@+id/myLocation"
            android:src="@drawable/btn_location"
            android:layout_gravity="right|bottom"
            android:layout_marginBottom="70dp"
            android:layout_marginRight="5dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </FrameLayout>

</RelativeLayout>

将代码拷贝 和 相关资源文件拷贝以后就能实现。下面对代码逻辑做一下介绍

代码整体分两部分 一部分是发送位置逻辑 一部分是从会话界面地理位置消息点击进来逻辑。主要逻辑是 发送位置逻辑

@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 不继续执行代码。完成当前位置的预览即结束


发送地理位置&高德地图结束 有任何疑问可以在下方留言。高德地图相关的问题可登陆高德地图官网进行咨询

时间: 2024-08-13 00:58:54

融云&高德地图-实现地理位置发送的相关文章

融云知识点

1.为选择图片发送界面加上返回 融云自带的选择发送图片界面没有返回按钮,为了app界面统一完整需要加上: 首先,连接融云服务器之前: //扩展功能自定义 InputProvider.ExtendProvider[] provider = { new MyImageInputProvider(RongContext.getInstance()),//图片 new CameraInputProvider(RongContext.getInstance())//相机 }; RongIM.getInst

java servlet手机app访问接口(三)高德地图云存储及检索

这篇关于高德地图的随笔内容会多一点, 一.业务说明     对应APP业务中的成员有两类,一是服务人员,二是被服务人员,  主要实现功能, 对APP中的服务人员位置进行时时定位, 然后通过被服务人员登录APP时提供的一个经纬度来计算服务人员与被服务人员之间的距离 单位m. 下面是整个详细流程,从创建高德对应应用(这里注册我就不说了)------最后完成此功能. 二.创建servlet对应的高德地图应用,创建自己的云图数据库表 注册帐号后登录点击右上角的控制台,会出现下面这个界面,我截图 这里当然

nodejs向远程服务器发送post请求----融云Web SDK/客户端获取token

最近要用到一个叫融云的及时通讯的SDK,在获取token这个步骤的时候有点卡顿,以防以后碰到类似的问题,再此记录一下. 客户端通过融云 SDK 每次连接服务器时,都需要向服务器提供 Token,以便验证身份,流程如下: 流程如下: 1.客户端获取用户id,并向服务器请求token(注意这里的服务器不是融云的服务器,而是客户端的服务端) 2.客户端的服务端接收到token请求后,向融云的服务器请求token 3.融云服务器接受到token请求,返回token给客户端的服务端. 4.客户端的服务端接

融云发送不显示缩略图解决方法

部分安卓手机在使用融云打包正式版后,发送图片不显示缩略图,解决方法如下: 1. 发送本地图片,rong.sendImageMessage的prepare,此时使用本地默认图片2. 发送中,显示图片发送百分比,利用监听3. 发送成功后,rong.getHistoryMessages 获取历史记录,参数:oldestMessageId : -1,count : 14. 根据返回值替换之前的默认图片src /** * 发送图片消息 * 周枫 * 2015.08.11 * @param {Object}

百度地图与融云的“冲突”(APP的.so手机架构目录,与Library的.so的手机架构目录冲突)

在项目引进融云的IMkit时,总是报百度地图的错误,最开始以为是65535的错误,然后试着去改下百度地图,错误原因是在IMKit里面,它的.so库有这么几个目录 而我的app的libs里面的百度地图的SO库的目录里只有armeabi这个文件夹,导致不一致而报错,所以在app/libs里面加一个文件夹,把百度地图的SO复制进去,变成这样 那么在arm环境下就一致了,就不会报错了.http://bbs.lbsyun.baidu.com/forum.php?mod=viewthread&tid=815

融云 Android SDK 拍照,图片选择器方案分析

一  拍照 目前拍照融云提供两种方案 1 SDK kit 包中自带的拍照 关键类 : CameraInputProvider 此类点击是唤起 TakingPicturesActivity 特点是拍照后 勾选完成 会有一个预览界面  此方案如果在某些机型上 点击勾选后无响应 是因为 一些机型唤起 系统相机后 把下面的栈资源回收了 已经做了 onSaveInstanceState 的生命周期保存瞬间状态 但是还是偶现此情况 下面贴出实现代码 如果有知道此问题终极解决方案的开发者 欢迎留言 或者 联系

【高德地图API】汇润做爱地图技术大揭秘

昨日收到了高德地图微信公众号的消息推送,说有[一大波免费情趣用品正在袭来],点进去看了一眼,说一个电商公司(估计是卖情趣用品的)用高德云图制作了一张可以标记做爱地点与详情的地图.这不就是中国版的I just made love麽? 滑到屏幕底下,看了看阅读量,哇塞,居然有4万3!!!说明实在是有很多人关注做爱地图啊.本着研究地图的心情(绝对不是为了什么价值300的智能情趣用品!),我也就点击了[阅读原文]…… 好吧,为了证明我真的不是为了奖品,我会一边写活动步骤,一边揭秘其中的LBS技术.  

利用高德地图完成用户地图选址,包括搜索位置和标签固定居中

这两天一直捣鼓着地图的选址功能,需要达到的要求是:1,能用户定位  2,大头针固定在地图中心,拖动地图停止后获取到该大头针的位置信息    3,能通过搜索框搜索到我们输入的地址 主要思路:大头针分为两个   一个是用户的位置大头针  另一个是所选取的位置的大头针(包括拖动后的大头针和搜索功能查找到位置的大头针,公用一个大头针  )并且两个大头针都成为控制器器属性. 我使用到的高德地图sdk是: 'AMap3DMap' , '5.2.1' #高德3D地图 'AMapSearch' , '5.2.1

融云为什么成了App开发者的超级创业乐园?

全球市场上的App有数百万之多,如何在这百万大军中脱颖而出?纵观这些近年成功的App明星身上都有一个亮点--App的场景社交,那么如何增加社交功能满足场景化社交,又为什么要找融云即时通讯云实现这一切呢? App社交化成为开发者迈向成功的"星光大道" 近年来,在App这个巨大产业链条之下上演了多少创业者的 "悲欢离合",即有创业挫败的"苦逼",也有创业成功的欢愉.尤其是如今社会迈入云服务时代.社交化时代,原本默默无闻的App创业者们经常上演绝地反击