手机安全卫士04

1.号码归属地查询的UI

2.号码归属地查询的原理

1.查询数据库

3.号码归属地的查询实现

1、把数据库拷贝到assets目录并创建包com.itheima.mobilesafe.db.dao包创建该类

      file:///android_aset/address.db 这种无法访问

2.  在SplashActivit页面做从Assets目录拷贝到data/data/<包名>/files/address.db数据库的代码

	/**
	 * //path 把address.db这个数据库拷贝到data/data/《包名》/files/address.db
	 */
	private void copyDB() {
		//只要你拷贝了一次,我就不要你再拷贝了
		try {
			File file = new File(getFilesDir(), "address.db");
			if(file.exists()&&file.length()>0){
				//正常了,就不需要拷贝了
				Log.i(TAG, "正常了,就不需要拷贝了");
			}else{
				InputStream is = getAssets().open("address.db");
				
				FileOutputStream fos = new FileOutputStream(file);
				byte[] buffer = new byte[1024];
				int len = 0;
				while((len = is.read(buffer))!= -1){
					fos.write(buffer, 0, len);
				}
				is.close();
				fos.close();
			}
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
3.操作数据库放在独立的包下

  使用正则表达式输入号码

public class NumberAddressQueryUtils {

	private static String path = "data/data/com.itheima.mobilesafe/files/address.db";

	/**
	 * 传一个号码进来,返回一归属地回去
	 * 
	 * @param number
	 * @return
	 */
	public static String queryNumber(String number) {
		String address = number;
		// path 把address.db这个数据库拷贝到data/data/《包名》/files/address.db
		SQLiteDatabase database = SQLiteDatabase.openDatabase(path, null,
				SQLiteDatabase.OPEN_READONLY);
		// 手机号码 13 14 15 16 18
		// 手机号码的正则表达式判断\d需要加\转义
		if (number.matches("^1[34568]\\d{9}$")) {
			// 手机号码

			Cursor cursor = database
					.rawQuery(
							"select location from data2 where id = (select outkey from data1 where id = ?)",
							new String[] { number.substring(0, 7) });

			while (cursor.moveToNext()) {

				String location = cursor.getString(0);
				address = location;
			}
			cursor.close();

		} else {
			// 其他的电话号码
			switch (number.length()) {
			case 3:
				// 110
				address = "匪警号码";
				break;
			case 4:
				// 5554
				address = "模拟器";
				break;
			case 5:
				// 10086
				address = "客服电话";
				break;
			case 7:
				//
				address = "本地号码";
				break;

			case 8:
				address = "本地号码";
				break;

			default:
				// /处理长途电话 10
				if (number.length() > 10 && number.startsWith("0")) {
					// 010-59790386
					Cursor cursor = database.rawQuery(
							"select location from data2 where area = ?",
							new String[] { number.substring(1, 3) });

					while (cursor.moveToNext()) {
						String location = cursor.getString(0);
						address = location.substring(0, location.length() - 2);
					}
					cursor.close();

					// 0855-59790386
					cursor = database.rawQuery(
							"select location from data2 where area = ?",
							new String[] { number.substring(1, 4) });
					while (cursor.moveToNext()) {
						String location = cursor.getString(0);
						address = location.substring(0, location.length() - 2);

					}
				}

				break;
			}

		}

		return address;
	}

}
 

4.号码归属地的查询效果优化

1.文本改变的监听  addTextChangedListener( new TextWatcher(){})
ed_phone.addTextChangedListener(new TextWatcher() {
			
			/**
			 * 当文本发生变化的时候回调
			 */
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if(s!= null&&s.length()>=3){
					//查询数据库,并且显示结果
					String address = NumberAddressQueryUtils.queryNumber(s.toString());
					result.setText(address);
				}
				
			}
			
			/**
			 * 当文本发生变化之前回调
			 */
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
				
			}
			/**
			 * 当文本发生变化之后回调
			 */
			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				
			}
		});

5.输入框抖动和振动效果

 ----------抖动----------
1.在res/anim下创建两个xml文件
   shake.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0"
    android:interpolator="@anim/cycle_7"
    android:toXDelta="10" />

  cycle_7.xml
<?xml version="1.0" encoding="utf-8"?>
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:cycles="7" />
2.使用
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
			 et.startAnimation(shake);

----------振动---------
1.振动权限
<uses-permission android:name="android.permission.VIBRATE"/>
2.代码
/**
 * 系统提供的振动服务
 */
private Vibrator vibrator; 

vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);   //初始化
 //当电话号码为空的时候,就去振动手机提醒用户
//vibrator.vibrate(2000);  //振动毫秒数

long[] pattern = {200,200,300,300,1000,2000};//振动规律,动停动停
//-1不重复 0循环振动 1;
 vibrator.vibrate(pattern, -1);

6.来电号码归属地的显示

1.创建后台监听来电服务
2.权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
3.在功能清单中注册服务<service>
4.监听电话状态----(在服务中监听)
private TelephonyManager tm;
	private MyListenerPhone listenerPhone;  //监听器,监听来电
	private OutCallReceiver receiver;       //接收去电广播

	// 服务里面的内部类
	//广播接收者的生命周期和服务一样
	class OutCallReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			// 这就是我们拿到的播出去的电话号码
			String phone = getResultData();
			// 查询数据库
			String address = NumberAddressQueryUtils.queryNumber(phone);
			
 			Toast.makeText(context, address, 1).show();
		}

	}

      //监听器监听来电
      private class MyListenerPhone extends PhoneStateListener {

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			// state:状态,incomingNumber:来电号码
			super.onCallStateChanged(state, incomingNumber);
			switch (state) {
			case TelephonyManager.CALL_STATE_RINGING:       // 来电铃声响起
				// 查询数据库的操作
				String address = NumberAddressQueryUtils
						.queryNumber(incomingNumber);
				
  				Toast.makeText(getApplicationContext(), address, 1).show();
				
				break;
				
			case TelephonyManager.CALL_STATE_IDLE://电话的空闲状态:挂电话、来电拒绝
				//把这个View移除
				if(view != null ){
					wm.removeView(view);
				}
			
				
				break;

			default:
				break;
			}
		}

	}


                //使用
          public void onCreat(){

                tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

                // 监听来电
	        listenerPhone = new MyListenerPhone();
		tm.listen(listenerPhone, PhoneStateListener.LISTEN_CALL_STATE);//监听电话状态


                //用代码去注册广播接收者
		receiver = new OutCallReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
		registerReceiver(receiver, filter);
              }

	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		// 取消监听来电
		tm.listen(listenerPhone, PhoneStateListener.LISTEN_NONE);
		listenerPhone = null;
		
		//用代码取消注册广播接收者
		unregisterReceiver(receiver);
		receiver = null;
        }



 

 10.自定义吐司

1.吐司的布局文件--(address_show.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_vertical"
     >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_menu_call" />

    <TextView
        android:textColor="#000000"
        android:id="@+id/tv_address"
        android:textSize="22sp"
        android:text="号码归属地"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

2.自定义吐司
 
	/**
	 * 窗体管理者
	 */
	private WindowManager wm;
        private View view;
	//实例化窗体
	wm = (WindowManager) getSystemService(WINDOW_SERVICE);

	
        
        /**
	 * 自定义土司
	 * @param address
	 */
	public void myToast(String address) {
	     view =   View.inflate(this, R.layout.address_show, null);
	    TextView textview  = (TextView) view.findViewById(R.id.tv_address);
	    
	    //"半透明","活力橙","卫士蓝","金属灰","苹果绿"
	    int [] ids = {R.drawable.call_locate_white,R.drawable.call_locate_orange,R.drawable.call_locate_blue
	    ,R.drawable.call_locate_gray,R.drawable.call_locate_green};
	    SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
	    view.setBackgroundResource(ids[sp.getInt("which", 0)]);   //设置背景
	    textview.setText(address);
         //窗体的参数就设置好了
         WindowManager.LayoutParams params = new WindowManager.LayoutParams();
		 
         params.height = WindowManager.LayoutParams.WRAP_CONTENT;//高度
         params.width = WindowManager.LayoutParams.WRAP_CONTENT; //宽度
         
         params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE //不可以有焦点
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE      //不可以触摸
                 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;    //当吐司弹出时,不可以锁屏
         params.format = PixelFormat.TRANSLUCENT;                     //半透明
         params.type = WindowManager.LayoutParams.TYPE_TOAST;
		wm.addView(view, params);
		
	}





      //使用
      myToast(address);
    //停用吐司
   if(view!=null){
    wm.remove(View)
    }




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值