基于腾讯地图的实时位置共享-客户端

最近写了一个关于位置共享的demo,拿出来给大家看看,欢迎点赞留言丢香蕉丢苹果!长话短说!

地图应用主要是使用腾讯地图http://lbs.qq.com/ 上面,注册自己的地图开发密钥!

Paste_Image.png

先说下客户端这边的逻辑!

  1. 导入相关地图包,实现基本的地图使用,包括地图显示,定位,位置变化监听
  2. 启动后台服务负责保持Socket与服务器之间的数据交互
  3. 获取服务器返回数据后,更新地图标识地址

我们需要与服务器交换的数据包括,sessionId还有位置的经纬度
<pre>
public class UserLocation {
public int sessionId;//session标志
public LatLng latLng;
}</pre>

**至于怎么使用腾讯地图,大家可以看下关于腾讯地图里面的Demo!
当后台服务从获取到Socket数据的时候,会给前台发布广播,Activity通过广播来进行数据更新!

public class MainActivity extends AppCompatActivity implements
    TencentLocationListener, SensorEventListener, ServiceConnection {
private SensorManager sensorManager;
private Sensor        oritationSensor;

private TencentLocationManager locationManager;
private TencentLocationRequest locationRequest;

private UserLocation myLocation = new UserLocation();

private MapView    mapView;
private TencentMap tencentMap;

private HashMap<Integer, Marker> marks = new HashMap<>();//存储其它用户Marker
private Marker myMarker;

public static final String ip   = "10.0.1.122";
public static final int    port = 8000;
public UpdateLocationbc updateLocationbc;
public boolean isConnection, hasLocation = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bindSocketService();
    init();
    initListener();
}

/**
 * 绑定服务监听
 */
public void bindSocketService() {
    Intent socketService = new Intent(this, SocketService.class);
    socketService.putExtra("url", ip);
    socketService.putExtra("port", port);
    bindService(socketService, this, BIND_AUTO_CREATE);
}

public SocketService.Binder binder;

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    binder = (SocketService.Binder) iBinder;
    isConnection = true;
}

@Override
public void onServiceDisconnected(ComponentName componentName) {

}

/**
 * 初始化页面数据
 */
private void init() {
    sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    oritationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
    locationManager = TencentLocationManager.getInstance(this);
    locationRequest = TencentLocationRequest.create();
    mapView = (MapView) findViewById(R.id.mapview);
    tencentMap = mapView.getMap();
    getMapsFocus();
}

/**
 * 注册监听
 */
private void initListener() {
    sensorManager.registerListener(MainActivity.this,
                                   oritationSensor, SensorManager.SENSOR_DELAY_NORMAL
                                  );
    updateLocationbc = new UpdateLocationbc();
    registerReceiver(updateLocationbc, new IntentFilter(getString(R.string.updatelocationbc)));
}

public void getMapsFocus() {
    // 获取地图焦点
    int error = locationManager.requestLocationUpdates(locationRequest, MainActivity.this);
    //输出提示
    showToast(error < Constanst.MapErrorItems.length ? Constanst.MapErrorItems[error] : "地图注册失败");
}

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    locationManager.removeUpdates(this);
    sensorManager.unregisterListener(this);
    if (binder != null) {
        unbindService(this);
        binder = null;
        isConnection = false;
    }
    super.onDestroy();
}

@Override
public void onSensorChanged(SensorEvent event) {
    if (myMarker != null) {
        myMarker.setRotation(-event.values[0]);
    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

@Override
public void onLocationChanged(TencentLocation arg0, int arg1, String arg2) {
    if (arg1 == TencentLocation.ERROR_OK) {
        locationFuction(arg0);
        if (binder != null && isConnection) {
            binder.putUploaderLocation(GsonUtil.getGson(myLocation));
        }
    }
}

/**
 * 位置改变
 * @param arg0
 */
public void locationFuction(TencentLocation arg0){
    LatLng latLng = new LatLng(arg0.getLatitude(), arg0.getLongitude());
    if (myMarker == null) {
        myMarker = tencentMap.addMarker(new MarkerOptions().
                position(latLng).
                icon(BitmapDescriptorFactory.fromResource(R.drawable.navigation)).
                anchor(0.5f, 0.5f));
    }
    myMarker.setPosition(latLng);
    myMarker.setRotation(arg0.getBearing()); //仅当定位来源于gps有效,或者使用方向传感器
    myLocation.setLatLng(latLng);

    /**
     * 首次定位调用
     */
    if (!hasLocation) {
        tencentMap.animateTo(latLng);
        tencentMap.setZoom(14);
        hasLocation = true;
    }
}

@Override
public void onStatusUpdate(String s, int i, String s1) {

}


/**
 * 更新别人对象位置
 *
 * @param location 位置数据
 */
public void updateLocation(String location) {
    if (location.startsWith(getString(R.string.socketLocation))) {
        UserLocation userLocation = new Gson().fromJson(location.replace(getString(R.string.socketLocation), ""), UserLocation.class);

        Marker marker = marks.get(userLocation.getSessionId());
        if (marker != null) {
            marker.setPosition(userLocation.getLatLng());
        } else {
            marker = tencentMap.addMarker(new MarkerOptions().
                    position(userLocation.getLatLng()).
                    icon(BitmapDescriptorFactory.fromResource(R.drawable.navigation)).
                    anchor(0.5f, 0.5f));
            marker.setPosition(userLocation.getLatLng());
            tencentMap.animateTo(userLocation.getLatLng());
            marks.put(userLocation.getSessionId(), marker);
        }
    }
}

/**
 * 发送数据更新广播
 */
public class UpdateLocationbc extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String data = intent.getStringExtra("location");
        System.out.println("接收到广播数据--->" + data);
        if (!data.isEmpty()) {
            if (data.startsWith(getString(R.string.socketLocation))) {
                updateLocation(data);
            }
        }
    }
}

/**
 * 弹出提示
 * @param msg
 */
public void showToast(String msg) {
    Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}

}

客户端之间通过Socket进行数据的交互,而客户端中对Socket的处理,都放在Service里面处理,而Service和Activity之间的数据通过广播来传递!下面的Service里面对Socket的操作代码:

public class SocketService extends Service {
Binder binder;
public String url;
public int    port;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    url = intent.getStringExtra("url");
    port = intent.getIntExtra("port", 8888);
    connect(url, port);
    binder = new Binder();
    return binder;
}

/**
 * 返回Binder
 */
public class Binder extends android.os.Binder {
    /**
     * 返回的数值是的其他客户端返回的数值
     *
     * @param data
     */
    public void getUpdateLocation(String data) {
        System.out.println("--->返回的数值是的其他客户端返回的数值" + data);
        Intent intent = new Intent(getString(R.string.updatelocationbc));
        intent.putExtra("location", data);
        sendBroadcast(intent);
    }

    /**
     * 上传当前位置信息
     *
     * @param data 包含当前数据信息的json化后的UserLocation对象
     */
    public void putUploaderLocation(String data) {
        if (writer == null) {
            return;
        }

        try {
            System.out.println("--->上传当前位置信息" + data);
            writer.write("@location" + data + "\n");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 建立链接
 */
Socket         socket = null;
BufferedWriter writer = null;
BufferedReader reader = null;

public void connect(final String url, final int port) {
    AsyncTask<Void, String, Void> connectionTask = new AsyncTask<Void, String, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                socket = new Socket(url, port);
                writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                publishProgress(getString(R.string.socketConnectionSuccess));

            } catch (IOException e) {
                System.out.println("error--->" + getString(R.string.connectionFailure));
                e.printStackTrace();
                return null;
            }

            String line;
            try {
                while ((line = reader.readLine()) != null) {
                    publishProgress(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            if (values[0].isEmpty()) return;
            if (values[0].equals(getString(R.string.socketConnectionSuccess))) {
                System.out.println((getString(R.string.socketConnectionSuccess)));
            }
            binder.getUpdateLocation(values[0]);
        }
    };
    connectionTask.execute();
}}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,401评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,587评论 18 139
  • 1、葱姜呛锅 2、放肉炒熟 3、放黄豆、料酒少许、酱油少许 4、放雪菜进去翻炒,然后加点热水 5、放盐、鸡精、白糖一点点
    Oo日光微澜oO阅读 633评论 0 1
  • 王维[唐] 荆溪白石出,天寒红叶稀。 山路元无雨,空翠湿人衣。 今日分享一首诗吧。 此诗描绘了秋末时节的山中野景,...
    叶小安吖阅读 503评论 0 0
  • (一)沉沦或向往 银杏叶把秋天背在肩上,请求 冷风给它添点颜色的枯黄 昨晚拜托了天空 把光线调得再暗一些,显得 它...
    豆四吧阅读 141评论 1 1