上篇文章介绍了传感器的基础用法(如有需要,可先移步),下面将通过两个实战案例学习具体如何使用。
一、靠近黑屏
这是距离传感器的简单应用。
–检测手机是否贴在耳朵上正在打电话,以便自动熄灭屏幕达到省电的目的。也可用于皮套、口袋模式下自动实现解锁与锁屏动作。
–用到电量管理器PowerManager来控制屏幕的亮灭,需要获取权限
–我们并不需要获取距离传感器的值,而是让它和PowerManager的内建功能一起配合使用
新建项目SensorDemo3。
修改activity_main.xml文件,代码如下:
下面定义了一个RelativeLayout布局,里面有一个TextView
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp"
>
<TextView
android:textSize="20sp"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="不要靠近我~~我会变黑的"/>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
修改AndroidManifest.xml文件,获取权限
获取相关的系统唤醒锁定权限。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.WAKE_LOCK"/>
..............
修改MainAcitivity,代码如下:
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager sensorManager;
/*使用电量管理器控制屏幕的熄灭和唤醒*/
private PowerManager pm;
private PowerManager.WakeLock wakeLock;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
pm = (PowerManager) getSystemService(POWER_SERVICE);
closeOrClose();
}
/**
* 初始化唤醒锁wakeLock,直接使用内置PROXIMITY_SCREEN_OFF_WAKE_LOCK,
* 就可以直接实现靠近熄灭屏幕的功能
*
* 初始化完要调用acquire()方法启用
*/
@SuppressLint("InvalidWakeLockTag")
private void closeOrClose() {
wakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
"w1");
wakeLock.setReferenceCounted(false);
wakeLock.acquire();
}
@Override
protected void onResume() {
/*注册距离传感器,只有注册了距离传感器唤醒锁才有效果*/
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
SensorManager.SENSOR_DELAY_NORMAL);
super.onResume();
}
@Override
protected void onStop() {
/*释放传感器和唤醒锁*/
wakeLock.release();
sensorManager.unregisterListener(this);
super.onStop();
}
@Override
public void onSensorChanged(SensorEvent event) {
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
PowerManager要点
https://blog.youkuaiyun.com/fengyeNom1/article/details/121373158
二、计步器
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:name="android.hardware.sensor.stepcounter" />
<uses-feature android:name="android.hardware.sensor.stepdetector" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
..............
修改activity_main.xml代码,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/step_counter_txt"
android:text="总步数"
android:layout_gravity="center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/step_counter"
android:text="-1"
android:layout_gravity="center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/step_detector_txt"
android:text="单次记步"
android:layout_gravity="center" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/step_detector"
android:text="0"
android:layout_gravity="center" />
</LinearLayout>
修改MainActivity代码如下:
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private TextView mStepCounterTextView, mStepDetectorTextView; // Textview for showing steps counter of respective sensors
private boolean isActivityRunning; // if true then activity is in foreground
private int mStepDetectCounter = 0; // used in step detector sensor
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PackageManager packageManager = getPackageManager();
if (packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)
&& packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR)) {
mStepCounterTextView = (TextView) findViewById(R.id.step_counter);
mStepDetectorTextView = (TextView) findViewById(R.id.step_detector);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
} else {
Toast.makeText(this, "This phone does not supports required sensor", Toast.LENGTH_SHORT).show();
}
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED){
//ask for permission
requestPermissions(new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, 1);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_STEP_COUNTER:
if (isActivityRunning) {
mStepCounterTextView.setText(String.valueOf(event.values[0]));
}
break;
case Sensor.TYPE_STEP_DETECTOR:
if (isActivityRunning) {
mStepDetectCounter++;
mStepDetectorTextView.setText(String.valueOf(mStepDetectCounter));
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
protected void onResume() {
super.onResume();
isActivityRunning = true;
Sensor countSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
Sensor detectSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
if (countSensor != null) {
mSensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_FASTEST);
} else {
Toast.makeText(this, "Count sensor not available!", Toast.LENGTH_LONG).show();
}
if (detectSensor != null) {
mSensorManager.registerListener(this, detectSensor, SensorManager.SENSOR_DELAY_FASTEST);
} else {
Toast.makeText(this, "Count sensor not available!", Toast.LENGTH_LONG).show();
}
}
@Override
protected void onPause() {
super.onPause();
isActivityRunning = false;
}
@Override
protected void onStop() {
super.onStop();
mSensorManager.unregisterListener(this);
}
}