基本信息
源码名称:android 室内定位 源码下载(蓝牙定位)
源码大小:9.35M
文件格式:.zip
开发语言:Java
更新时间:2016-09-29
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 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);
		}
	}
}