How to programatically hide Caller ID on Android

后端 未结 2 1923
后悔当初
后悔当初 2020-12-10 07:29

on Android phones, under Call -> Additional settings -> Caller ID

it is possible to hide your caller ID. I want to do that programatically from my code, but was not

相关标签:
2条回答
  • 2020-12-10 07:37

    I'm not sure if this is a global feature, but Australian phones can hide their number by prefixing the caller's number with #31# or 1831. This may not be the perfect solution, but a prefix like this could possibly work for your requirements during coding.

    0 讨论(0)
  • 2020-12-10 07:40

    Here I will describe two approaches I tried.

    1.) It is possible to display Additional Call Settings screen from your application. Although it looks like it is part of the Settings application, that is not true. This Activity is part of the Native Phone Application, and it may be approached with the following intent:

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

    Then user has to manually press on the CallerID preference and gets radio button with 3 options.

    This was not actually what I wanted to achieve when I asked this question. I wanted to avoid step where user has to select any further options.

    2.) When approach described under 1.) is executed in the Native Phone Application, function setOutgoingCallerIdDisplay() from com.android.internal.telephony.Phone has been used. This was the basis for the next approach: use Java Reflection on this class and try to invoke the function with appropriate parameters:

    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();                   
    }       
    

    Firstly I tried just to use getDefaultPhone(), but I get RuntimeException

    "PhoneFactory.getDefaultPhone must be called from Looper thread"

    Obviously, issue lies in the fact that I tried to call this method from the Message Loop that was not the Native Phone App one.

    Tried to avoid this by making own default phone, but this was a security violation:

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

    The only way to overcome (both of) this would be to sign your app with the same key as the core systems app, as described under

    Run secure API calls as root, android

    0 讨论(0)
提交回复
热议问题