Как использовать com.android.internal.CallManager в приложении для Android

ОБНОВЛЕНИЯ:

«Пожалуйста, смотрите комментарий ниже для новейших состояний».

Я пытаюсь использовать этот класс «com.android.internal.CallManager» в своем приложении. Я изучал эту тему несколько дней. Однако я не нашел ничего, кроме этого и это. Они оба не могут решить мою проблему. Я использовал два способа вызова скрытого API Android.

1) Первый способ, который я использую для вызова скрытого API, — это Java Reflection. Вот мой пример кода:

ClassLoader classLoader = context.getClass().getClassLoader();
final Class<?> callManagerClass = classLoader.loadClass("com.android.internal.telephony.CallManager");

Method getInstanceMethod = callManagerClass.getDeclaredMethod("getInstance");
getInstanceMethod.setAccessible(true);
mCallManager = getInstanceMethod.invoke(null);

mActiveFgMethod = callManagerClass.getDeclaredMethod("hasActiveFgCall");
Object res = mActiveFgMethod.invoke(mCallManager);

boolean result = ((Boolean) res).booleanValue();

Как видите, я использую Java Reflection для доступа к CallManager и затем получаю доступ к функции hasActiveFgCall. Но каким бы ни было состояние телефона, результатом будет false.

2) Второй способ, который я использую, похож на этот сайт (http://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction//). Ниже приведен пример кода.

import com.android.internal.telephoney.CallManager;

CallManager mCallManager = CallManager.getInstance();
boolean result = mCallManager.hasActiveFgCall();

Я скачал и скомпилировал исходный код Android 4.1.2. Файл jar был следующим: «out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar». Я мог успешно вызвать класс и функцию. К сожалению, результат тот же, false.

Ниже приведены разрешения, которые я добавил:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.USE_SIP" />

Я проверил код этого файла класса (CallManager.java) и нашел список вызовов функций: hasActiveFgCall() --> getFirstActiveCall() --> isIdle(). Я думал, что неправильно понял состояние телефона, поэтому написал приложение для проверки состояния телефона. Код выглядит следующим образом:

public class MainActivity extends Activity {
    private static final String TAG = "Telephony";

    TextView t1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        t1 = (TextView) this.findViewById(R.id.text1);

        TelephonyManager mTelephonyMgr = (TelephonyManager) 
                this.getSystemService(Context.TELEPHONY_SERVICE);

        mTelephonyMgr.listen(new TeleListener(), 
                PhoneStateListener.LISTEN_CALL_STATE);

        t1.setText("listen the state of phone:\n"); 
    }

    class TeleListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                Log.e(TAG, "CALL_STATE_IDEL");
                t1.append("CALL_STATE_IDLE"+"\n");
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                Log.e(TAG, "CALL_STATE_OFFHOOK");
                t1.append("CALL_STATE_OFFHOOK" + "\n");
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                Log.e(TAG, "CALL_STATE_RINGING");
                t1.append("CALL_STATE_RINGING"+"\n");
                break;

            default:
                break;

            }
        }
    }
}

Однако я был прав. Независимо от того, в каком состоянии находился телефон, например OFFHOOK, IDLE и RINGING, функция hasActivieFgCall() возвращала значение false. Это очень расстраивает.

Будем признательны за любой ответ.


person Community    schedule 09.08.2013    source источник
comment
какие разрешения у вашего приложения. Могут быть проверки разрешений, чтобы ваше приложение и приложения, подобные вашему, не могли получать информацию из внутренних классов API, которые скрыты от SDK ... по какой-то причине.   -  person dudebrobro    schedule 09.08.2013
comment
@QuentinSwain спасибо за ваш комментарий. Я попытался добавить некоторые разрешения в приложение. Например, я выбрал все разрешения, применяемые Android Phone.apk, и удалил некоторые разрешения не для стороннего приложения. Однако ничего не изменилось. Я не мог получить правильный результат.   -  person dongmu    schedule 11.08.2013
comment
Какие разрешения вы пытались добавить? Вы создаете свое приложение с помощью eclipse или у вас есть полная проверка AOSP? Вы смотрели исходный код для TelephonyManager/Telephony Services?   -  person dudebrobro    schedule 11.08.2013
comment
@QuentinSwain Я перечислил разрешения выше. Они были из Android Phone.apk без каких-либо разрешений, а не для стороннего приложения. Да, я создаю свое приложение с помощью eclipse и проверяю некоторый код в AOSP, например Phone.apk, и пакет framework/base/telephony/java/com/android/internal/telephony/ и framework/base/telephony/java/android. /телефония. Однако ничто не могло помочь.   -  person dongmu    schedule 12.08.2013
comment
Я хотел использовать CallManager для получения состояний телефона. Однако, перечитав код еще раз, я обнаружил, что ошибался. Хотя я вызвал CallManager.getInstance(), я только что получил его в среде своего приложения, что означает, что я мог получить только состояние телефонов в своем приложении. В моем приложении не зарегистрирован телефон, и я не могу зарегистрировать телефон Phone.apk в своем приложении. Поэтому, если я вызвал класс Callmanager, я ничего не получил. Это все.   -  person dongmu    schedule 13.09.2013


Ответы (1)


Ему не нравится такой сервис, как ITelephony, который может использоваться Java Reflection и helpl. Я думаю, что единственный способ использовать CallManager — это дать вашему приложению системное разрешение.

вам нужно подписать свой apk и добавить android:sharedUserId="android.uid.system" в ваш файл mainfest.

person Community    schedule 05.03.2014
comment
Спасибо, @Akachy. На самом деле, я видел метод, который мог бы использовать ITelephony by aidl и сделать телефонный звонок без внимания пользователя. Я не мог найти точный URL, который я видел. Но я уверен, что это можно сделать. - person dongmu; 28.03.2014