Можно ли создать объект telephony.Phone через SDK?

Я пытаюсь получить телефонный объект, чтобы я мог позвонить и конференц-связь двух номеров из моего приложения.

Я пытался использовать статический PhoneFactory.makeDefaultPhones((Context)this) но не повезло.

String phoneFactoryName = "com.android.internal.telephony.PhoneFactory";
String phoneName = "com.android.internal.telephony.Phone";
Class phoneFactoryClass = Class.forName(phoneFactoryName);
Class phoneClass = Class.forName(phoneName);
Method getDefaultPhone = phoneFactoryClass.getMethod("getDefaultPhone");
Object phoneObject = getDefaultPhone.invoke(null);

Ошибка - вызвана java.lang.RuntimeException: PhoneFactory.getDefaultPhone должен быть вызван из потока Looper

6 ответов

Да, это может быть реализовано. Но вы должны преодолеть пару препятствий:

  • В вашем AndroidManifest.xml задавать

    андроид:sharedUserId="android.uid.phone"

    в пределах <manifest> тег. Это необходимо для предотвращения SecurityException от того, чтобы быть брошенным, когда защищенные Интенты отправляются методами, которые вы можете вызвать (например, android.intent.action.SIM_STATE_CHANGED).

  • Задавать

    Android: процесс ="com.android.phone"

    в вашем <application> тег. Это необходимо для разрешения вызова getDefaultPhone() / makeDefaultPhone(),

  • Чтобы сделать все это, ваше приложение должно быть подписано с помощью ключа подписи системы.

По крайней мере, мы можем отвечать или игнорировать звонки =) позвольте мне скопировать и вставить мой пост

О, МОЙ БОГ!!! Да, мы можем сделать это!!!
Я собирался покончить с собой после 24 часов суровых исследований и открытий... Но я нашел "свежее" решение!

// "cheat" with Java reflection to gain access
// to TelephonyManager's ITelephony getter
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony)m.invoke(tm);

Люди, которые хотят разработать свое программное обеспечение для управления вызовами, посещают эту начальную точку: http://www.google.com/codesearch/p?hl=en#zvQ8rp58BUs/trunk/phone/src/i4nc4mp/myLock/phone/CallPrompt.java&q = itelephony% 20package: HTTP://mylockforandroid%5C.googlecode%5C.com&d=0

Есть проект. и есть важные комментарии (и кредиты).

Вкратце: скопируйте файл AIDL, добавьте разрешения в манифест, скопируйте и вставьте источник для управления телефонией.

Еще немного информации для вас. AT команды вы можете отправлять, только если у вас есть права root. Чем вы можете убить системный процесс и отправить команды, но вам потребуется перезагрузка, чтобы ваш телефон мог принимать и отправлять вызовы.

Я очень счастлив! =) Теперь мой Shake2MuteCall получит обновление!

Hy. Я смог получить ProxyPhone, который работал с этим классом (и немного размышлений). Вы можете использовать (Отраженный)PhoneFactory ниже:

package your.package;

import java.lang.reflect.Method;

import android.content.Context;
import android.util.Log;

public class ReflectedPhoneFactory {

public static final String TAG = "PHONE";

public static void makeDefaultPhones(Context context) throws IllegalArgumentException {

    try{

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes")
      Class PhoneFactory = cl.loadClass("com.android.internal.telephony.PhoneFactory");

      //Parameters Types
      @SuppressWarnings("rawtypes")
      Class[] paramTypes= new Class[1];
      paramTypes[0]= Context.class;

      Method get = PhoneFactory.getMethod("makeDefaultPhone",  paramTypes);

      //Parameters
      Object[] params= new Object[1];
      params[0]= context;

      get.invoke(null, params);

    }catch( IllegalArgumentException iAE ){
        throw iAE;
    }catch( Exception e ){
        Log.e(TAG, "makeDefaultPhones", e);
    }

}

public static void makeDefaultPhone(Context context) throws IllegalArgumentException {

    try{

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes")
      Class PhoneFactory = cl.loadClass("com.android.internal.telephony.PhoneFactory");

      //Parameters Types
      @SuppressWarnings("rawtypes")
      Class[] paramTypes= new Class[1];
      paramTypes[0]= Context.class;

      Method get = PhoneFactory.getMethod("makeDefaultPhone",  paramTypes);

      //Parameters
      Object[] params= new Object[1];
      params[0]= context;

      get.invoke(null, params);

    }catch( IllegalArgumentException iAE ){
        throw iAE;
    }catch( Exception e ){
        Log.e(TAG, "makeDefaultPhone", e);
    }

}

/*
 * This function returns the type of the phone, depending
 * on the network mode.
 *
 * @param network mode
 * @return Phone Type
 */
public static Integer getPhoneType(Context context, int networkMode) throws IllegalArgumentException {

    Integer ret= -1;

    try{

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes")
      Class PhoneFactory = cl.loadClass("com.android.internal.telephony.PhoneFactory");

      //Parameters Types
      @SuppressWarnings("rawtypes")
      Class[] paramTypes= new Class[1];
      paramTypes[0]= Integer.class;

      Method get = PhoneFactory.getMethod("getPhoneType", paramTypes);

      //Parameters
      Object[] params= new Object[1];
      params[0]= new Integer(networkMode);

      ret= (Integer) get.invoke(PhoneFactory, params);

    }catch( IllegalArgumentException iAE ){
        throw iAE;
    }catch( Exception e ){
        ret= -1;
    }

    return ret;

}

public static Object getDefaultPhone(Context context) throws IllegalArgumentException {

    Object ret= null;

    try{

        ClassLoader cl = context.getClassLoader(); 
        @SuppressWarnings("rawtypes")
        Class PhoneFactory = cl.loadClass("com.android.internal.telephony.PhoneFactory");

        Method get = PhoneFactory.getMethod("getDefaultPhone",  (Class[]) null);
        ret= (Object)get.invoke(null, (Object[]) null);

    }catch( IllegalArgumentException iAE ){
        throw iAE;
    }catch( Exception e ){
        Log.e(TAG, "getDefaultPhone", e);
    }

    return ret;

}

public static Phone getCdmaPhone(Context context) throws IllegalArgumentException {

    Phone ret= null;

    try{

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes")
      Class PhoneFactory = cl.loadClass("com.android.internal.telephony.PhoneFactory");

      Method get = PhoneFactory.getMethod("getCdmaPhone",  (Class[]) null);
      ret= (Phone)get.invoke(null, (Object[]) null);

    }catch( IllegalArgumentException iAE ){
        throw iAE;
    }catch( Exception e ){
        //
    }

    return ret;

}

public static Phone getGsmPhone(Context context) throws IllegalArgumentException {

    Phone ret= null;

    try{

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes")
      Class PhoneFactory = cl.loadClass("com.android.internal.telephony.PhoneFactory");

      Method get = PhoneFactory.getMethod("getGsmPhone",  (Class[]) null);
      ret= (Phone)get.invoke(null, (Object[]) null);

    }catch( IllegalArgumentException iAE ){
        throw iAE;
    }catch( Exception e ){
        //
    }

    return ret;

}
}

С ним используйте код:

        ReflectedPhoneFactory.makeDefaultPhone(yourContext);
        Object phoneProxy= ReflectedPhoneFactory.getDefaultPhone(yourContext);

Обратите внимание, что вызов "makeDefaultPhone" обновит значение статического члена "static private Looper sLooper;" и я еще не проверил на побочные эффекты.

С помощью полученного объекта phoneProxy вы можете отразить проблему вызова PhoneProxy. (В настоящее время я реализую этот класс и могу опубликовать его, если посчитаю полезным.

К вашему сведению, внутренние классы Phone, CallManager и некоторые другие перемещены из /system/framework/framework.jar в /system/framework/telephony-common.jar в Jelly bean.

Я пытаюсь получить телефонный объект, чтобы я мог позвонить и конференц-связь двух номеров из моего приложения.

Это невозможно из SDK.

Я пытался использовать статический PhoneFactory.makeDefaultPhones((Context) это), но не повезло.

Этого нет в SDK. Пожалуйста , не выходите за пределы SDK.

Ошибка - вызвана java.lang.RuntimeException: PhoneFactory.getDefaultPhone должен быть вызван из потока Looper

Это потому, что вы пытаетесь сделать то, чего не должны делать из фонового потока.

Я вызвал его из Activity.onCreate, и он разбился на несколько строк после вашей проблемы со следующей ошибкой:

Стандартные телефоны еще не были сделаны!

Смотрите источники Android:

public static Phone getDefaultPhone() {
    if (sLooper != Looper.myLooper()) {
        throw new RuntimeException(
            "PhoneFactory.getDefaultPhone must be called from Looper thread");
    }

    if (!sMadeDefaults) {
        throw new IllegalStateException("Default phones haven't been made yet!");
    }
    return sProxyPhone;
}
Другие вопросы по тегам