如何在Android上编程隐藏来电者身份信息

6
在安卓手机上,可以在"通话" -> "附加设置" -> "来电显示"下隐藏您的来电显示。我想从我的代码中以编程方式实现这一点,但是找不到方法来实现它。我已经搜索了2.1版本的android.provider和android.telephony,但没有找到相关信息。是否有人成功解决了这个问题呢?谢谢。最好的问候。
2个回答

1

在这里,我将描述我尝试过的两种方法。

1.) 可以从您的应用程序中显示“附加呼叫设置”屏幕。虽然它看起来像是设置应用程序的一部分,但事实并非如此。该活动是原生电话应用程序的一部分,并且可以使用以下意图进行访问:

Intent additionalCallSettingsIntent = new Intent("android.intent.action.MAIN");
ComponentName distantActivity = new ComponentName("com.android.phone", "com.android.phone.GsmUmtsAdditionalCallOptions");
additionalCallSettingsIntent.setComponent(distantActivity);
startActivity(additionalCallSettingsIntent);

然后用户必须手动按下CallerID偏好设置,并获得带有3个选项的单选按钮。

这实际上不是我在提问时想要实现的。我想避免用户必须选择任何进一步的选项的步骤。

2.) 当在本机电话应用程序中执行1.)中描述的方法时,使用了com.android.internal.telephony.Phone中的setOutgoingCallerIdDisplay()函数。这是下一个方法的基础:在此类上使用Java反射,并尝试使用适当的参数调用该函数:

try 
{
    Class <?> phoneFactoryClass = Class.forName("com.android.internal.telephony.PhoneFactory");

    try
    {
        Method getDefaultPhoneMethod = phoneFactoryClass.getDeclaredMethod("getDefaultPhone");              
        Method makeDefaultPhoneMethod = phoneFactoryClass.getMethod("makeDefaultPhone" , Context.class);                

        try
        {                       
            makeDefaultPhoneMethod.invoke(null, this);
            Object defaultPhone = getDefaultPhoneMethod.invoke(null);

            Class <?> phoneInterface = Class.forName("com.android.internal.telephony.Phone");
            Method getPhoneServiceMethod = phoneInterface.getMethod("setOutgoingCallerIdDisplay", int.class, Message.class);

            getPhoneServiceMethod.invoke(defaultPhone, 1, null);                    
        }
        catch (InvocationTargetException ex) 
        {
            ex.printStackTrace();                   
        }
        catch (IllegalAccessException ex) 
        {
            ex.printStackTrace();                   
        }       
    }
    catch (NoSuchMethodException ex) 
    {
        ex.printStackTrace();                   
    }           
}
catch (ClassNotFoundException ex) 
{
    ex.printStackTrace();                   
}       

首先,我尝试使用getDefaultPhone(),但是我得到了RuntimeException。

"PhoneFactory.getDefaultPhone必须从Looper线程中调用"

显然,问题在于我试图从不是本机电话应用程序的消息循环中调用此方法。

尝试通过创建自己的默认电话来避免这个问题,但这是一种安全违规:

ERROR/AndroidRuntime(2338): java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.provider.Telephony.SPN_STRINGS_UPDATED from pid=2338, uid=10048

克服这个问题的唯一方法(两个问题)是使用与核心系统应用程序相同的密钥签署您的应用程序,如下所述

以root身份运行安全API调用,android


如何获取与核心系统应用相同的密钥以及如何签署我的应用程序? - pengwang
请参考我回答底部的链接。您将在那里找到更详细的讨论。但一般来说,由于安全原因,除非您自己“烹饪”Android系统构建,否则不应该可能获取它。 - Zelimir
@Zelimir,你能帮我看看这里吗?(https://dev59.com/JX7aa4cB1Zd3GeqPqXMf)… - RuntimeException

0

我不确定这是否是全球性的功能,但澳大利亚手机可以通过在呼叫者号码前加上#31#1831来隐藏其号码。这可能不是完美的解决方案,但像这样的前缀可能在编程期间适用于您的要求。


是的,我知道这一点,但我正在寻找一种通过Android系统并且不依赖于网络提供商的方法来完成它。无论如何,感谢你的提示。 - Zelimir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接