抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > Android实现简单的检测手机自由落体关闭屏幕

Android实现简单的检测手机自由落体关闭屏幕

时间:2023-08-27 03:04:29

相关推荐

实现功能如下:在背景运行app,检测到自由落体状态时,熄灭屏幕,可重复测试。

1. 检测自由落体动作

需要使用到加速度感应器TYPE_ACCELEROMETER

SensorManager mSensorManager;private float mLastX;private float mLastY;private float mLastZ;private double force;@Overridepublic void onCreate() {super.onCreate();mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);mSensorManager.registerListener(sensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);}private final SensorEventListener sensorListener = new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent event) {try {if(event.sensor == null){return;}}catch (Exception ex){}if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){mLastX = event.values[0];mLastY = event.values[1];mLastZ = event.values[2];force = Math.sqrt(mLastX*mLastX+mLastY*mLastY+mLastZ*mLastZ);}if(force < 1 ){Log.i("Kunkka","force < 1 START-------------");new Handler().postDelayed(new Runnable() {@Overridepublic void run() {if (force < 1) {Log.i("Kunkka","force < 1 END, SCREEN OFF");screenOff();}}}, 20);}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};

标黄的是判断手机失重的依据,即三个方向的合力为0。由于不是那么精确,让其合力<1即可。

另外为了防止手机平时突然出现符合这个结果的,当第一次出现符合条件的合力时,延迟20ms再检测一次,(最好连续检测多次来确定连续处于失重状态),假如依旧符合失重,就认定此时在失重状态。再做下一步的处理。

2. 关闭屏幕

熄灭屏幕代码:

private void screenOff(){DevicePolicyManager policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);ComponentName adminReceiver = new ComponentName(DeviceFallDetectService.this, MyAdminReceiver.class);boolean admin = policyManager.isAdminActive(adminReceiver);if (admin) {policyManager.lockNow();} else {Toast.makeText(this,"没有设备管理权限",Toast.LENGTH_LONG).show();}}

息屏主要使用的是DevicePolicyManager 类,此外MyAdminReceiver是一个息屏管理的广播接收器,该接受器非常重要,系统设置中正是通过该接收器才找到的应用程序,该广播接收器在AndroidManifest.xml中的声明如下:

<receiverandroid:name=".MyAdminReceiver"android:permission="android.permission.BIND_DEVICE_ADMIN"><meta-dataandroid:name="android.app.device_admin"android:resource="@xml/admin"/><intent-filter><action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/></intent-filter></receiver>

xml/admin.xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?><device-admin xmlns:android="/apk/res/android" ><uses-policies><force-lock /></uses-policies></device-admin>

Receiver的源码空的就可以,只需要继承DeviceAdminReceiver:

public class MyAdminReceiver extends DeviceAdminReceiver {}

网上说还需要加权限

<uses-permission android:name="android.permission.USES_POLICY_FORCE_LOCK" />

但我没加去运行也没出什么问题。

3. Forground service实现重复运行

由于运行在background service中的话,屏幕关了再打开,好像background service就被停下了。

为了每次屏幕亮了都可以继续运行,把service改成O之后的foreground service:

首先startservice的地方,改成foreground方式启动:

Intent intent = new Intent(MainActivity.this,DeviceFallDetectService.class);startForegroundService(intent);MainActivity.this.finish();

然后在service的onStartCommand中,立刻声明startForeground。

并且android O 以后每个Notification都需要依附一个channel,要不然就报错。加一个简单的channel:

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {initChanel();return super.onStartCommand(intent, flags, startId);} private void initChanel(){NotificationChannel channel = new NotificationChannel(CHANNEL_ID,"FallDetect",NotificationManager.IMPORTANCE_HIGH);NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);manager.createNotificationChannel(channel);Notification notification = new Notification.Builder(getApplicationContext(),CHANNEL_ID).build();startForeground(3210, notification);}

大功告成

如果觉得《Android实现简单的检测手机自由落体关闭屏幕》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。