基于距离传感器的自动锁屏程序
最近写了一个基于距离传感器锁屏的程序,在这里Mark一下。
手机为了节约能耗,一段时间没有操作就会自动锁屏,这带来了一个问题——你得不断的解锁,当然用了这么多年大家也许都习惯了。现在我想尝试一种既节约能耗,又不用频繁解锁的方法。
当手机被装到包里或者口袋里面,距离传感器都是可以检测出来的,所以为什么不根据这个特性来控制手机锁屏呢?
关于这个问题的详细讨论可以看看这里。
1.程序功能
主界面
主要功能:
在后台创建一个后台服务,用来检测距离传感器是否被触发,如果触发就锁住屏幕。
带来的好处:
打开这个服务后,可以尝试把手机设置为不自动锁屏或者延长自动锁屏的时间,在不想用手机之后直接装到兜里面,由于距离传感器被触发,手机将自动锁屏。如果你的手机放在桌上,没有锁屏恰好有人想看你手机上的内容,你可以直接把手放到手机上,距离传感器被触发,就会锁住屏幕,这也比较符合人下意识的动作。对于像我这样不大喜欢频繁解锁的人,应该可以试试。
带来的问题:
一般的手机距离传感器应该是在听筒位置,在使用手机的时候一般不容易被触发。当然使用微信,或者语音助手的时候除外(我也在想解决这个问题的方案)。另外打电话接电话的时候必然会触发距离传感器。
解决方法:
尽量检测出在使用听筒时触发距离传感器的情况,然后在这种情况下,暂停锁屏服务,在不用听筒之后再将锁屏服务打开。在这个程序中,我只实现了检测来电和去电两种情形的检测,在打电话的时候,停止锁屏服务,在挂断电话后重启锁屏服务。
2.实现
2.1最关键的部分:锁屏功能
public static class Controller extends Activity {
DevicePolicyManager mDPM;
ComponentName mDeviceAdminSample;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 首先我们要获得android设备管理代理
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
// LockScreen 继承自 DeviceAdminReceiver
mDeviceAdminSample = new ComponentName(Controller.this,
LockScreen.class);
// 得到当前设备管理器有没有激活(获取权限)
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
if (!active) {
// 如果没有激活的话,就去提示用户激活(第一次运行程序时)
getAdmin();
} else {
// 如果已经激活的话,就执行立即锁屏
mDPM.lockNow();
}
// killMyself ,锁屏之后就立即kill掉我们的Activity,避免资源的浪费;
//android.os.Process.killProcess(android.os.Process.myPid());
finish();
}
2.2后台服务
首先继承Android.app.Service类,然后实现 OnCreate、OnStart、OnDestroy方法,然后实现SensorEventListener接口中的两个函数——onAccuracyChanged和onSensorChanged,一个是判断精度变化,一个是判断传感器距离变化。
最后将这个服务在Manifest文件中注册一个名称,然后在MainActivity中直接通过这个名称来启动和停止。
public class AutoLockService extends Service implements SensorEventListener {
}
2.3获取权限
首先在res目录下新建一个xml文件夹,然后在该文件夹下新建文件device_admin_sample.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>然后在Manifest文件中注册一个广播接收者:
<!-- 接收请求Device Admin广播 --> <receiver
android:name="org.hq.autolock.LockScreen"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin_sample" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
2.4判断来电和去电状态
继承BroadcastReceiver,已接收到广播就停止锁屏服务,判断挂机之后重新开启锁屏服务。
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
//停止锁屏服务
if( null == myintent ){
myintent = new Intent("org.hq.autoLockService");
}
context.stopService(myintent);
System.out.println("action"+intent.getAction());
if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
//如果是去电(拨出)
System.out.println("拨出");
}else{
//查了下android文档,貌似没有专门用于接收来电的action,所以,非去电即来电
System.out.println("来电");
TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
//如果挂断了,开启锁屏服务
if( TelephonyManager.CALL_STATE_IDLE == tm.getCallState() ){
if( null == myintent ){
myintent = new Intent("org.hq.autoLockService");
}
context.startService(myintent);
}
}
}
2.5获取传感器信息
首先获取传感器管理类,通过SensorManager就可以获得手机上所有的传感器信息。要监测传感器参数变化,只需新建一个SensorEvenListener。
sm = (SensorManager) getSystemService(SENSOR_SERVICE); // 获取传感器管理类
promixty = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY); // 获取距离传感器
3.题外话
在写完这个程序,装到手机里用了一段时间之后,发现用一个软件来实现锁屏其实没多大必要。很多智能手机用户已经适应甚至依赖那种解锁的感觉,所以并不感到繁琐。因此,用距离传感器来锁屏,也许大材小用没有必要。
最近看到一款应用,用距离传感器来自动接听来电,这个倒方便不少,省去了滑屏的动作。有兴趣的可以试试看~
工程源码:
http://download.csdn.net/detail/he_qiao_2010/5979623
没有积分的到这里下载:
http://pan.baidu.com/share/link?shareid=207532332&uk=1158831200
APK文件:
http://pan.baidu.com/share/link?uk=1158831200&shareid=2641184411

浙公网安备 33010602011771号