第一次写博客,只想把自己的一些经验分享出来,写的不好,轻喷。
我的项目中有这样一个需求,通过距离传感器判断,人与平板电脑的距离,如果很近并且在5秒内一直在这个距离当中。则会提示一个对话框---请远离屏幕!
思路:
首先,这个功能需要做成服务,也就是在 HD的开发者选项中,添加一个CheckBoxPreference,通过persist.sys.distance保存的值进行判断CheckBoxPreference是否为选中状态,开启或关闭 “视力保护”,也就是距离传感器的Service。
//System.out.println("进去create");
// dialog.show();
// 获取传感器对象
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// 获取距离传感器对象
ProximitySensor = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
proximityListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
float[] its = event.values;
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY
&& its != null) {
// 判断当距离传感器 人与电脑距离很近时 弹窗提示
if (its[0] == 0.0) {
// 计时器 5秒后执行 调用窗体的方法
dialogThread();
//System.out.println("开始");
} else {
//Log.i("text", "手离开了");
try {
if (timer != null)
// 关闭计时器
timer.cancel();
if (dialog.isShowing())
Thread.sleep(2000);
// 窗体默认显示2秒后关闭
dialog.dismiss();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
OnCreate 方法中获取距离传感器对象,设置传感器对象的监听事件,通过its[0]的值是否为0,则调用dialogThread。
private void dialogThread() {
timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println(num1);
if (num1 == 0) {
timer.cancel();
handler.post(new Runnable() {
@Override
public void run() {
// CreateDialog();
handler.sendEmptyMessage(0);
}
});
} else {
num1--;
}
}
};
num1 = 5;
timer.schedule(timerTask, 0, 1000);
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 初始化dialog对象
CreateDialog();
dialog.show();
}
};
这里如何5秒后调用弹窗,我是用计时器来实现的。每隔1秒执行一次 num1-- 一次,当num1等于0时,执行调用ALertDialog方法,当然在OnCreate方法中,当物体离开距离传感器时,会关闭计时器,num1重置,再进入时,调用计时器。
/**
* 系统默认的alertDialog
*/
Builder builder = new AlertDialog.Builder(this);
builder.setTitle(this.getResources().getString(R.string.title));
builder.setMessage(this.getResources().getString(R.string.message));
// 点击区域外不关闭对话框
builder.setCancelable(false);
builder.setNegativeButton(this.getResources().getString(R.string.exit), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
dialog = builder.create();
// 在dialog show方法之前添加如下代码,表示该dialog是一个系统的dialog**
dialog.getWindow().setType(
(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
我用的是系统默认的alertDialog,你也可以用自定义的,这个因人而已。不过 因为是警告,所以必须使用系统级别的弹窗。好了 Service就写完了。
package com.example.util;
import com.example.sensordemo.SenerService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemProperties;
import android.util.Log;
public class BootBroadcastReceive extends BroadcastReceiver {
private Intent service;
@Override
public void onReceive(Context context, Intent intent) {
boolean value = SystemProperties.getBoolean("persist.sys.distance",false);
try {
if (value) {
service = new Intent(context, SenerService.class);
context.startService(service);
}else if(!value){
service = new Intent(context, SenerService.class);
context.stopService(service);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("log",e.getMessage());
}
}
}
创建一个广播接收器,用来从系统设置中 获取persist.sys.distance的值, 关于 persist.sys.distance 如何使用 网上有很多教程,我就不说了,在这里 判断value的值,如果为true,启动senerService,如果为false,则关闭,关于 CheckBoxPreference的添加以及如何存值到persist.sys.distance中,这一块代码我拿不出来 我就说一下思路吧。
//获取CheckBoxPreference
mVisionDefendSetting=(CheckBoxPreference)findPreference(KEY_VISION_DEFEND);
boolean bool=mVisionDefendSetting.isChecked();
之后在CheckBoxPreference的onPreferenceClick事件中判断preference==mVisionDefendSetting,判断bool的状态也就是判断CheckBoxPreference是否为选中状态。
SystemProperties.set("persist.sys.distance","true");
Intent intent = new Intent("info.zhegui.receiver.interprocess");
contenContext.sendBroadcast(intent);
发送一个跨进程的广播,启动Service。
最后是AndroidManifest.xml的配置文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sensordemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.sensordemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.sensordemo.SenerService" />
<receiver android:name="com.example.util.BootBroadcastReceive">
<intent-filter>
<action android:name="info.zhegui.receiver.interprocess"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
</manifest>
第一次写,可能写的有些不好,如果有什么建议的话,说出来 我可以改正!