基本信息
源码名称:android 室内定位 源码下载(蓝牙定位)
源码大小:9.35M
文件格式:.zip
开发语言:Java
更新时间:2016-09-29
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
package com.uestc.indoorlocation;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import com.aprilbrother.aprilbrothersdk.Beacon;
import com.aprilbrother.aprilbrothersdk.BeaconManager;
import com.aprilbrother.aprilbrothersdk.utils.AprilL;
import com.uestc.indoorlocation.algorithm.Location;
import com.uestc.indoorlocation.common.AppActivity;
import com.uestc.indoorlocation.common.BeaconUtils;
import com.uestc.indoorlocation.common.Constant;
import com.uestc.indoorlocation.common.Point;
import com.uestc.indoorlocation.service.IbeaconListenerService;
public class MainActivity extends AppActivity {
/**
* 显示距离
*/
private TextView tv_distance = null;
private static final int REQUEST_ENABLE_BT = 1234;
private static final String TAG = "beacon";
private BeaconManager beaconManager;
//private ArrayList<Beacon> myBeacons;
private Intent scanIntent = null;
WindowManager wm;
volatile int windowWidth;
volatile int windowHeight;
double scaleX;
double scaleY;
private IndoorPositionView mapView;
private volatile double currentLocationX = (float) 0.0;
private volatile double currentLocationY = (float) 0.0;
/**
* rssi值的queue,针对不同的MAC地址
*/
private volatile Map<String, Queue<Integer>> rssiMapQueue;
/**
* 计算后的结果值,根据这个值来定位
*/
private volatile Map<String, Integer> rssiAvgMap;
/**
* 处理交互信息
* handlerResult函数处理信息类型
* 类型MSG_FRESH_BEACON:得到扫描结果
*
*/
@Override
protected void handleResult(Message msg) {
switch (msg.what) {
//处理beacon位置更新信息
case Constant.MSG_FRESH_BEACON:
//Log.v("beacon", "recved msg: " msg.obj);
if (msg == null) break;
Point position = position(msg);
if (position != null) {
position = getRealPosition(position);
double x = position.getPointX();
double y = position.getPointY();
currentLocationX = x > 0 ? x : 0;
currentLocationY = y > 0 ? y : 0;
mapView.invalidate(); //更新地图坐标点
BeaconUtils.printLogInfo(Constant.LOG_BEACON, "after position ==== x: "
currentLocationX " y: " currentLocationY);
}
break;
}
}
/**
* 处理信号
* @param msg
*/
private void processMsg(Message msg) {
/**
* 将beacon区分开,即key为mac地址,value为相关的Beacon列表
*/
Map<String, List<Beacon>> diffBeacons =
BeaconUtils.diffBeacons((List<Beacon>)msg.obj);
/**
* 在Beacon里将rssi值提取出来
*/
Map<String, List<Integer>> rssisAfterFilter = BeaconUtils.beaconFilter(diffBeacons);
/**
* 遍历滤波后的结果值
*/
//Log.v(TAG, "processMsg: " rssisAfterFilter);
for (Map.Entry<String, List<Integer>> entry : rssisAfterFilter.entrySet()) {
Queue<Integer> queue = rssiMapQueue.get(entry.getKey());
/**
* 初始化时,队列为空,同样结果列表也会为空
*/
if (queue == null || queue.size() == 0) {
BeaconUtils.printLogInfoWithoutOtherMsg("print", "queue is null");
queue = new LinkedList<Integer>();
rssiMapQueue.put(entry.getKey(), queue);
queue.addAll(entry.getValue());
/**
* 如果队列未满时,则需将队列填满
*/
} else if (queue.size() < Constant.QUEUE_MAX_SIZE) {
BeaconUtils.printLogInfoWithoutOtherMsg("print", "queue not full");
List<Integer> l = entry.getValue();
int length = l.size();
int i = 0;
while (queue.size() < Constant.QUEUE_MAX_SIZE && i < length-1) {
queue.add(l.get(i ));
}
/**
* 此时,队列已满,则去除队列头部,同时尾部增加一个滤波后的均值
*/
} else {
List<Integer> list = entry.getValue();
int head = queue.poll();
queue.offer(BeaconUtils.avgOfList(list));
}
//结果取为queue中的均值
rssiAvgMap.put(entry.getKey(), BeaconUtils.avgOfQueue(queue));
}
BeaconUtils.printLogInfo(Constant.LOG_PRINT, "rssiAvgMap: " rssiAvgMap.toString());
BeaconUtils.printLogInfo(Constant.LOG_PRINT, "rssiMapQueue: " rssiMapQueue.toString());
}
/**
* 处理信息,但没有其它的处理,仅取得平均值,即不再有个滑动队列
* @param msg
*/
private void processMsgWithoutOtherAlgorithm(Message msg) {
/**
* 将beacon区分开,即key为mac地址,value为相关的Beacon列表
*/
Map<String, List<Beacon>> diffBeacons =
BeaconUtils.diffBeacons((List<Beacon>)msg.obj);
/**
* 在Beacon里将rssi值提取出来
*/
Map<String, List<Integer>> rssisAfterFilter = BeaconUtils.beaconFilter(diffBeacons);
for (Map.Entry<String, List<Integer>> entry : rssisAfterFilter.entrySet()) {
int avg = BeaconUtils.avgOfList(entry.getValue());
rssiAvgMap.put(entry.getKey(), avg);
}
}
/**
* 定位
* @return
*/
public Point position(Message msg) {
//信号处理
processMsg(msg);
//Log.v(TAG, "position(): " rssiAvgMap);
return Location.getInstance().position(rssiAvgMap);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//requestWindowFeature(Window.FEATURE_NO_TITLE);
mapView = new IndoorPositionView(this);
mapView.setBackgroundResource(R.drawable.map_bg);
setContentView(mapView);
init();
}
@SuppressWarnings("deprecation")
private void init(){
wm = this.getWindowManager();
windowWidth = wm.getDefaultDisplay().getWidth();
windowHeight = wm.getDefaultDisplay().getHeight();
//比例
scaleX = windowWidth / 1040.0;
scaleY = windowHeight / 1150.0;
//new Thread(new MessageProcessor()).start(); //启动消息转接线程
scanIntent = new Intent(this, IbeaconListenerService.class);//绑定service
tv_distance = (TextView)findViewById(R.id.distance);
AprilL.enableDebugLogging(true);
beaconManager = new BeaconManager(getApplicationContext());
rssiMapQueue = new HashMap<String, Queue<Integer>>();
rssiAvgMap = new HashMap<String, Integer>();
}
/**
* 坐标转换
* @param point
* @return
*/
private Point getRealPosition(Point point) {
Log.v("scale", "scale x: " scaleX " y: " scaleY);
return new Point(point.getPointX() * scaleX, point.getPointY() * scaleY);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_OK) {
} else {
Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_LONG)
.show();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onStart() {
super.onStart();
startService(scanIntent);
/**
* 蓝牙开闭判断
*/
if (!beaconManager.hasBluetooth()) {
Log.v(TAG, "request bluttooth");
Toast.makeText(this, "Device does not have Bluetooth Low Energy",
Toast.LENGTH_LONG).show();
return;
}
if (!beaconManager.isBluetoothEnabled()) {
Log.v(TAG, "on start bluetooth");
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onStop() {
stopService(scanIntent);
super.onStop();
}
/**
* 显示的简单图片地图,
* 作为内部类主要是好处理坐标信息
* @author vincent
*
*/
class IndoorPositionView extends View{
private Paint paint = new Paint();
public IndoorPositionView(Context context) {
super(context);
setFocusable(true);
}
public void onDraw(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawCircle((float)currentLocationX, (float)currentLocationY, 10, paint);
}
}
}