以Toast吐丝的方式显示来电归属地
1、来电时,显示号码归属地,但不可能在其他程序中修改电话拨号程序的界面 2、Toast很特殊的组件,它是显示在手机的(操作系统的)界面上,也就是所有UI的界面上方 |
需要开启一个Service来监听来电的状态 TelephonyManager PhoneStateListener 1、注册一个监听电话的状态的服务 2、在设置中提供是否开启来电提醒的功能 3、监听电话状态的服务,是否开启,不能用SharedPreferences保存,因为,当开启为true的时候,应用程序突然挂掉或者没电了,在下次启动的时候,service不在了(因为没有点击,服务启动不了),所以不能存,要检测服务的状态。然后根据检测出来的服务的状态来勾选或者不勾选这个。 |
1、注册一个监听电话的状态的服务ShowAddressService.java package cn.zengfansheng.mobilesafe.service;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import cn.zengfansheng.mobilesafe.dao.AddressDao;
/**
* 2、显示来电归属地Service
* @author hacket
*/
public class ShowAddressService extends Service {
private MyPhoneStateListener listener;// 电话状态监听器
private TelephonyManager manager;// 电话管理器
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
manager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener listener = new MyPhoneStateListener();
manager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
@Override
public void onDestroy() {
super.onDestroy();
manager.listen(listener, PhoneStateListener.LISTEN_NONE);
listener = null;
}
/**
* 电话状态监听器
* @author hacket
*/
private class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:// 电话响铃时
String phoneAddress = AddressDao.getAddress(getApplicationContext(), incomingNumber);
Toast.makeText(getApplicationContext(), phoneAddress, Toast.LENGTH_SHORT).show();
break;
}
}
}
} |
2、在设置中提供是否开启来电提醒的功能 // 2、注册来电提醒是否提醒事件
sv_setting_showPhoneAddress = (SettingView) this.findViewById(R.id.sv_setting_show_phone_address);
sv_setting_showPhoneAddress.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (sv_setting_showPhoneAddress.isChecked()) {
sv_setting_showPhoneAddress.setChecked(false);
stopService(addressIntent);// 停止服务
}else {
sv_setting_showPhoneAddress.setChecked(true);
addressIntent = new Intent(SettingActivity.this, ShowAddressService.class);
startService(addressIntent);// 开启服务
}
}
});结果: |
问题1:监听电话状态的服务,是否开启,不能用SharedPreferences保存,因为,当开启为true的时候,应用程序突然挂掉或者没电了,在下次启动的时候,service不在了(因为没有点击,服务启动不了),所以不能存,要检测服务的状态。然后根据检测出来的服务的状态来勾选或者不勾选这个。 解决:只能检测服务,而不是保存服务 -- ActivityManager /**
* 3、检测服务的状态-是否开启和关闭
* @author hacket
*/
public class ServiceStatusUtils {
/**
* 1、检测服务是否开启
* @param context 上下文
* @param clazz 待检测的是否运行服务的字节码
* @return true为开启,false为关闭状态
*/
public static boolean isServiceOpen(Context context, Class<?> clazz) {
ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
//获取正在运行的服务,参数表示最大获取的服务,超过100个,那么也只获取最近100个服务
List<RunningServiceInfo> runningServices = activityManager.getRunningServices(100);
for (RunningServiceInfo runningServiceInfo : runningServices) {
// 注意要runningServiceInfo.service中的service一定要记得写上
String runningServiceName = runningServiceInfo.service.getClassName();// 正在运行的服务的类名
String isRunServiceName = clazz.getName();
if (!TextUtils.isEmpty(isRunServiceName)) { //正在运行的服务和要检测的服务相同类名
if (isRunServiceName.equals(runningServiceName)) {
return true;
}
}
}
return false;
}
} 结果测试: a) 刚进去界面,Service没有开启,然后按后退键,退出程序,但服务还是在运行着,再次进来的时候,服务还是运行着,因为是开启服务,不是绑定服务,Activity销毁,服务还在后台运行着。 b) 要想停止服务,那么可以停止服务或者强制退出进程和服务 或者 c) 隐藏的bug: 设置中,勾选了开启服务,但按home键,此时SettingActivity并没有退出, 此时,将服务给关闭掉。 然后,在切换到SettingActivity界面中去,发现服务的勾,还在. 但如果是强制退出,就不会出现该bug,因为SettingActivity也退出了 这是一个隐藏的bug,这是因为我们检测服务是否运行的代码,写在 SettingActivity中的onCreate()方法中,这个方法只有按后退键会销毁, 而按Home键,不会销毁,所以此时将服务关闭,然后在进来,此时 Oncreate()方法并没有执行,那么勾自然也不会更新。 解决:将检测服务是否运行,放在SettingActivity中的onStart()方法, 当用户可见,Home切换过来,也会执行该方法,才能服务是否正在运行状态。 // 3、检测一下, 是否服务运行,用户界面可见时判断服务是否开启
@Override
protected void onStart() {
super.onStart();
boolean isServiceOpen = ServiceStatusUtils.isServiceOpen(this,ShowAddressService.class);
if (isServiceOpen) {// 服务开启了
Log.i(TAG, "手机归属地查询服务开启了。。。");
sv_setting_showPhoneAddress.setChecked(true);
} else {
sv_setting_showPhoneAddress.setChecked(false);
Log.i(TAG, "手机归属地查询服务关闭了。。。");
}
} |