Android实现简单的检测手机自由落体关闭屏幕
實現功能如下:在背景運行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="http://schemas.android.com/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);}大功告成
?
?轉載于:https://www.cnblogs.com/kunkka/p/9779540.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Android实现简单的检测手机自由落体关闭屏幕的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【BIRT】使用rptlibrary设置
- 下一篇: 什么是Java的应用程序?(写给第一次接