android传感器 android与Service通信 使用BroadCast发送和接收消息

由于需要做android传感器(加速度相关)采集应用,而加速度相关信息采集是实时的,显然创建一个Service来单独处理传感器的信息采集是明智之举,而之气没有使用过Service和BroadcastReceiver,因此在前期学习时颇为不顺。


之前参考了一篇文章《Android 传感器应用举例》,无奈有种被坑的感觉:http://wenku.baidu.com/view/ef9bd802a6c30c2259019e8f.html


在编译时出现java.lang.RuntimeException: Unable to instantiate receiver

折腾两天,终于找到问题根源了


被坑原因并不是文章有问题,而是文章中提到的BroadcastReceiver是Activity的内部类,但是文中没有给出AndroidManifest.xml文件,我想当然地认为与普通的服务和广播写法一样。

正确的写法如下文:http://blog.csdn.net/lzg08_08/article/details/8303003


特别注意:Activity创建BroadcastReceiver内部类时要声明为static类,同时在AndroidManifest.xml文件中需要用$标识出内部Receiver。


废话不多说,贴出源码

SensorService.java

package com.dm;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.util.Log;

public class SensorService extends Service {

	// 声明加速度传感器对象
	private SensorManager sm = null; // 获取SensorManager对象,通过它可以获得距离,加速度等传感器对象
	private Sensor accelerationSensor = null; // 加速度传感器
	private Sensor magneticSensor = null; // 磁力传感器
	// ******************加速度传感器初始化变量*********************************************//
	double gravity[] = new double[3];// 代表3个方向的重力加速度
	double xAcceleration = 0;// 代表3个方向的真正加速度
	double yAcceleration = 0;
	double zAcceleration = 0;
	double currentAcceleration = 0; // 当前的合加速度
	double maxAcceleration = 0; // 最大加速度
	// 接下来定义的数组是为了对加速度传感器采集的加速度加以计算和转化而定义的,转化的目的是为了使数据看上去更符合我们平时的习惯
	float[] magneticValues = new float[3];
	float[] accelerationValues = new float[3];
	float[] values = new float[3];
	float[] rotate = new float[9];
	// 初始化的三个方位角的值
	float Yaw = 0;
	float Pitch = 0; // values[1]
	float Roll = 0;
	
	final static int CMD_STOP = 0;
	final static int CMD_UPDATAE = 1;
	
	
	public void onCreate() {
		super.onCreate();

		/**
		 * 设置加速度传感器
		 */
		sm = (SensorManager) this.getSystemService(SENSOR_SERVICE);
		accelerationSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		magneticSensor = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
		sm.registerListener(accelerationListener, accelerationSensor,
				SensorManager.SENSOR_DELAY_UI);
		sm.registerListener(magneticListener, accelerationSensor,
				SensorManager.SENSOR_DELAY_UI);
		sm.registerListener(magneticListener, magneticSensor,
				SensorManager.SENSOR_DELAY_UI);


	}
	
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		Log.i("-----------SensorService---------------","服务启动" ); 

	}
	//重写 onDestroy 方法
	public void onDestroy() {
		sm.unregisterListener(accelerationListener);
		currentAcceleration = 0;
		maxAcceleration = 0;
		xAcceleration = yAcceleration = zAcceleration = 0;

		// 注销监听器
		sm.unregisterListener(magneticListener);
		sm = null;

		super.onDestroy();
	}
	
	
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	
	// **************************加速度测试传感器部分*************************
	// 加速度传感器监听器,当获取的传感器数据发生精度要求范围内的变化时,监听器会调用onSensorChanged函数
	SensorEventListener accelerationListener = new SensorEventListener() {
		
		public void onSensorChanged(SensorEvent event) {
			final double alpha = 0.8;
			gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
			gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
			gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

			xAcceleration = event.values[0] - gravity[0];
			yAcceleration = event.values[1] - gravity[1];
			zAcceleration = event.values[2] - gravity[2];

			// 计算三个方向上的和加速度
			double G = Math.sqrt(Math.pow(xAcceleration, 2)
					+ Math.pow(zAcceleration, 2) + Math.pow(yAcceleration, 2));
			currentAcceleration = G;
			if (currentAcceleration > maxAcceleration)
				maxAcceleration = currentAcceleration;
			
			Intent i = new Intent();
			i.setAction("com.dm.accReceiver");
			i.putExtra("xAcceleration", xAcceleration);
			i.putExtra("yAcceleration", yAcceleration);
			i.putExtra("zAcceleration", zAcceleration);
			i.putExtra("currentAcceleration", currentAcceleration);
			i.putExtra("maxAcceleration", maxAcceleration);
			sendBroadcast(i);
		}

		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}

	};

	// ************************方向传感器**************************
	// 手机方位传感器监听器,当获取的加速度或者磁力传感器数据发生精度要求范围内的变化时,监听器会调用onSensorChanged函数
	SensorEventListener magneticListener = new SensorEventListener() {

		public void onSensorChanged(SensorEvent event) {
			// 如果是加速度传感器的值发生了变化
			if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
				accelerationValues = event.values;
			}
			// 如果是磁力传感器的值发生了变化
			if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
				magneticValues = event.values;
			}
			SensorManager.getRotationMatrix(rotate, null, accelerationValues,
					magneticValues);
			SensorManager.getOrientation(rotate, values);
			for (int i = 0; i < 3; i++) {
				values[i] = (float) Math.toDegrees(values[i]);
				Log.i("方位检测", "values[" + i + "]=" + values[i]);
			}
			Yaw = values[0];
			Pitch = values[1];
			Roll = values[2];
			
			Intent i = new Intent();
			i.setAction("com.dm.magReceiver");
			i.putExtra("Yaw", Yaw);
			i.putExtra("Pitch", Pitch);
			i.putExtra("Roll", Roll);
			sendBroadcast(i);
		}

		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}
	};
	
}
Activity中核心代码(在onCreate()方法中创建BroadcastReceiver实例)
		BroadcastReceiver accReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				Bundle bundle = intent.getExtras();// 获得 Bundle
				xAcceleration = bundle.getDouble("xAcceleration", 0);
				yAcceleration = bundle.getDouble("yAcceleration", 0);
				zAcceleration = bundle.getDouble("zAcceleration", 0);
				currentAcceleration = bundle.getDouble("currentAcceleration", 0);
				maxAcceleration = bundle.getDouble("maxAcceleration", 0);
				
				Log.i("-----------accReceiver---------------", String.valueOf(xAcceleration) + "|" +
						String.valueOf(xAcceleration) + "|" +
						String.valueOf(yAcceleration) + "|" +
						String.valueOf(zAcceleration) + "|" +
						String.valueOf(currentAcceleration) + "|" +
						String.valueOf(maxAcceleration) ); 
			        }
			};
			
		IntentFilter accFilter = new IntentFilter();
		accFilter.addAction("com.dm.accReceiver");
		registerReceiver(accReceiver, accFilter);
		
		// 新建并注册广播接收器,用于接收传感器类传递的数据
		BroadcastReceiver magReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				Bundle bundle = intent.getExtras();// 获得 Bundle
				Yaw = bundle.getFloat("Yaw", 0);
				Pitch = bundle.getFloat("Pitch", 0);
				Roll = bundle.getFloat("Roll", 0);
				
				Log.i("-----------magReceiver---------------", 
						String.valueOf(Yaw) + "|" +
						String.valueOf(Pitch) + "|" +
						String.valueOf(Roll) ); 
			        }
			};
					
		IntentFilter magFilter = new IntentFilter();
		magFilter.addAction("com.dm.magReceiver");
		registerReceiver(magReceiver, magFilter);
				
				
		// 启动注册了传感器监听的 Service
		Intent i = new Intent(this, SensorService.class);
		startService(i);



希望大家在做android传感器项目时不要再犯这样的错误。





  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值