实现 微信/QQ聊天 发送位置功能

Posted 摘星猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现 微信/QQ聊天 发送位置功能相关的知识,希望对你有一定的参考价值。

利用百度地图 实现QQ/微信发送位置功能

1.看到好多同学 项目需要 模仿发送位置 功能 自己项目也使用了 经过摸索现在分享出来
2.申请百度地图key(http://lbsyun.baidu.com/apiconsole/key);
3.主要界面代码 定位界面,内含 一个 popupWindow 里面显示的内容及 发送地图需要的内容 (图片+Location 点及 地点名字address)

package com.zhxqqmap;

/** * @author  作者 E-mail: 194093798@qq.com 
 * @date 创建时间:2016年2月22日 上午11:32:18 
 * @version 1.0 
 * @parameter  
 * @since  
 * @return  */

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;
import com.baidu.mapapi.map.BaiduMap.SnapshotReadyCallback;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;

public class MainActivity extends Activity 

    MapView mMapView;
    BaiduMap mBaiduMap;
    ImageView mSelectImg;
    // 定位
    LocationClient mLocationClient = null;
    MyBDLocationListner mListner = null;
    BitmapDescriptor mCurrentMarker = null;
    // 当前经纬度
    double mLantitude;
    double mLongtitude;
    LatLng mLoactionLatLng;
    // 设置第一次定位标志
    boolean isFirstLoc = true;
    // MapView中央对于的屏幕坐标
    Point mCenterPoint = null;
    // 地理编码
    GeoCoder mGeoCoder = null;
    // 位置列表
    ListView mListView;
    PlaceListAdapter mAdapter;
    List mInfoList;
    PoiInfo mCurentInfo;
    private String pictruepath;

    String base64Pic = "";
    String loacalpath;
    private ImageButton chat_activity_backBtn;
    private TextView placeTv;
    private ImageView showImg;
    private String addree;
    private PopupWindow mPopupWindow;

    /**
     * 重要说明  1.本demo 利用百度地图模仿 实现 微信/QQ  聊天   发送位置功能
     *       2. 考虑到具体界面比较复杂 所以并未 全仿界面 ,提供实现思路。
     *       3. 拿到demo 后 请从bin 文件中 提取 已经编译好的APK  试看效果。
     *       4. 更换menifast 里面  百度地图 的你自己的 key后  可在本地重新编译 运行
     *       5.百度地图 key申请地址(http://lbsyun.baidu.com/apiconsole/key)
     *       6.本demo  mPopupWindow 中显示的内容 即为 要显示在聊天窗口中的内容  包括一张实时 截图 及一个Location 点。
     *       7.如有疑问 可联系QQ: 194093798 相互交流学习。
     * 
     * 
     * */

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chooseplace);
        initView();
    

    /**
     * 初始化界面
     */
    private void initView() 
        // TODO Auto-generated method stub
        initPop();

        showImg.setOnClickListener(new OnClickListener() 

            @Override
            public void onClick(View v) 
                // TODO Auto-generated method stub
                Intent intent = new Intent(MainActivity.this,
                        PointMapActivity.class);
                Location location = new Location();
                location.setLatitude(mCurentInfo.location.latitude);
                location.setLongitude(mCurentInfo.location.longitude);
                location.setAddress(mCurentInfo.address);
                intent.putExtra("pointInfo", location);
                startActivity(intent);
            
        );
        findViewById(R.id.chat_activity_backBtn).setOnClickListener(
                new OnClickListener() 

                    @Override
                    public void onClick(View v) 
                        // TODO Auto-generated method stub
                        finish();
                    
                );
        findViewById(R.id.place_btn).setOnClickListener(new OnClickListener() 

            @Override
            public void onClick(View v) 
                // TODO Auto-generated method stub
                if (mCurentInfo != null) 
                    mBaiduMap.snapshot(new SnapshotReadyCallback() 

                        @Override
                        public void onSnapshotReady(Bitmap snapshot) 
                            // TODO Auto-generated method stub
                            if (mCurentInfo != null) 
                                mPopupWindow.showAtLocation(getWindow()
                                        .getDecorView(), Gravity.BOTTOM, 0, 0);
                                showImg.setImageBitmap(snapshot);
                                placeTv.setText(mCurentInfo.name
                                        + mCurentInfo.address);
                                backgroundAlpha(0.1f);
                                mMapView.setVisibility(View.INVISIBLE);
                            
                        
                    );
                
            

        );
        // 初始化地图
        mMapView = (MapView) findViewById(R.id.chooseplace_bmapView);

        mCurrentMarker = BitmapDescriptorFactory
                .fromResource(R.drawable.dingwei);
        mMapView.showZoomControls(false);
        mBaiduMap = mMapView.getMap();
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);
        mBaiduMap.setMapStatus(msu);
        mBaiduMap.setOnMapTouchListener(touchListener);

        mBaiduMap.setOnMapClickListener(new OnMapClickListener() 
            public void onMapClick(LatLng point) 
                mLoactionLatLng = point;
                turnBack();
                resetMarker(point);
            

            public boolean onMapPoiClick(MapPoi poi) 
                return false;
            
        );
        // 初始化POI信息列表
        mInfoList = new ArrayList();
        // 初始化当前MapView中心屏幕坐标,初始化当前地理坐标
        mCenterPoint = mBaiduMap.getMapStatus().targetScreen;
        mLoactionLatLng = mBaiduMap.getMapStatus().target;
        // 定位
        mBaiduMap.setMyLocationEnabled(true);
        mLocationClient = new LocationClient(this);
        mListner = new MyBDLocationListner();
        mLocationClient.registerLocationListener(mListner);
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true);// 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(0);
        mLocationClient.setLocOption(option);
        mLocationClient.start();
        // 地理编码
        mGeoCoder = GeoCoder.newInstance();
        mGeoCoder.setOnGetGeoCodeResultListener(GeoListener);
        // 周边位置列表
        mListView = (ListView) findViewById(R.id.place_list);
        mListView.setOnItemClickListener(itemClickListener);
        mAdapter = new PlaceListAdapter(getLayoutInflater(), mInfoList);
        mListView.setAdapter(mAdapter);

        mSelectImg = new ImageView(this);
    

    public void backgroundAlpha(float bgAlpha) 
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = bgAlpha; // 0.0-1.0
        getWindow().setAttributes(lp);
    

    private void initPop() 
        // TODO Auto-generated method stub
        View view = getLayoutInflater().inflate(R.layout.poup_layout, null);
        showImg = (ImageView) view.findViewById(R.id.show_img);
        placeTv = (TextView) view.findViewById(R.id.place_tv);
        mPopupWindow = showPlaceWindow(view);
        mPopupWindow.setOnDismissListener(new OnDismissListener() 

            @Override
            public void onDismiss() 
                // TODO Auto-generated method stub
                backgroundAlpha(1.0f);
                mMapView.setVisibility(View.VISIBLE);
            
        );
    

    protected void resetMarker(LatLng point) 
        // TODO Auto-generated method stub
        OverlayOptions ooC = new MarkerOptions().position(point)
                .icon(mCurrentMarker).zIndex(0);
        Marker marker = (Marker) mBaiduMap.addOverlay(ooC);
        marker.setPosition(point);
        // 实现动画跳转
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);
        mBaiduMap.animateMapStatus(u);

    

    public void turnBack() 
        // 实现动画跳转
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);
        mBaiduMap.animateMapStatus(u);

        mBaiduMap.clear();
        // 发起反地理编码检索
        mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                .location(mLoactionLatLng));

    

    @Override
    protected void onDestroy() 
        // TODO Auto-generated method stub
        super.onDestroy();
        mLocationClient.stop();
        mGeoCoder.destroy();
    

    // 定位监听器
    private class MyBDLocationListner implements BDLocationListener 

        @Override
        public void onReceiveLocation(BDLocation location) 
            // TODO Auto-generated method stub
            // map view 销毁后不在处理新接收的位置
            if (location == null || mMapView == null)
                return;

            mLantitude = location.getLatitude();
            mLongtitude = location.getLongitude();
            mLoactionLatLng = new LatLng(mLantitude, mLongtitude);

            // 是否第一次定位
            if (isFirstLoc) 
                resetMarker(mLoactionLatLng);
                isFirstLoc = false;
                // 实现动画跳转
                MapStatusUpdate u = MapStatusUpdateFactory
                        .newLatLng(mLoactionLatLng);
                mBaiduMap.animateMapStatus(u);

                mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                        .location(mLoactionLatLng));
                return;
            

        

    

    // 地理编码监听器
    OnGetGeoCoderResultListener GeoListener = new OnGetGeoCoderResultListener() 

        public void onGetGeoCodeResult(GeoCodeResult result) 
            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) 
                // 没有检索到结果
            
            // 获取地理编码结果
        

        @Override
        public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) 
            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) 
                // 没有找到检索结果
            
            // 获取反向地理编码结果
            else 
                // 当前位置信息
                mCurentInfo = new PoiInfo();
                mCurentInfo.address = result.getAddress();
                mCurentInfo.location = result.getLocation();
                mCurentInfo.name = "[位置]";
                mInfoList.clear();
                mInfoList.add(mCurentInfo);

                // 将周边信息加入表
                if (result.getPoiList() != null) 
                    mInfoList.addAll(result.getPoiList());
                
                // 通知适配数据已改变
                mAdapter.setmList(mInfoList, 0);
                // placeTv.setText(mCurentInfo.name+mCurentInfo.address);
            
        
    ;

    // 地图触摸事件监听器
    OnMapTouchListener touchListener = new OnMapTouchListener() 
        @Override
        public void onTouch(MotionEvent event) 
            // TODO Auto-generated method stub
            if (event.getAction() == MotionEvent.ACTION_UP) 

                if (mCenterPoint == null) 
                    return;
                

                // 获取当前MapView中心屏幕坐标对应的地理坐标
                LatLng currentLatLng;
                currentLatLng = mBaiduMap.getProjection().fromScreenLocation(
                        mCenterPoint);
                System.out.println("----" + mCenterPoint.x);
                System.out.println("----" + currentLatLng.latitude);
                // 发起反地理编码检索
                mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                        .location(currentLatLng));

            
        
    ;

    // listView选项点击事件监听器
    OnItemClickListener itemClickListener = new OnItemClickListener() 

        @Override
        public void onItemClick(AdapterView parent, View view, int position,
                long id) 
            // TODO Auto-generated method stub

            // 通知是适配器第position个item被选择了
            mAdapter.setNotifyTip(position);
            mBaiduMap.clear();
            mCurentInfo = (PoiInfo) mAdapter.getItem(position);
            mLoactionLatLng = mCurentInfo.location;

            resetMarker(mLoactionLatLng);

            // 选中项打勾
            mSelectImg.setBackgroundResource(R.drawable.weigouxuan);
            mSelectImg = (ImageView) view.findViewById(R.id.place_select);
            mSelectImg.setImageResource(R.drawable.gouxuan);
            // placeTv.setText(mCurentInfo.name+mCurentInfo.address);
        

    ;

    public PopupWindow showPlaceWindow(View view) 

        PopupWindow popupWindow = new PopupWindow(this);

        popupWindow.setWidth(LayoutParams.MATCH_PARENT);
        popupWindow.setHeight(LayoutParams.WRAP_CONTENT);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setFocusable(true);
        popupWindow.setAnimationStyle(R.anim.push_up_in);
        popupWindow.setContentView(view);

        return popupWindow;
    

4.点击popupWindow 跳转到 地图详细界面 pointMapActivity

package com.zhxqqmap;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;

public class PointMapActivity extends Activity implements OnClickListener 
    private MapView mMapView;
    private BaiduMap mBaiduMap;
    private boolean isFirst = true;
    // MapView中央对于的屏幕坐标
    Point mCenterPoint = null;
    // 地理编码
    GeoCoder mGeoCoder = null;

    // 当前经纬度
    double mLantitude;
    double mLongtitude;
    LatLng mLoactionLatLng;

    // 定位
    LocationClient mLocationClient = null;

    BitmapDescriptor mCurrentMarker = null;
    private boolean isFirstLoc = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        // TODO by zhx
        super.onCreate(savedInstanceState);
        initWidget();
    

    public void initWidget() 
        // TODO Auto-generated method stub
        setContentView(R.layout.point_activity);
        mMapView = (MapView) findViewById(R.id.pointplace_bmapView);
        Intent intent = getIntent();
        Location location = (Location) intent.getSerializableExtra("pointInfo");

        mBaiduMap = mMapView.getMap();
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        mCurrentMarker = BitmapDescriptorFactory
                .fromResource(R.drawable.dingwei);
        mBaiduMap.setMapStatus(MapStatusUpdateFactory
                .newMapStatus(new MapStatus.Builder().zoom(17).build()));

        mLoactionLatLng = new LatLng(location.getLatitude(),
                location.getLongitude());
        resetMarker(mLoactionLatLng);

        View view = getLayoutInflater().inflate(R.layout.place_layout_tv, null);
        TextView tv = (TextView) view.findViewById(R.id.palce_name_tv);
        tv.setText(location.getAddress());
        mBaiduMap.showInfoWindow(new InfoWindow(view, new LatLng(location
                .getLatitude(), location.getLongitude()), -40));
        findViewById(R.id.point_back).setOnClickListener(this);

    

    protected void resetMarker(LatLng point) 
        // TODO Auto-generated method stub
        OverlayOptions ooC = new MarkerOptions().position(point)
                .icon(mCurrentMarker).zIndex(0);
        Marker marker = (Marker) mBaiduMap.addOverlay(ooC);
        marker.setPosition(point);
        // 实现动画跳转
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);
        mBaiduMap.animateMapStatus(u);

    

    public void widgetClick(View v) 
        // TODO Auto-generated method stub
        switch (v.getId()) 
        case R.id.point_back:
            finish();
            break;

        default:
            break;
        
    

    @Override
    protected void onPause() 
        mMapView.onPause();
        super.onPause();
    

    @Override
    protected void onResume() 
        mMapView.onResume();
        super.onResume();
    

    @Override
    protected void onDestroy() 

        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
        super.onDestroy();
    

    @Override
    public void onClick(View v) 
        // TODO by zhx
        widgetClick(v);
    


5.源码地址OSC:https://github.com/zhoulinxue/ZhxQQMap.git
gitHub https://github.com/zhoulinxue/ZhxQQMap.git
6.QQ:194093798 欢迎交流

以上是关于实现 微信/QQ聊天 发送位置功能的主要内容,如果未能解决你的问题,请参考以下文章

android黑科技系列——微信定位聊天记录中照片的位置信息插件开发详解

微信QQ聊天是怎么实现的?原来这么简单!!!

利用百度地图Android sdk高仿微信发送位置功能

手把手教你用鸿蒙HarmonyOS实现微信聊天界面

jsp聊天室实现发送表情功能

android 版百度地图如何通过定位功能获得当前的位置所在的城市?