本文的例子,是一个非常有趣的例子。该例子中会用到两个知识点,首先,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>到这里已经基本完成了。