大讲电话归属地查询

       大家好,今天给大家发一大招,讲的是电话归属地查询,只要是有效的电话号码都可以查出是哪个地方,还可以查询长途号码的归属地,由于数据库不是很完整,那些短号码就不能查到,比如说110,10086,95588,等一些服务号码,但十一位数的有效的号码这绝对能查的出来的,这大家可放心。废话不多说,直接上图给大家理解理解。


想要查询归属地号码,必须具有强大的数据库,我这里用到的是address.db数据库,这数据网上可以下载,淘宝也可以购买,我是从老师那里拷过来的,节省了很多心思。相信大家有疑问,数据库应该放在哪里。在这里我们放在原生目录Assest,然后通过流再拷到软件的私有文件夹。为什么要这样做呢。因为assest只能有读取操作,而我们这里有涉及到写入操作,所有需要,转路径。

//放在onCreate方法里,一启动Activity,就执行方法,从而拷贝数据库
 copyDB("address.db");


//拷贝数据库方法
 public void copyDB(String name) {
  try {
   
   //读取assest目录下的db
   InputStream is = getAssets().open(name);
  //设置保存的文件的路径,和文件名
   File file = new File(getFilesDir(), name);
   
  //如果文件有就返回
   if(file.exists()){
    return;
   }
   
   //输入流读取数据库
   FileOutputStream fos = new FileOutputStream(file);
   //将输入流转换为字符节
   int len = 0;
   byte[] buff = new byte[2014];
   while ((len = is.read(buff)) != -1) {

//开始写入文件,参数二:开始值。参数三:结束值
    fos.write(buff, 0, len);
   }

   //关闭流
   is.close();
   fos.close();

  } catch (Exception e) {
   e.printStackTrace();
  }

 }


创建一个数据dao工具类,作为读取和查询在新路径下的文件内容,以及一些得到电话号码的长度的判断。

/**
 * 电话号码归属工具类
 */
public class Address {
//新路径:data/data/包名/files/address.db
   //参数一:输入的电话号码,参数二:上下文
 public static String getAddress(String num, Context context) {

//设置归属地初始值
  String location = "";
 //数据库保存的新路径
  String PATH = context.getFilesDir().getAbsolutePath() + "/address.db";
    //打开数据库,读取数据,参数三:标志位可读状态
  SQLiteDatabase db = SQLiteDatabase.openDatabase(PATH, null,
    SQLiteDatabase.OPEN_READONLY);

 //电话号码涉及到位数,总共有六种可能

  /**
   * 号码的查询分析: 1. 手机号码查询 : 11位 如何设别手机号码 通过正则表达式来识别: ^1[345678]\d{9}$
   * 2.三位的号码 110 120 119 121 等 : 特殊号码
   * 3. 四位的号码 5556 ,5554 : 虚拟号码
   * 4. 五位的号码10086 ,10000 95553 95556 12345 等 服务号码
   * 5. 本地座机号码 7位或者8位
   * 6. 长途号码020-68767565, 0735-56435434
   */

//正则表达式,^表示起点,$表示:终点,1表示第一个数字,[345678]表示第二位数字有这几个,\d表示0到9的数字,{9}表示重复九次,这样就构成十一位数
  if (num.matches("^1[345678]\\d{9}$")) {

  //执行address.db语句,查询数据库,根据address.db字段查询
   String sql = "select location from data2 where id in(select outkey from data1 where id=?)";
   //截取号码前6位数字,因为根据前六位就可以查到归属地
   Cursor cursor = db.rawQuery(sql,
     new String[] { num.substring(0, 7) });
   //遍历游标
   while (cursor.moveToNext()) {
    location = cursor.getString(0);
   }

  //关掉游标
   cursor.close();

  } else {
  //设置一个多判断
   switch (num.length()) {
   case 3:
    location = "特殊号码";
    break;
   case 4:
    location = "虚拟号码";
    break;
   case 5:
    location = "服务号码";
    break;
   case 7:
    location = "本机号码";
    break;
   case 8:
    location = "本机号码";
    break;

   default:

//还有一种情况是0开头的长途号码
  //判断一个位数是0,并电话号码长度大于10
    if (num.startsWith("0")) {

     if (num.length() > 10) {
      //依据area条件取得归属地,截取第二位数字
      String area = num.substring(1, 3);
      String sql = "select location from data2 where area=? ";
      Cursor cursor = db.rawQuery(sql, new String[] { area });
      while (cursor.moveToNext()) {
       location = cursor.getString(0);
      }

      cursor.close();

//其他情况,可能是0075这种形式的

//截取第二第三位数字,取得游标

     } else {

      String area1 = num.substring(1, 4);

      String sql = "select location from data2 where area=? ";
      Cursor cursor = db
        .rawQuery(sql, new String[] { area1 });
      while (cursor.moveToNext()) {
       location = cursor.getString(0);

      cursor.close();

     }

    }

    break;
   }

  }
  db.close();
  return location;

 }

}

数据库工具类方法就写好了,我们就要调用这方法,实现查询归属地这功能,由于layout布局简单,我就不上代码了,直接上实现查询的类。

/**
 * 实现电话归属地功能
 *
 */
public class AddressActivity extends Activity {
 //使用的是注解方法
 @ViewInject(R.id.num_et)
 private EditText mNumEt;
 @ViewInject(R.id.query_btn)
 private Button mQueryBtn;
 @ViewInject(R.id.num_tv)
 private TextView mNumTv;
 private Context context;

 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  setContentView(R.layout.activity_address);

  //注解这个Activity
  ViewUtils.inject(this);
  context = this;

//文本内容改变监听,意思是,输入一个字符串就会触发监听,而我这里,只要是输入三位数以上的数字,就会在TextView显示内容
  mNumEt.addTextChangedListener(new TextWatcher() {

 //文字改变的方法, s是Char类型需要转换为String类型
   public void onTextChanged(CharSequence s, int start, int before,
     int count) {
    //转换为String类型
    String result = s.toString();
    //调用工具类方法,得到归属地
    String location = Address.getAddress(result, context);

//判断是否为空,显示文本
    if (!TextUtils.isEmpty(location)) {
     mNumTv.setText(location);

    }

   }

 //文字改变之前
   public void beforeTextChanged(CharSequence s, int start, int count,
     int after) {

   }

//文字改变之后
   public void afterTextChanged(Editable s) {

   }
  });

//点击事件

  mQueryBtn.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View v) {

//获取输入值。
    String numValue = mNumEt.getText().toString().trim();
    if (TextUtils.isEmpty(numValue)) {
    //使用抖动动画
     Animation shake = AnimationUtils.loadAnimation(
       AddressActivity.this, R.anim.shake);
    //控件开始执行动画
     mNumEt.startAnimation(shake);

    } else {
        //显示归属地信息
     String location = Address.getAddress(numValue, context);
     if (!TextUtils.isEmpty(location)) {
      mNumTv.setText(location);

     }
    }


//实现手机震动效果,通过服务获取震动对象,Vibrator
    Vibrator vibrator=(Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
   //震动时间
    vibrator.vibrate(10000);
   //震动频率
  //2表示根据300,200无限重复震动

//-1表示不重复
    /
    vibrator.vibrate(new long[]{500,400,300,200}, 2);
   //设置震动时间最大值,Integer.MAX_VALUE
    //vibrator.vibrate(Integer.MAX_VALUE);
  //震动取消
                //vibrator.cancel();

   }
   
  
  });

 }

}

需要设置震动权限‘

<!-- 手机震动权限 -->
   <uses-permission android:name="android.permission.VIBRATE" />

anim下的动画配置xml文件

cycle_7.xml

<?xml version="1.0" encoding="utf-8"?>

<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />

shake.xml

<?xml version="1.0" encoding="utf-8"?>

<translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="10" android:duration="1000" android:interpolator="@anim/cycle_7" />


查询电话归属地的大致功能就这样了,中间我还添加了抖动动画,系统震动等功能。写了那么久的代码,总结来说,需要的是理解这方法怎么用,知道有这东西,还要重复记忆,知识太多,你不记多记稳,是很难再代码中游刃有余的。晚安。



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值