public boolean isContain(int x, int y){//判断点是否在圆内
int tempx =(int) (x + mv.zhongBitmap2.getWidth()/2.0);
int tempy =(int) (y + mv.zhongBitmap2.getWidth()/2.0);
int ox = (int) (mv.zhong1_X+ mv.zhongBitmap1.getWidth()/2.0);
int oy = (int) (mv.zhong1_X+ mv.zhongBitmap1.getWidth()/2.0);
if(Math.sqrt((tempx-ox)*(tempx-ox)+(tempy-oy)*(tempy-oy))>(mv.zhongBitmap1.getWidth()/2.0-mv.zhongBitmap2.getWidth()/2.0)){//不在圆内return false;
}else{ //在圆内时
return true;
}
}
};
www.55dianzi.com
在传感器监听类中, onSensorChanged 方法用于监听传感器采样值的变化, 例如手机姿态的改变等。上述代码中的is-Contain 方法用于判断界面中间的气泡是否出界, 若出界则返回false.
完成了代码框架的开发后, 便可以对传感器的监听方法onSensorChanged 进行开发了, 其详细代码如下:
publIC void onSensorChanged(int sensor, float[] values){
if(sensor == SensorManager.SENSOR_ORIENTATION){
double pitch = values[SensorManager.DATA_Y];
double roll = values[SensorManager.DATA_Z];
int x=0; int y=0;//临时变量,算中间水泡坐标时用
int tempX=0; int tempY=0;//下面气泡的临时变量
//开始调整x 的值
if(Math.abs(roll)<=k){
mv.shang2_X = mv.shang1_X //上面的
+ (int)(((mv.shangBitmap1.getWidth()
-mv.shangBitmap2.getWidth())/2.0)
-(((mv.shangBitmap1.getWidth()
-mv.shangBitmap2.getWidth())/2.0)*roll)/k);
x = mv.zhong1_X //中间的
+ (int)(((mv.zhongBitmap1.getWidth()
-mv.zhongBitmap2.getWidth())/2.0)
-(((mv.zhongBitmap1.getWidth()
-mv.zhongBitmap2.getWidth())/2.0)*roll)/k);
}else if(roll>k){
mv.shang2_X=mv.shang1_X; x = mv.zhong1_X;
}else{
mv.shang2_X=mv.shang1_X+
mv.shangBitmap1.getWidth()
- mv.shangBitmap2.getWidth();
x = mv.zhong1_X+ mv.zhongBitmap1.getWidth()
- mv.zhongBitmap2.getWidth();
}
//开始调整y 的值
if(Math.abs(pitch)<=k){
mv.zuo2_Y=mv.zuo1_Y //左面的
+ (int)(((mv.zuoBitmap1.getHeight()
-mv.zuoBitmap2.getHeight())/2.0)
+(((mv.zuoBitmap1.getHeight()
-mv.zuoBitmap2.getHeight())/2.0)*pitch)/k);
y =mv.zhong1_Y+ //中间的
(int)(((mv.zhongBitmap1.getHeight()
-mv.zhongBitmap2.getHeight())/2.0)
+(((mv.zhongBitmap1.getHeight()
-mv.zhongBitmap2.getHeight())/2.0)*pitch)/k);
}else if(pitch>k){
mv.zuo2_Y=mv.zuo1_Y
+mv.zuoBitmap1.getHeight()
-mv.zuoBitmap2.getHeight();
y=mv.zhong1_Y+mv.zhongBitmap1.getHeight()
-mv.zhongBitmap2.getHeight();
}else{
mv.zuo2_Y = mv.zuo1_Y; y = mv.zhong1_Y;
}
//下面的
tempX = -(int) (((mv.xiaBitmap1.getWidth()/2-28)*roll
+(mv.xiaBitmap1.getWidth()/2-28)*pitch)/k);
tempY = -(int) ((-(mv.xiaBitmap1.getWidth()/2-28)*roll
-(mv.xiaBitmap1.getWidth()/2-28)*pitch)/k);
//限制下面的气泡范围
if(tempY>mv.xiaBitmap1.getHeight()/2-28){
tempY = mv.xiaBitmap1.getHeight()/2-28;
}
if(tempY < -mv.xiaBitmap1.getHeight()/2+28){
tempY = -mv.xiaBitmap1.getHeight()/2+28;
}
if(tempX > mv.xiaBitmap1.getWidth()/2-28){
tempX = mv.xiaBitmap1.getWidth()/2-28;
}
if(tempX < -mv.xiaBitmap1.getWidth()/2+28){
tempX = -mv.xiaBitmap1.getWidth()/2+28;
}
mv.xia2_X = tempX + mv.xia1_X
+ mv.xiaBitmap1.getWidth()/2
-mv.xiaBitmap2.getWidth()/2;
mv.xia2_Y = tempY + mv.xia1_Y
+ mv.xiaBitmap1.getHeight()/2
- mv.xiaBitmap2.getWidth()/2;
if(isContain(x, y)){//中间的水泡在圆内才改变坐标
mv.zhong2_X = x; mv.zhong2_Y = y;
}
mv.postInvalidate();//重绘MainView
}
}
在onSensorChanged 方法中首先得到pitch 轴以及roll 轴的数值, 然后根据该数值的大小调整水泡在屏幕中的位置, 同时需要对水泡的坐标进行判断, 使其保持在自身所在外框的范围内。
此时运行该程序, 并保证测试工具Sensorsimulator 与Android模拟器的连通, 便会观察到如图1 所示的效果, 通过Sensorsimulator 工具模拟手机的姿态的改变, 屏幕中的水泡便随之向高处运动。
8 程序发布
完成了所有代码的开发后, 就可以将应用程序打包发布了。本案例中只需将Eclipse 工具自动生成的apk 文件拷出即可, 按如下步骤操作。
(1) 进行正式发布之前首先需要将代码中注释为"测试时使用" 的两处代码删掉, 并将注释为"真机使用" 代码的注释去掉。
(2) 完成代码的修改后重新构建项目。
(3) 打开项目文件夹下的bin 目录, 其中名为SPY 的apk文件便为本应用程序的安装包。
(4) 将SPY.apk 文件拷贝到支持传感器的Android 手机中运行即可完成本应用程序的安装。
9 结语
通过开发基于Android 平台的传感器应用---水平仪程序, 读者应该对Android 程序的开发有了一定的了解, 同时读者也应该了解到在Android 平台下使用传感器来丰富自己软件的功能是十分方便的。
另外, 本案例虽然只对姿态传感器进行了应用, 但相信通过对本案例的学习, 读者已经有能力对其他传感器进行应用,开发出更具新意的吸引人的其他应用程序。