在好例子网,分享、交流、成长!
您当前所在位置:首页Java 开发实例Android平台开发 → android 室内定位 源码下载(蓝牙定位)

android 室内定位 源码下载(蓝牙定位)

Android平台开发

下载此实例
  • 开发语言:Java
  • 实例大小:9.35M
  • 下载次数:134
  • 浏览次数:1530
  • 发布时间:2016-09-29
  • 实例类别:Android平台开发
  • 发 布 人:crazycode
  • 文件格式:.zip
  • 所需积分:2
 相关标签: Android 蓝牙 定位

实例介绍

【实例简介】

【实例截图】

【核心代码】

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);
		}
	}
}

标签: Android 蓝牙 定位

实例下载地址

android 室内定位 源码下载(蓝牙定位)

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 wei-chen 发表于: 2018-04-17 22:17 24
请问这几个的档案内容是什么?可以请你更新一下 import com.aprilbrother.aprilbrothersdk.Beacon; import com.aprilbrother.aprilbrothersdk.BeaconManager; import com.aprilbrother.aprilbrothersdk.BeaconManager.RangingListener; import com.aprilbrother.aprilbrothersdk.Region; import com.aprilbrother.aprilbrothersdk.utils.AprilL;

支持(0) 盖楼(回复)

第 2 楼 xujie丶 发表于: 2018-12-20 10:50 51
这个怎么操作呀?

支持(0) 盖楼(回复)

第 3 楼 794160190@qq.co 发表于: 2020-05-12 10:34 31
这个怎么操作呀?

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有3条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警