实例介绍
【实例简介】
【实例截图】
【核心代码】
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);
}
}
}
好例子网口号:伸出你的我的手 — 分享!
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)