1 点击按钮开启归属地显示服务
@OnClick(R.id.siv_address)
public void setAddress(View view) {
Intent service = new Intent(this, AddressService.class);
if (ServiceStatusUtils.isServiceRunning(this, AddressService.class)) {// 是
stopService(service);
} else {// 否
startService(service);
}
sivAddress.toggle();
}
2 号码显示服务
package org.heima.mobilesafe01.service;
import org.heima.mobilesafe01.db.AddressDao;
import org.heima.mobilesafe01.utils.L;
import org.heima.mobilesafe01.view.AddressToast;
import android.app.AlertDialog;
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.text.TextUtils;
/**
* @author U
* 号码归属地的服务
*/
public class AddressService extends Service{
private TelephonyManager mTm;
private MPhoneStateListener mListener;
private AddressToast mToast;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
L.d("AddressService:onCreate");
mTm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mListener = new MPhoneStateListener();
mTm.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
mToast = new AddressToast(getApplicationContext());
}
class MPhoneStateListener extends PhoneStateListener{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
// 挂断 (隐藏)
mToast.hide();
break;
case TelephonyManager.CALL_STATE_RINGING:
// 响铃(显示)
if(TextUtils.isEmpty(incomingNumber)){
return;
}
String cardType=AddressDao.getCardType(getApplicationContext(), incomingNumber);
mToast.show(cardType);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
default:
break;
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
L.d("AddressService:onDestroy");
// 取消监听
if(mListener!=null){
mTm.listen(mListener, PhoneStateListener.LISTEN_NONE);
}
}
}
权限!!!!!!!!!
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
3 自定义对属地实现的Toast
package org.heima.mobilesafe01.view;
import org.heima.mobilesafe01.R;
import org.heima.mobilesafe01.constants.Constants;
import org.heima.mobilesafe01.utils.L;
import org.heima.mobilesafe01.utils.PreferencesUtils;
import android.content.Context;
import android.graphics.PixelFormat;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.TextView;
public class AddressToast implements OnTouchListener {
private WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
private Context mContext;
private View mView;
private WindowManager mWm;
private float mDownX;
private float mDownY;
public AddressToast(Context context) {
this.mContext = context;
mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final WindowManager.LayoutParams params = mParams;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.format = PixelFormat.TRANSLUCENT;
// params.windowAnimations =
// com.android.internal.R.style.Animation_Toast;
params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
// params.setTitle("Toast");
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mView = View.inflate(mContext, R.layout.view_toast, null);
}
public void show(String msg) {
if (mView == null) {
mView = View.inflate(mContext, R.layout.view_toast, null);
}
mView.setOnTouchListener(this);
// 给这个View设置背景
mView.setBackgroundResource(PreferencesUtils.getInt(mContext,
Constants.ADDRESS_STYLE, R.drawable.toast_address_normal));
TextView tv = (TextView) mView.findViewById(R.id.tv_custom_toast);
tv.setText(msg);
// 添加View
if (mView.getParent() != null) {
mWm.removeView(mView);
}
mWm.addView(mView, mParams);
}
public void hide() {
if (mView != null) {
// note: checking parent() just to make sure the view has
// been added... i have seen cases where we get here when
// the view isn't yet added, so let's try not to crash.
if (mView.getParent() != null) {
mWm.removeView(mView);
}
mView = null;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
L.d("AddressToast:ACTION_DOWN");
mDownX = event.getRawX();
mDownY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
L.d("AddressToast:ACTION_MOVE");
// mParams.x=mParams.x+10;
float moveX = event.getRawX();
float moveY = event.getRawY();
int dx = (int) (moveX - mDownX + 0.5f);// 四舍五入 4.1 int 4 4.8 4
// 4.1+0.5=4.6 4 4.8+0.5=5.3
// 5
int dy = (int) (moveY - mDownY + 0.5f);
mParams.x += dx;
mParams.y += dy;
mWm.updateViewLayout(mView, mParams);
// 更新一下按下的点
mDownX = moveX;
mDownY = moveY;
break;
case MotionEvent.ACTION_UP:
L.d("AddressToast:ACTION_UP");
break;
default:
break;
}
return true;// 自己消费
}
}
4 AddressDao 查询号码
package org.heima.mobilesafe01.db;
import java.util.regex.Pattern;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* @author U 号码归属地查询
*/
public class AddressDao {
/**
* @param context
* @param phone
* @return
*/
public static String getCardType(Context context, String phone) {// I ---- O
// ctrl+alt+j
String path = context.getFilesDir().getAbsolutePath() + "/address.db";
SQLiteDatabase database = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
String cardType = "";
// 正则表达式
if (phone.matches("^\\d{11}$")) {
phone = phone.substring(0, 7);
Cursor cursor = database.rawQuery(
"select cardtype from info where mobileprefix=?",
new String[] { phone });
if (cursor != null) {
if (cursor.moveToNext()) {
cardType = cursor.getString(0);
return cardType;
}
cursor.close();
}
} else {
int length = phone.length();
switch (length) {
case 3:
cardType = "紧急号码";
break;
case 4:
cardType = "模拟器";
break;
case 5:
cardType = "服务号码";
break;
default:
cardType = "未知号码";
break;
}
}
database.close();
return cardType;
}
}