在大多数的骚扰拦截类的软件中都会有定时拦截这个实用的的功能,其实,也不难实现。
看图:
在未选中启用时间段时,下面的两个开始时间和结束时间呈灰色状态,并且单击无响应,启用时间段后,下面则变成了可以单击的状态,通过单击可以弹出选择日期与时间的对话框,用于选择开始时间和结束时间。
主要思路:
1. 启用时间段,将下面的控件变成可获得焦点状态
2. 添加单击事件,弹出日期时间选择对话框
3. 选择时间,并显示在相应的位置
4. 通过SharedPrefresence将相关设置保存,以便下次启动程序时使用
设置界面的布局文件已在第一节给出了,下面实现就实现具体添加时间的功能。
首先是控件的声明,这里用到了ToggleButton来表示两种状态,当然了也可用Switch,但是2.3不支持。
private ToggleButton tb_switch,tb_whiteList,tb_time;
private RelativeLayout start_layout;
private RelativeLayout end_layout;
private TextView tv_start_time,tv_start_tip;
private TextView tv_end_time,tv_end_tip;
private SharedPreferences sp;
SharedPreferences.Editor editor;
接着,就是从布局文件中找到相应的控件,并绑定监听器
sp = this.getSharedPreferences("setting",Activity.MODE_PRIVATE);
editor = sp.edit();
start_layout = (RelativeLayout)findViewById(R.id.start_layout);
start_layout.setOnClickListener(new ClickEvent());
start_layout.setClickable(false);
end_layout = (RelativeLayout)findViewById(R.id.end_layout);
end_layout.setOnClickListener(new ClickEvent());
end_layout.setClickable(false);
tv_start_time =(TextView)findViewById(R.id.tv_start_time);
tv_end_time = (TextView)findViewById(R.id.tv_end_time);
tv_start_tip = (TextView)findViewById(R.id.tv_start_tip);
tv_end_tip = (TextView)findViewById(R.id.tv_end_tip);
tb_switch = (ToggleButton)findViewById(R.id.tb_switch);
tb_whiteList = (ToggleButton)findViewById(R.id.tb_whitelist);
tb_time = (ToggleButton)findViewById(R.id.tb_time);
tb_switch.setOnCheckedChangeListener(new ToggleButtonCheckedEvent());<br abp="830" /> tb_whiteList.setOnCheckedChangeListener(new ToggleButtonCheckedEvent());<br abp="831" /> tb_time.setOnCheckedChangeListener(new ToggleButtonCheckedEvent());
其中,sp = this.getSharedPreferences("setting",Activity.MODE_PRIVATE);这个可以将简单的设置信息保存到文件,注意这里是对两个relativeLayout添加单击事件,这样,就可以通过点击设置界面中的两个时间段选择行,就可以弹出相应的日期时间选择对话框。
附: SharedPreferences的用法:
1. 得到SharedPreferences对象:SharedPreferences sp = this.getSharedPreferences("setting",Activity.MODE_PRIVATE);后面的参数,表示模式,表示共享的范围,可以查看具体文档。
2. 存入数据:SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("isStartListen",true);
editor.commit();//提交数据,这样数据就保存到setting.xml文件中了
3. 取出数据:boolean data = sp.getBoolean("isStartListen", false),其中第二个参数false是默认值,也就是如果文件中不存在该key,就返回false。
在监听器中实现想要的功能了,如下:
//ToggleButton开关监听器
class ToggleButtonCheckedEvent implements OnCheckedChangeListener{
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(buttonView.getId() == R.id.tb_switch){
tb_switch.setChecked(isChecked);
if(isChecked){
editor.putBoolean("isStartListen",true);
editor.commit();
tb_switch.setBackgroundResource(R.drawable.start_service_on);
Toast.makeText(SettingActivity.this, "开启拦截服务", 1000 ).show();
}
else{
editor.putBoolean("isStartListen",false);
editor.commit();
tb_switch.setBackgroundResource(R.drawable.start_service_off);
Toast.makeText(SettingActivity.this, "关闭拦截服务", 1000 ).show();
}
}
else if(buttonView.getId() == R.id.tb_whitelist){
tb_whiteList.setChecked(isChecked);
if(isChecked){
editor.putBoolean("isWhiteList",true);
tb_whiteList.setBackgroundResource(R.drawable.start_service_on);
Toast.makeText(SettingActivity.this, "白名单模式", 1000 ).show();
}
else{
editor.putBoolean("isWhiteList", false);
tb_whiteList.setBackgroundResource(R.drawable.start_service_off);
Toast.makeText(SettingActivity.this, "黑名单模式", 1000 ).show();
}
editor.commit();
}
else if(buttonView.getId() == R.id.tb_time){
tb_time.setChecked(isChecked);
if(isChecked){
tb_time.setBackgroundResource(R.drawable.start_service_on);
start_layout.setClickable(true);
end_layout.setClickable(true);
tv_start_tip.setTextColor(Color.BLACK);
tv_start_time.setTextColor(Color.BLACK);
tv_end_tip.setTextColor(Color.BLACK);
tv_end_time.setTextColor(Color.BLACK);
editor.putBoolean("isTime", true);
Toast.makeText(SettingActivity.this, "启用定时拦截,请设置开始时间和结束时间", 1000 ).show();
String[] time = getCurrentTime();
tv_start_time.setText(time[0]);
tv_end_time.setText(time[1]);
editor.putString("startTime", time[0]);
editor.putString("endTime", time[1]);
}
else{
tb_time.setBackgroundResource(R.drawable.start_service_off);
tv_start_tip.setTextColor(Color.GRAY);
tv_start_time.setTextColor(Color.GRAY);
tv_end_tip.setTextColor(Color.GRAY);
tv_end_time.setTextColor(Color.GRAY);
start_layout.setClickable(false);
end_layout.setClickable(false);
editor.putBoolean("isTime", false);
Toast.makeText(SettingActivity.this, "关闭定时拦截", 1000).show();
String[] time = getCurrentTime();
tv_start_time.setText(time[0]);
tv_end_time.setText(time[1]);
}
editor.commit();
}
}
}
可以看出,监听器中还有其他两个ToggleButton需要实现的功能,当然了,因为目前还没有通过service实现电话拦截的功能,所以,在之后实现拦截功能时,会在相应的地方添加代码,这里只实现将设置的信息保存。
下面就实现选择日期与时间功能,并将其保存。
依然是监听器:
class ClickEvent implements OnClickListener{
@Override
public void onClick(View v) {
Context mContext = SettingActivity.this;
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
View view = View.inflate(mContext, R.layout.data_time_dialog, null);
final DatePicker datePicker = (DatePicker)view.findViewById(R.id.data_picker);
final TimePicker timePicker = (TimePicker)view.findViewById(R.id.time_picker);
builder.setView(view);
//获取当前日期
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
//将日期选择器设置为当前日期
datePicker.init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH),null);
//将时间选择器设置为当前时间
timePicker.setIs24HourView(true);
timePicker.setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));
timePicker.setCurrentMinute(cal.get(Calendar.MINUTE));
if(v.getId() == start_layout.getId()){
builder.setTitle("选择起始监听时间");
builder.setPositiveButton("确定 ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
StringBuffer sb = new StringBuffer();
//取出选择的时间,并格式化
sb.append(String.format("%02d-%02d", datePicker.getMonth()+1,datePicker.getDayOfMonth()));
//将日期与时间用空格分开
sb.append(" ");
sb.append(String.format("%02d:%02d", timePicker.getCurrentHour(),timePicker.getCurrentMinute()));
//将选择好的日期日间显示
tv_start_time.setText(sb);
//将时间保存到sharedPreference
editor.putString("startTime", sb.toString());
editor.commit();
showTimeErrorTip();
dialog.cancel();
}
});
}
else if(v.getId() == end_layout.getId()){
builder.setTitle("选择结束监听时间");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
StringBuffer sb = new StringBuffer();
//取出选择的时间,并格式化
sb.append(String.format("%02d-%02d", datePicker.getMonth()+1,datePicker.getDayOfMonth()));
//将日期与时间用空格分开
sb.append(" ");
sb.append(String.format("%02d:%02d", timePicker.getCurrentHour(),timePicker.getCurrentMinute()));
//将选择好的日期日间显示
tv_end_time.setText(sb);
editor.putString("endTime", sb.toString());
editor.commit();
showTimeErrorTip();
dialog.cancel();
}
});
}
//创建对话框,并显示
Dialog dialog = builder.create();
dialog.show();
}
}
//刷新存储时间,判断开始时间与结束时间大小
public void showTimeErrorTip(){
//如果时间合法,则不提示,否则提示
if(sp.getString("startTime", "").compareTo(sp.getString("endTime", "")) > 0){
Toast.makeText(SettingActivity.this, "结束时间必须大于开始时间", 1000).show();
}
}
弹出的日期时间选择界面的布局文件如下:
data_time_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="选择日期"
android:textSize="15sp"
/>
<DatePicker
android:id="@+id/data_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:text="选择时间 "
android:textSize="15sp"
/>
<TimePicker
android:id="@+id/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
至此,已实现了选择日期时间,并将相关的设置信息写入文件的功能。