Android传感器应用_指南针(《第一行代码》教程)

Posted AdamDuncan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android传感器应用_指南针(《第一行代码》教程)相关的知识,希望对你有一定的参考价值。

1、检测你的手机里有哪些传感器

CheckSensor.java代码架构

1、使用一个ScrollView包裹的TextView把所有的传感器厂家、设备名称、版本、类型编号等打印出来

2、其中为了得到传感器名字,使用了一个静态内部类,这个静态内部类的作用是把(int)Sensor.getType()转化成对应的传感器名字

  这个内部类唯一的方法,getSensorTypeName(int type)就是为了起到这个作用

package com.example.checksensor;

import java.util.List;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textViewOfShowSensorList = (TextView)findViewById(R.id.show_sensor);
SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
StringBuilder sb = new StringBuilder();
sb.append("该手机总共有传感器: "+sensorList.size()+"个\\n");
String typeName = "";
for (Sensor i:sensorList) {
Log.d("", String.format("类型编号: %d\\n", i.getType()));
}
for (Sensor i:sensorList) {
typeName = SensorTypeName.getSensorTypeName(i.getType());
sb.append(String.format("传感器名字:%s\\n", typeName));
sb.append(String.format("设备名称: %s\\n", i.getName()));
sb.append(String.format("设备版本: %s\\n", i.getVersion()));
sb.append(String.format("设备供应商: %s\\n\\n", i.getVendor()));
}
textViewOfShowSensorList.setText(sb.toString());
}
//为什么子类才能被形容为static类型,
//新建一个类存储各种传感器类型,这样的好处是,每次新建前面的类,不必花费大量的代价
//存储这些无关紧要的东西
static class SensorTypeName {
static private String []typeName;
//为什么在static里面还要使用关键字,应该已经是static了啊
static {
typeName = new String[20];
typeName[Sensor.TYPE_GRAVITY] = "重力传感器";
typeName[Sensor.TYPE_LIGHT] = "光线传感器";
typeName[Sensor.TYPE_PRESSURE] = "压力传感器";
typeName[Sensor.TYPE_RELATIVE_HUMIDITY] = "TYPE_RELATIVE_HUMIDITY";
typeName[Sensor.TYPE_AMBIENT_TEMPERATURE] = "TYPE_AMBIENT_TEMPERATURE";
typeName[Sensor.TYPE_GYROSCOPE] = "陀螺仪";
typeName[0] = "未知";
typeName[Sensor.TYPE_ACCELEROMETER] = "加速度";
typeName[Sensor.TYPE_MAGNETIC_FIELD] = "磁力";
typeName[Sensor.TYPE_ORIENTATION] = "方向";
typeName[Sensor.TYPE_TEMPERATURE] = "温度";
typeName[Sensor.TYPE_PROXIMITY] = "接近,距离传感器";
typeName[Sensor.TYPE_LINEAR_ACCELERATION] = "线性加速度";
typeName[Sensor.TYPE_ROTATION_VECTOR] = "旋转矢量";
//itsNames[Sensor.TYPE_GAME_ROTATION_VECTOR] = "TYPE_GAME_ROTATION_VECTOR";
typeName[14] = "TYPE_MAGNETIC_FIELD_UNCALIBRATED";
}
public static String getSensorTypeName(int type) {
if (type > 0 && type < typeName.length) {
return typeName[type];
}
return null;
}
}
}

xml文件:

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<TextView android:id="@+id/show_sensor"
android:layout_width="match_parent"
android:layout_height="match_parent">
</TextView>

</LinearLayout>
</ScrollView>

 得到结果如下:

 

 

2、新建一个指南针实例

StudyCompass.java架构

新建一个SensorManager类以及MagneticSensor、AccelerometerSensor.

通过使用sensorManager.registerListener(listener, magneticSensor, SensorManager.SENSOR_DELAY_NORMAL);

新建一个SensorEventListener对象listener。重写其中的onSensorChanged(SensorEvent sensorEvent)。

 注意点:

其中使用动画效果的时候,需要使用clone()。不然会指向同一个引用。

rotateAnimation.setFillAfter(true);
compassImg.startAnimation(rotateAnimation);

 

package com.example.studycompass;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;


public class MainActivity extends Activity {

private ImageView compassImg;
private ImageView arrowImg;
private SensorManager sensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
compassImg = (ImageView)findViewById(R.id.compass_img);
arrowImg = (ImageView)findViewById(R.id.arrow_img);
sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Sensor magneticSensor = (Sensor)sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Sensor accelerometerSensor = (Sensor)sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(listener, magneticSensor, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onDestroy() {
super.onDestroy();
if (sensorManager != null) {
sensorManager.unregisterListener(listener);
}
}
private SensorEventListener listener = new SensorEventListener() {
float[] magneticArray = new float[3];
float[] accelerometerArray = new float[3];
private float lastRotateDegree;
private float rotateDegree;
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
// TODO Auto-generated method stub
if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
/**
* 这里必须使用clone方法不然的话,会指向同一个引用
*/
magneticArray = sensorEvent.values.clone();
} else if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accelerometerArray = sensorEvent.values.clone();
}

float[] rotation = new float[9];
float[] orientation = new float[3];
SensorManager.getRotationMatrix(rotation, null, accelerometerArray, magneticArray);
SensorManager.getOrientation(rotation, orientation);
rotateDegree = -(float)Math.toDegrees(orientation[0]);
if (Math.abs(lastRotateDegree - rotateDegree) > 1) {
RotateAnimation rotateAnimation = new RotateAnimation(lastRotateDegree, rotateDegree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
//使得动画保持在终止结果
rotateAnimation.setFillAfter(true);
compassImg.startAnimation(rotateAnimation);
lastRotateDegree = rotateDegree;
}
}

@Override
public void onAccuracyChanged(Sensor paramSensor, int paramInt) {
// TODO Auto-generated method stub

}

};
}

 首先使用叠加的两个图片,一个作为指针,另一个作为背景四个方向l

xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ImageView
android:id="@+id/compass_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/compass"/>

<ImageView
android:id="@+id/arrow_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/arrow"/>

</RelativeLayout>

得到结果:

 

以上是关于Android传感器应用_指南针(《第一行代码》教程)的主要内容,如果未能解决你的问题,请参考以下文章

Android 应用程序只能安装在带有磁传感器的设备上吗?

Android开发之方向传感器的使用? (2011-10-13 20:56:05)转载▼

Android_5_学习《第一行代码》的使用摄像头和相册无法显示图片问题解决

人工智能闯关指南:清华教授教你过第一关!

8年Android开发教你如何写简历,复习指南

Android第一行代码之制作简易版新闻应用