仿360手机卫士之查询号码归属地

仿360手机卫士之查询号码归属地,第1张

概述360手机卫士里基本的功能–查询来电归属地 技术要点大概如下 - 对最新号码归属地数据的压缩与解压 - sqlite3数据库的基本 *** 作 - 监听手机来电 - 自定义Toast 准备 *** 作 最新号码归属地数据库,这里有一份但不是最新的https://pan.baidu.com/s/1bpKSghT,这是压缩过的2兆多,解压后40多兆,本来更大,这里将一个表拆成多表,减少数据冗余,其实里面的表还可以拆分 360手机卫士里基本的功能–查询来电归属地

技术要点大概如下
- 对最新号码归属地数据的压缩与解压
- sqlite3数据库的基本 *** 作
- 监听手机来电
- 自定义Toast

准备 *** 作
最新号码归属地数据库,这里有一份但不是最新的https://pan.baidu.com/s/1bpKSghT,这是压缩过的2兆多,解压后40多兆,本来更大,这里将一个表拆成多表,减少数据冗余,其实里面的表还可以拆分,更大程度的减少数据冗余,只是查询上会造成单表查询变成多表查询,不过这种拆分应该是值得的。

1.解压
前面准备的数据库其实已经压缩过了,是用下面的工具类ZipUtil实现的,用360压缩也是ok的,亲测一样。压缩过的(链接中下载到的)放到assets目录下,启动应用程序的时候解压缩,或者用到的时候再解压,暂称为懒解压。工具类ZipUtil如下:

/** * 压缩 * @param filePath * @param savePath * @throws Exception */    public static voID compress(String filePath,String savePath) throws Exception{        ZipOutputStream out = new ZipOutputStream(new fileOutputStream(                  savePath));        bufferedoutputstream bos = new bufferedoutputstream(out);        file file = new file(filePath);        zip(out,file,file.getname(),bos);        if(bos != null){            bos.close();        }        if(out != null){            out.close();        }    }    private static int k = 0;    private static voID zip(ZipOutputStream out,file f,String base,bufferedoutputstream bo) throws Exception { // 方法重载         if (f.isDirectory()) {              file[] fl = f.Listfiles();              if (fl.length == 0) {                  out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base                 System.out.println(base + "/");              }              for (int i = 0; i < fl.length; i++) {                  zip(out,fl[i],base + "/" + fl[i].getname(),bo); // 递归遍历子文件夹             }              System.out.println("第" + k + "次递归");              k++;          } else {              out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base             System.out.println(base);              fileinputStream in = new fileinputStream(f);              BufferedinputStream bi = new BufferedinputStream(in);              int b;              while ((b = bi.read()) != -1) {                  bo.write(b); // 将字节流写入当前zip目录             }              bi.close();              in.close(); // 输入流关闭         }      }    /** * 解压缩 * @param filePath 源文件路径 * @param rootPath 要解压到哪个文件夹下 * @throws Exception */    public static voID uncompress(String filePath,String rootPath) throws Exception{        ZipinputStream zis=new ZipinputStream(new fileinputStream(                  filePath));//输入源zip路径         BufferedinputStream bis=new BufferedinputStream(zis);          file fOut=null;          ZipEntry entry;        while((entry = zis.getNextEntry())!=null){            if(entry.isDirectory()){                continue;            }            fOut=new file(rootPath,entry.getname());              if(!fOut.exists()){                  (new file(fOut.getParent())).mkdirs();              }              fileOutputStream out=new fileOutputStream(fOut);              bufferedoutputstream Bout=new bufferedoutputstream(out);              int b;              while((b=bis.read())!=-1){                  Bout.write(b);              }            Bout.flush();            Bout.close();              out.close();          }        bis.close();          zis.close();    }

ok,解压完成,40多兆的东西进了手机,流汗!

2.监听来电,自定义toast
用后台开启服务的方式监听手机来电

public class MonitorPhoneservice extends Service {    private static final String TAG = "MonitorPhoneservice";    private WindowManager windowManager;    private TelephonyManager manager;    private MyListener Listener;    private VIEw vIEw;    @Nullable    @OverrIDe    public IBinder onBind(Intent intent) {        return null;    }    @OverrIDe    public voID onCreate() {        super.onCreate();        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);        manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);        Listener = new MyListener();        manager.Listen(Listener,PhonestateListener.ListEN_CALL_STATE);    }    private class MyListener extends PhonestateListener {        @OverrIDe        public voID onCallStateChanged(int state,String incomingNumber) {            super.onCallStateChanged(state,incomingNumber);            switch (state) {                case TelephonyManager.CALL_STATE_IDLE:  //处于静止状态,没有呼叫                    if (vIEw != null) { //这里及时移除vIEw(自定义toast)                        windowManager.removeVIEw(vIEw);                        vIEw = null;                    }                    break;                case TelephonyManager.CALL_STATE_OFFHOOK:  //接通状态                    if (vIEw != null) { //同上                        windowManager.removeVIEw(vIEw);                        vIEw = null;                    }                    break;                case TelephonyManager.CALL_STATE_RINGING:  //铃响状态                    showAddress(incomingNumber);                    break;            }        }    }    //显示归属地,自定义Toast    private voID showAddress(String incomingNumber) {        WindowManager.LayoutParams params = new WindowManager.LayoutParams();        params.height = WindowManager.LayoutParams.WRAP_CONTENT;        params.wIDth = WindowManager.LayoutParams.WRAP_CONTENT;        params.format = PixelFormat.TRANSLUCENT;        params.type = WindowManager.LayoutParams.TYPE_TOAST;        params.setTitle("Toast");        params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE                | WindowManager.LayoutParams.FLAG_NOT_touchABLE;        vIEw = LayoutInflater.from(getApplicationContext()).inflate(R.layout.toast_query_address,null);        TextVIEw tv = (TextVIEw) vIEw.findVIEwByID(R.ID.tv_toast_query_address);        //这里 *** 作数据库查询号码归属地        tv.setText(new queryAddressEngine(getApplicationContext()).queryAddress(incomingNumber));        tv.setTextSize(20);        windowManager.addVIEw(vIEw,params);    }    @OverrIDe    public voID onDestroy() {        super.onDestroy();        manager.Listen(Listener,PhonestateListener.ListEN_NONE);        Listener = null;    }}

只需启动服务监听就行了,还要添加权限

<uses-permission androID:name="androID.permission.CALL_PHONE" />    <uses-permission androID:name="androID.permission.READ_PHONE_STATE" />    <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE" />    <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE" />    <uses-permission androID:name="androID.permission.SYstem_ALERT_WINDOW"/>    <uses-permission androID:name="androID.permission.MODIFY_PHONE_STATE" />

3.查询号码归属地
这里只用对数据库进行查-DQL

public class queryAddressEngine {    private Context mContext;    public queryAddressEngine(Context mContext) {        this.mContext = mContext;    }    public String queryAddress(String number) {        //匹配手机号可以写成工具类        String pattern = "^1[3458]\d{9}$";        String result = number;        int type = -1;        String city = "";        String province = "";        if(number.matches(pattern)){ //手机号码            sqliteDatabase database = DbDao.getDatabase(mContext);            if(database.isopen()){                Cursor cursor = database.rawquery(                        "select province,city,type from phone where mobilepre = ? limit 1",new String[]{number.substring(0,7)});                if(cursor.movetoNext()){                    city = cursor.getString(cursor.getColumnIndex("city"));                    type = cursor.getInt(cursor.getColumnIndex("type"));                    province = cursor.getString(cursor.getColumnIndex("province"));                }                result = province + " " + city + " " + getoperatorByType(type);                cursor.close();                database.close();            }        } else {  //固定电话            int len = number.length();            sqliteDatabase db;            switch (len){                case 4: //模拟器                    result = "模拟器";                    break;                case 7: //本地号码                case 8: //本地号码                    result = "本地号码";                    break;                case 10: //3位区号 + 7位号码                    db = DbDao.getDatabase(mContext);                    if(db.isopen()){                        Cursor cursor = db.rawquery(                                "select province,type from phone where areacode = ? limit 1",3)});                        if(cursor.movetoNext()){                            city = cursor.getString(cursor.getColumnIndex("city"));                            type = cursor.getInt(cursor.getColumnIndex("type"));                            province = cursor.getString(cursor.getColumnIndex("province"));                        }                        result = province + " " + city + " " + getoperatorByType(type);                        cursor.close();                        db.close();                    }                    break;                case 11:  //3位区号 + 8位号码 4位区号 + 7位号码                    sqliteDatabase db2 = DbDao.getDatabase(mContext);                    if(db2.isopen()){                        Cursor cursor = db2.rawquery(                                "select province,3)});                        if(cursor.movetoNext()){                            city = cursor.getString(cursor.getColumnIndex("city"));                            type = cursor.getInt(cursor.getColumnIndex("type"));                            province = cursor.getString(cursor.getColumnIndex("province"));                        } else {                            Cursor cursor2 = db2.rawquery(                                    "select province,4)});                            if(cursor.movetoNext()){                                city = cursor.getString(cursor.getColumnIndex("city"));                                type = cursor.getInt(cursor.getColumnIndex("type"));                                province = cursor.getString(cursor.getColumnIndex("province"));                            }                            cursor2.close();                        }                        result = province + " " + city + " " + getoperatorByType(type);                        cursor.close();                        db2.close();                    }                    break;                case 12: //4位区号 +8位号码                    db = DbDao.getDatabase(mContext);                    if (db.isopen()) {                        Cursor cursor = db.rawquery(                                "select province,new String[] { number.substring(0,4) });                        if(cursor.movetoNext()){                            city = cursor.getString(cursor.getColumnIndex("city"));                            type = cursor.getInt(cursor.getColumnIndex("type"));                            province = cursor.getString(cursor.getColumnIndex("province"));                        }                        result = province + " " + city + " " + getoperatorByType(type);                        cursor.close();                        db.close();                    }                    break;            }        }        return result;    }    public String getoperatorByType(int type){        String operator = "未知";        switch (type){            case 1:                operator = "移动";                break;            case 2:                operator = "联通";                break;            case 3:                operator = "电信";                break;            case 4:                operator = "虚拟运营商";                break;        }        return operator;    }}public class DbDao {    public static sqliteDatabase getDatabase(Context mContext){        return new DbHelper(mContext).getWritableDatabase();    }}public class DbHelper extends sqliteOpenHelper {    public DbHelper(Context context){        this(context,Db.name,null,Db.VERSION);    }    public DbHelper(Context context,String name,sqliteDatabase.CursorFactory factory,int version) {        super(context,name,factory,version);    }    @OverrIDe    public voID onCreate(sqliteDatabase db) {    }    @OverrIDe    public voID onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) {    }}

好了,写完收工领盒饭

总结

以上是内存溢出为你收集整理的仿360手机卫士之查询号码归属地全部内容,希望文章能够帮你解决仿360手机卫士之查询号码归属地所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1163507.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存