最近写了一个关于位置共享的demo,拿出来给大家看看,欢迎点赞留言丢香蕉丢苹果!长话短说!
地图应用主要是使用腾讯地图http://lbs.qq.com/ 上面,注册自己的地图开发密钥!
先说下客户端这边的逻辑!
- 导入相关地图包,实现基本的地图使用,包括地图显示,定位,位置变化监听
- 启动后台服务负责保持Socket与服务器之间的数据交互
- 获取服务器返回数据后,更新地图标识地址
我们需要与服务器交换的数据包括,sessionId还有位置的经纬度
public class UserLocation {
public int sessionId;//session标志
public LatLng latLng;
}
**至于怎么使用腾讯地图,大家可以看下关于腾讯地图里面的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 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 connectionTask = new AsyncTask() {
@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();
}}