Android从SIM卡中获取联系人信息

android调用ITelephony类,AIDL实现电话,联系人黑名单拦截挂断服务 版权声明:本文为博主原创文章,未经博主允许不得转载。 首先新建AIDL文件,ITelephony.aidl。注意包名为com.android.internal.telephony,不可更改,此时需要重新rebuild project才能正常使用。 总体效果图:如下 废话不多说,咱还是直接上代码吧: 首先布局文件:activity_phonestate<?xml version="1.0 阅读详情
Uri uri = Uri.parse("content://icc/adn"); 
String[] projection = {"_id", "name", "number"}; 
Cursor cursor = managedQuery(uri, projection, null, null, "name"); 
if(cursor!=null){ 
      while(cursor.moveToNext()){ 
String name = cursor.getString(cursor.getColumnIndex("name")); 
String phone = cursor.getString(cursor.getColumnIndex("number")); 
        } 
} 
在文件AndroidManifest.xml中添加权限
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Android系统内部通过Contentprovider对外共享Sim卡存放的联系人等信息,你可以通过操作Contentprovider来实现Sim卡信息的添删改查操作。 内部实现源代码见下:
package com.android.internal.telephony;

import android.content.ContentProvider;
import android.content.UriMatcher;
import android.content.ContentValues;
import com.android.internal.database.ArrayListCursor;
import android.database.Cursor;
import android.net.Uri;
import android.os.SystemProperties;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.IIccPhoneBook;

public class IccProvider extends ContentProvider {
    private static final String TAG = "IccProvider";
    private static final boolean DBG = false;

    private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
        "name",
        "number"
    };

    private static final int ADN = 1;
    private static final int FDN = 2;
    private static final int SDN = 3;

    private static final String STR_TAG = "tag";
    private static final String STR_NUMBER = "number";
    private static final String STR_PIN2 = "pin2";

    private static final UriMatcher URL_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        URL_MATCHER.addURI("icc", "adn", ADN);
        URL_MATCHER.addURI("icc", "fdn", FDN);
        URL_MATCHER.addURI("icc", "sdn", SDN);
    }

    private boolean mSimulator;

    @Override
    public boolean onCreate() {
        String device = SystemProperties.get("ro.product.device");
        if (!TextUtils.isEmpty(device)) {
            mSimulator = false;
        } else {
            // simulator
            mSimulator = true;
        }
        return true;
    }

    @Override
    public Cursor query(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sort) {
        ArrayList<ArrayList> results;

        if (!mSimulator) {
            switch (URL_MATCHER.match(url)) {
                case ADN:
                    results = loadFromEf(IccConstants.EF_ADN);
                    break;

                case FDN:
                    results = loadFromEf(IccConstants.EF_FDN);
                    break;

                case SDN:
                    results = loadFromEf(IccConstants.EF_SDN);
                    break;

                default:
                    throw new IllegalArgumentException("Unknown URL " + url);
            }
        } else {
            // Fake up some data for the simulator
            results = new ArrayList<ArrayList>(4);
            ArrayList<String> contact;

            contact = new ArrayList<String>();
            contact.add("Ron Stevens/H");
            contact.add("512-555-5038");
            results.add(contact);

            contact = new ArrayList<String>();
            contact.add("Ron Stevens/M");
            contact.add("512-555-8305");
            results.add(contact);

            contact = new ArrayList<String>();
            contact.add("Melissa Owens");
            contact.add("512-555-8305");
            results.add(contact);

            contact = new ArrayList<String>();
            contact.add("Directory Assistence");
            contact.add("411");
            results.add(contact);
        }

        return new ArrayListCursor(ADDRESS_BOOK_COLUMN_NAMES, results);
    }

    @Override
    public String getType(Uri url) {
        switch (URL_MATCHER.match(url)) {
            case ADN:
            case FDN:
            case SDN:
                return "vnd.android.cursor.dir/sim-contact";

            default:
                throw new IllegalArgumentException("Unknown URL " + url);
        }
    }

    @Override
    public Uri insert(Uri url, ContentValues initialValues) {
        Uri resultUri;
        int efType;
        String pin2 = null;

        if (DBG) log("insert");

        int match = URL_MATCHER.match(url);
        switch (match) {
            case ADN:
                efType = IccConstants.EF_ADN;
                break;

            case FDN:
                efType = IccConstants.EF_FDN;
                pin2 = initialValues.getAsString("pin2");
                break;

            default:
                throw new UnsupportedOperationException(
                        "Cannot insert into URL: " + url);
        }

        String tag = initialValues.getAsString("tag");
        String number = initialValues.getAsString("number");
        boolean success = addIccRecordToEf(efType, tag, number, pin2);

        if (!success) {
            return null;
        }

        StringBuilder buf = new StringBuilder("content://im/");
        switch (match) {
            case ADN:
                buf.append("adn/");
                break;

            case FDN:
                buf.append("fdn/");
                break;
        }

        // TODO: we need to find out the rowId for the newly added record
        buf.append(0);

        resultUri = Uri.parse(buf.toString());

        /*
        // notify interested parties that an insertion happened
        getContext().getContentResolver().notifyInsert(
                resultUri, rowID, null);
        */

        return resultUri;
    }

    private String normalizeValue(String inVal) {
        int len = inVal.length();
        String retVal = inVal;

        if (inVal.charAt(0) == '\'' && inVal.charAt(len-1) == '\'') {
            retVal = inVal.substring(1, len-1);
        }

        return retVal;
    }

    @Override
    public int delete(Uri url, String where, String[] whereArgs) {
        int efType;

        if (DBG) log("delete");

        int match = URL_MATCHER.match(url);
        switch (match) {
            case ADN:
                efType = IccConstants.EF_ADN;
                break;

            case FDN:
                efType = IccConstants.EF_FDN;
                break;

            default:
                throw new UnsupportedOperationException(
                        "Cannot insert into URL: " + url);
        }

        // parse where clause
        String tag = null;
        String number = null;
        String pin2 = null;

        String[] tokens = where.split("AND");
        int n = tokens.length;

        while (--n >= 0) {
            String param = tokens[n];
            if (DBG) log("parsing '" + param + "'");

            String[] pair = param.split("=");

            if (pair.length != 2) {
                Log.e(TAG, "resolve: bad whereClause parameter: " + param);
                continue;
            }

            String key = pair[0].trim();
            String val = pair[1].trim();

            if (STR_TAG.equals(key)) {
                tag = normalizeValue(val);
            } else if (STR_NUMBER.equals(key)) {
                number = normalizeValue(val);
            } else if (STR_PIN2.equals(key)) {
                pin2 = normalizeValue(val);
            }
        }

        if (TextUtils.isEmpty(tag)) {
            return 0;
        }

        if (efType == FDN && TextUtils.isEmpty(pin2)) {
            return 0;
        }

        boolean success = deleteIccRecordFromEf(efType, tag, number, pin2);
        if (!success) {
            return 0;
        }

        return 1;
    }

    @Override
    public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
        int efType;
        String pin2 = null;

        if (DBG) log("update");

        int match = URL_MATCHER.match(url);
        switch (match) {
            case ADN:
                efType = IccConstants.EF_ADN;
                break;

            case FDN:
                efType = IccConstants.EF_FDN;
                pin2 = values.getAsString("pin2");
                break;

            default:
                throw new UnsupportedOperationException(
                        "Cannot insert into URL: " + url);
        }

        String tag = values.getAsString("tag");
        String number = values.getAsString("number");
        String newTag = values.getAsString("newTag");
        String newNumber = values.getAsString("newNumber");

        boolean success = updateIccRecordInEf(efType, tag, number,
                newTag, newNumber, pin2);

        if (!success) {
            return 0;
        }

        return 1;
    }

    private ArrayList<ArrayList> loadFromEf(int efType) {
        ArrayList<ArrayList> results = new ArrayList<ArrayList>();
        List<AdnRecord> adnRecords = null;

        if (DBG) log("loadFromEf: efType=" + efType);

        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                    ServiceManager.getService("simphonebook"));
            if (iccIpb != null) {
                adnRecords = iccIpb.getAdnRecordsInEf(efType);
            }
        } catch (RemoteException ex) {
            // ignore it
        } catch (SecurityException ex) {
            if (DBG) log(ex.toString());
        }
        if (adnRecords != null) {
            // Load the results

            int N = adnRecords.size();
            if (DBG) log("adnRecords.size=" + N);
            for (int i = 0; i < N ; i++) {
                loadRecord(adnRecords.get(i), results);
            }
        } else {
            // No results to load
            Log.w(TAG, "Cannot load ADN records");
            results.clear();
        }
        if (DBG) log("loadFromEf: return results");
        return results;
    }

    private boolean
    addIccRecordToEf(int efType, String name, String number, String pin2) {
        if (DBG) log("addIccRecordToEf: efType=" + efType + ", name=" + name +
                ", number=" + number);

        boolean success = false;

        // TODO: do we need to call getAdnRecordsInEf() before calling
        // updateAdnRecordsInEfBySearch()? In any case, we will leave
        // the UI level logic to fill that prereq if necessary. But
        // hopefully, we can remove this requirement.

        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                    ServiceManager.getService("simphonebook"));
            if (iccIpb != null) {
                success = iccIpb.updateAdnRecordsInEfBySearch(efType, "", "",
                        name, number, pin2);
            }
        } catch (RemoteException ex) {
            // ignore it
        } catch (SecurityException ex) {
            if (DBG) log(ex.toString());
        }
        if (DBG) log("addIccRecordToEf: " + success);
        return success;
    }

    private boolean
    updateIccRecordInEf(int efType, String oldName, String oldNumber,
            String newName, String newNumber,String pin2) {
        if (DBG) log("updateIccRecordInEf: efType=" + efType +
                ", oldname=" + oldName + ", oldnumber=" + oldNumber +
                ", newname=" + newName + ", newnumber=" + newNumber);
        boolean success = false;

        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                    ServiceManager.getService("simphonebook"));
            if (iccIpb != null) {
                success = iccIpb.updateAdnRecordsInEfBySearch(efType,
                        oldName, oldNumber, newName, newNumber, pin2);
            }
        } catch (RemoteException ex) {
            // ignore it
        } catch (SecurityException ex) {
            if (DBG) log(ex.toString());
        }
        if (DBG) log("updateIccRecordInEf: " + success);
        return success;
    }


    private boolean deleteIccRecordFromEf(int efType, String name, String number, String pin2) {
        if (DBG) log("deleteIccRecordFromEf: efType=" + efType +
                ", name=" + name + ", number=" + number + ", pin2=" + pin2);

        boolean success = false;

        try {
            IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
                    ServiceManager.getService("simphonebook"));
            if (iccIpb != null) {
                success = iccIpb.updateAdnRecordsInEfBySearch(efType,
                        name, number, "", "", pin2);
            }
        } catch (RemoteException ex) {
            // ignore it
        } catch (SecurityException ex) {
            if (DBG) log(ex.toString());
        }
        if (DBG) log("deleteIccRecordFromEf: " + success);
        return success;
    }

    /**
     * Loads an AdnRecord into an ArrayList. Must be called with mLock held.
     *
     * @param record the ADN record to load from
     * @param results the array list to put the results in
     */
    private void loadRecord(AdnRecord record,
            ArrayList<ArrayList> results) {
        if (!record.isEmpty()) {
            ArrayList<String> contact = new ArrayList<String>(2);
            String alphaTag = record.getAlphaTag();
            String number = record.getNumber();

            if (DBG) log("loadRecord: " + alphaTag + ", " + number);
            contact.add(alphaTag);
            contact.add(number);
            results.add(contact);
        }
    }

    private void log(String msg) {
        Log.d(TAG, "[IccProvider] " + msg);
    }
}

Android拦截电话与短信(电话拒接/短信拒收) 前段时间领导说了这样一个需求:对特定的号码电话进行拦截、短信拒收,在百度了查阅了很多的资料,结果有点不尽人意。特别是AIDL通信接口废了老大劲。直接上过程 创建aidl通信接口直接在main目录新建aldl类型文件ITelephony即可,自动生成包名等等如图所示此处有坑:网上基本上都是让这样写 interface ITelephony { boolean endCall(...... 阅读详情

相关推荐

模拟调制系统实战:从AM到FM的5种调制方式对比与选型指南

本文深度解析AM、DSB、SSB、VSB、FM五种经典模拟调制方式,从实现电路、频谱效率、抗噪性能及工程成本等维度进行实战对比。通过MATLAB/Simulink仿真案例,提供清晰的选型决策框架,帮助工程师在无人机图传、短波通信、广播系统等具体项目中,根据带宽、功耗和抗干扰需求选择最优方案。

study的专栏 900

android-26-带internal-telephony.jar

android sdk -26 带 com.android.internal.telephony 包的 jar, 下载后 将名称改为 android.jar 替换 anroid-sdk -> platform -> android-26 文件下的 android.jar 即可直接找到 telephony 下的类, 不会报错

(二)MS-MPI多机通信

1.关于MPI多机通信 一台计算机处理数据的能力是有限的,MPI的主要作用就是用来实现并行计算机,即将多台主机联机,实现大规模、高性能的计算机机群。我们知道一台计算机同时运行多个进程时,由于计算机资源是共享的,多个进程都会占用一些资源,每个进程运行的效率就会降低,比如当一台计算机同时跑着多个大型应用时会变得非常顿。所谓多机通信,可以理解为将本应该在同一台主机上运行的多个进程分配到多台主机上,以往...

xinwuya_的博客 4374

android如何处理错误,如何在android中解决此错误“com.android.internal.telephony无法解析为类型”...

我正在创建简单的呼叫过滤应用程序,限制不必要的呼我使用以下代码来限制调用,但我无法在下面的代码中解决此行的问题“com.android.internal.telephony.ITelephony telephonyService =(ITelephony)m.invoke(tm);”它显示错误消息com. android.internal.telephony无法解析为android中的某个类型如何...

weixin_40004659的博客 1768

Android Telephony

Telephony提供的功能: Voice, SMS, SIM, Data Connection, STK and etc 这个模块特殊的地方: 1. 在Phone应用中,注册了Service。这样Phone就必须始终运行。    将ITelephony放到Phone应用中:在Service中需要提供UI界面,比如打电话,拨号等。  2. 将与硬件相关的模块,抽离出来。一方面方便维护。另一

DOOM 2386

Android知识梳理:System Service

Android系统中有很多内置的软件,例如,当手机接到来电时,会显示对方的电话号。也可以根据周围的环境将手机设置成震动或静音。如果想把这些功能加到自己的软件中应该怎么办呢?答案就是“系统服务”。在Android系统中提供了很多这种服务,通过这些服务,就可以像Android系统的内置软件一样随心所欲地控制Android系统了。系统服务(System Services)并非Android开发应用程序...

勤奋的大叔 500

[应用代码] android 自动接听电话和挂断 (适合目前所有版本)

转载于:http://www.eoeandroid.com/thread-322243-1-1.html 注意:2.3上实现方式接听使用answerRingingCallWithBroadcast方法 注意:android2.3版本及以上不支持下面的自动接听方法。 (会抛异常:java.lang.SecurityException: Neither user xxxxx nor curren

lyen2010的专栏 3952

Android Telephony分析(四) ---- TelephonyManager详解

前言TelephonyManager主要提供Telephony相关信息的查询/修改功能,以及Phone状态监听功能,封装的方法主要是提供给APP上层使用。 TelephonyManager.java 在frameworks\base\telephony\java\android\telephony目录下。1. TelephonyManager整体结构从TelephonyManager导入的文件中可

linyongan 2万+

android如何读取sim联系人信息,Android上如何获取手机和sim联系人信息

需求很明确,获取手机和sim联系人信息。接口设计也很简介public interface OnFetchContactsListener {void onFetcherContactsComplete(List list);}数据设计为:public class ContactInfo extends BaseModel {private static final long serialVers...

weixin_40001805的博客 1729

androidSIM获取联系人信息

01./** 02. * 从SIM中读取联系人信息 03. * @return 04. */ 05. private Cursor getContacts() { 06. Uri uri = Uri.parse("content://icc/adn");//Contacts.People.CONTENT_URI; 07.//

crazy_jack 1828

Android工具类—— androidSIM获取联系人信息

[java] view plaincopy "font-size:18px;color:#3333ff;">01./**   02.     * 从SIM中读取联系人信息   03.     * @return   04.     */     05.    private Cursor getContacts() {     06.        Uri

Leesire的专栏 1671

php 获取sim,android中判断sim状态和读取联系人资料的方法

在写程序中,有时候可能需要获取sim中的一些联系人资料。在获取sim联系人前,我们一般会先判断sim状态,找到sim后再获取它的资料,如下代码我们可以读取sim中的联系人的一些信息。import android.app.Activity;import android.content.Context;import android.content.Intent;import android....

weixin_32494599的博客 281

android中判断sim状态和读取联系人资料的方法

在写程序中,有时候可能需要获取sim中的一些联系人资料。在获取sim联系人前,我们一般会先判断sim状态,找到sim后再获取它的资料,如下代码我们可以读取sim中的联系人的一些信息。 package com.android.test;       import android.app.Activity;   import android.con

nomisshe的专栏 1188

Android打电话流程学习(一)

打电话

TinyHorse的博客 4245

Telephony中ITelephony的AIDL调用关系

看完小插曲,回到PhoneInterfaceManager类的学习,通过查看这个所在路径packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java,发现它是运行在phone进程下的,它是PhoneGlobals在onCreate方法中初始化的 phoneMgr = PhoneInterfaceManager.init(this),并且这个只能初始化一次。方法也移除了,普通应用不再能够直接更改这些设置。

MYY的博客 1101

android中对sim联系人的增删改查以及监听sim联系数据的改变

主要是对sim联系人增删改查的一些操作,以及ContentObserver的使用,另外给大家推荐一个android源码查看的网址

Do Better Every Day 5881

[python]基于机器学习的恶意加密流量监测平台.zip

[python]基于机器学习的恶意加密流量监测平台

上一篇: Android判断SIM卡属于哪个移动运营商
下一篇: PreferenceActivity详解
jaycee110905
博客等级 码龄16年 328粉丝 232原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值