本文的例子,是一个非常有趣的例子。该例子中会用到两个知识点,首先,1.是利用方向传感器来检测手机与人脸的距离来确定是否要去锁屏。2.是获取android设备管理器来进行锁屏的操作。其实该功能非常实用,比如:在打电话时手机靠近人体会自动锁屏,而拿开时又会变亮。也是利用传感器实现的。
代码的实现:
一.首先是在MainActivity中来实现对方向传感器的一系列操作:
1.首先,activity_main布局文件的实现:
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="cn.com.hbtv.testautolockdemo.MainActivity">
<TextView
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="传感器锁屏程序"
android:textSize="20sp"
android:id="@+id/titel_tv"
/>
<Button
android:id="@+id/start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="启用服务"
android:textSize="20sp"
android:layout_centerHorizontal="true"
android:layout_below="@id/titel_tv"
/>
<Button
android:id="@+id/stop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="停止服务"
android:textSize="20sp"
android:layout_centerHorizontal="true"
android:layout_below="@id/start"
/>
<Button
android:id="@+id/exit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="退出"
android:textSize="20sp"
android:layout_centerHorizontal="true"
android:layout_below="@id/stop"
/>
<TextView
android:id="@+id/sensortitel_tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="传感器信息:"
android:textSize="20sp"
android:layout_centerHorizontal="true"
android:layout_below="@id/exit"
/>
<TextView
android:id="@+id/sensorinfo_tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="传感器信息:"
android:textSize="20sp"
android:layout_centerHorizontal="true"
android:layout_below="@id/sensortitel_tv"
/>
</RelativeLayout>
2.java代码的实现,具体的意思代码中已有所解释:
public class MainActivity extends AppCompatActivity {
private Button start;
private Button stop;
private Button exit;
private TextView sensorinfo_tv;
Intent intent;
private SensorManager sm=null;
private Sensor promixty=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (null==sm){
sm= (SensorManager) getSystemService(SENSOR_SERVICE);
promixty=sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
}
String sensorinfo;
if (null!=promixty){
sensorinfo="传感器名称:"+promixty.getName()+"\n"
+"设备版本:"+ promixty.getVersion()+"\n"
+"供应商:"+promixty.getVendor()+"\n";
}else {
sensorinfo="无法获取距离传感器的名称";
}
initUI();
intent=new Intent(this,AutoLockService.class);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//
start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//
stop();
}
});
exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//
finish();
}
});
sensorinfo_tv.setText(sensorinfo);
}
private void initUI() {
start= (Button) findViewById(R.id.start);
stop= (Button) findViewById(R.id.stop);
exit= (Button) findViewById(R.id.exit);
sensorinfo_tv= (TextView) findViewById(R.id.sensorinfo_tv);
}
private void start() {
Bundle bundle=new Bundle();
bundle.putInt("distance",3);
bundle.putBoolean("activited",true);
intent.putExtras(bundle);
startService(intent);
}
private void stop() {
stopService(intent);
Toast.makeText(MainActivity.this, "已停止后台服务", Toast.LENGTH_SHORT).show();
}
}
if (null==sm){
sm= (SensorManager) getSystemService(SENSOR_SERVICE);
promixty=sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
}
private void start() {
Bundle bundle=new Bundle();
bundle.putInt("distance",3);
bundle.putBoolean("activited",true);
intent.putExtras(bundle);
startService(intent);
}
启动一个AutoLockService 的服务在后台进行距离的运算以及锁屏的监听:
public class AutoLockService extends Service implements SensorEventListener{
private SensorManager sm=null;
private Sensor promixty=null;
//默认启动锁频
private static boolean ACTIVITED=true;
//锁屏距离
private static int LOCK_DIST=3;
public AutoLockService() {
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
if (null==sm){
sm= (SensorManager) getSystemService(SENSOR_SERVICE);
promixty=sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);//获取距离传感器
}
//显示距离传感器数据
if(null!=promixty){
Toast.makeText(AutoLockService.this, "已经创建后台服务", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(AutoLockService.this, "无法找到距离传感器", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (null!=sm){
sm.unregisterListener(this);
}
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (null!=intent){
Bundle bundle = intent.getExtras();
Toast.makeText(AutoLockService.this, "后台服务已启动", Toast.LENGTH_SHORT).show();
//从intent中获取参数
if (null!=bundle){
int distance = bundle.getInt("distance");
ACTIVITED=bundle.getBoolean("activited");
if (distance>0&&distance<9){
LOCK_DIST=distance;
}
}
sm.registerListener(this,promixty,SensorManager.SENSOR_DELAY_NORMAL);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.values[0]<LOCK_DIST){//距离小于5,锁屏;
if (ACTIVITED){
lockScreen();
}
}
}
private void lockScreen() {
//跳至锁屏界面;
Intent intent=new Intent();
//在activity之外启动,要加上FLAG_ACTIVITY_NEW_TASK flag
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(this,LockScreen.Controller.class);
startActivity(intent);
}
//监听精度变化
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
Toast.makeText(AutoLockService.this, "距离传感器promixty的精度变化:"+i, Toast.LENGTH_SHORT).show();
}
}
在该服务中我们要启动一个广播就是锁屏广播,当第一次使用是获取,锁屏权限来锁屏:
public class LockScreen extends DeviceAdminReceiver {
static final int RESULT_ENABLE=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
finish();
}
public void getAdmin(){
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,mDeviceAdminSample);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"欢迎使用,在第一次使用时请授予该程序锁屏权限");
startActivityForResult(intent,RESULT_ENABLE);
Toast.makeText(this, "管理员权限已开启!", Toast.LENGTH_SHORT).show();
}
}
}
其中AndroidManifest.xml中需要配置:
<activity android:name=".LockScreen$Controller"/>
<service
android:name=".AutoLockService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:enabled="true"
android:exported="true" >
<!--<meta-data-->
<!--android:name="android.app.device_admin"-->
<!--/>-->
<!--<intent-filter>-->
<!--<action android:name=".autoLockService"/>-->
<!--</intent-filter>-->
</service>
<receiver
android:name=".LockScreen"
android:description="@string/sample_device_admin_description"
android:label="@string/sample_device_admin"
android:permission="android.permission.BIND_DEVICE_ADMIN"
android:enabled="true"
android:exported="true">
<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>
最后一步在res中创建xml包实现device_admin_sample:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
<expire-password />
<encrypted-storage />
<disable-camera />
</uses-policies>
</device-admin>
到这里已经基本完成了。