2010-01-27 12 views
14

Sto cercando di ottenere un oggetto telefonico in modo da poter chiamare e comunicare due numeri dalla mia applicazione.È possibile istanziare un oggetto phone.Phone tramite il sdk?

Ho provato a utilizzare lo statico PhoneFactory.makeDefaultPhones((Context)this) ma non ho avuto fortuna.

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

Error - Caused by java.lang.RuntimeException: PhoneFactory.getDefaultPhone must be called from Looper thread

+0

Questo è probabilmente ovvio ma, poiché 'PhoneFactory' non è nell'SDK, probabilmente non si vuole usarlo :) –

+1

Quando si esegue questo codice, ottengo un' InvocationTargetException' su 'getDefaultPhone.invoke (null)'. Ho anche provato a precederlo con 'getDefaultPhone.setAccessible (true)', ma questo non ha alcun effetto. –

+0

@Tyler devo avviare la chiamata in conferenza dalla mia applicazione. se hai trovato una soluzione .pls answer here –

risposta

0

I am trying to get a phone object so that I can call and conference two numbers from within my application.

Questo non è possibile dal SDK.

I have tried using the static PhoneFactory.makeDefaultPhones((Context)this) but have not had any luck.

Questo non è nell'SDK. Si prega di do not go past the bounds of the SDK.

Error - Caused by java.lang.RuntimeException: PhoneFactory.getDefaultPhone must be called from Looper thread

Questo è perché si sta cercando di fare la cosa-tu sei-non-supposto-to-be-facendo da un thread in background.

+4

Mi rendo conto che non dovrei, comunque per fare la gestione delle chiamate avanzate dalla mia applicazione, nessuno dei metodi pubblici sarà sufficiente. Voglio chiamare due numeri, metterli in conferenza e terminare la chiamata quando appropriato. Avete delle raccomandazioni su come farlo al di fuori di ottenere un oggetto Phone interno. – tsmith

0

ho chiamato da Activity.onCreate e si schiantò diverse linee dopo il problema con il seguente errore:

Default phones haven't been made yet!

See the Android sources:

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; 
} 
4

Al minimo che possiamo rispondere o ignorare le chiamate =) fammi copiare e incollare il mio post

OMG !!! SI, POSSIAMO FARE QUELLO !!!
Stavo per uccidermi dopo 24 ore di ricerche e scoperte ... Ma ho trovato una soluzione "fresca"!

// "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); 

persone che vogliono sviluppare il loro software di controllo delle chiamate visita questo punto di partenza: 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

c'è un progetto. e ci sono commenti importanti (e crediti).

In breve: copia il file AIDL, aggiungi le autorizzazioni per manifest, copia-incolla l'origine per la gestione della telefonia.

Altre informazioni per voi. Comandi AT che puoi inviare solo se sei rootato. Quindi è possibile interrompere il processo di sistema e inviare i comandi, ma è necessario un riavvio per consentire al telefono di ricevere e inviare chiamate.

Sono molto felice! =) Ora il mio Shake2MuteCall riceverà un aggiornamento!

+0

Posso confermare che il progetto 'myLock' funziona (puoi verificarlo da SVN da http://mylockforandroid.googlecode.com/svn/trunk/phone/), ma non fornisce l'accesso a' PhoneFactory'. C'è un modo per modificare questo approccio per farlo, o per lo meno ottenere la chiamata attiva? –

+0

Si noti che si sta accedendo ai componenti interni del framework Android. E non hai garanzie su cosa sia mai stato così. Probabilmente non funzionerà su tutti i dispositivi e potrebbe improvvisamente smettere di funzionare su alcuni dispositivi dopo un aggiornamento. –

+0

Link va a 404; [ – r1si

11

Sì, può essere istanziato. Ma è necessario superare un paio di ostacoli:

  • Nella tua AndroidManifest.xml set

    android:sharedUserId="android.uid.phone"

    all'interno del tag <manifest>. Ciò è necessario per impedire che venga emesso un SecurityException quando gli Intenti protetti vengono inviati dai metodi che è possibile richiamare (come android.intent.action.SIM_STATE_CHANGED).

  • Set

    android:process="com.android.phone"

    nel tag <application>. Questo è necessario per consentire l'invocazione di getDefaultPhone()/makeDefaultPhone().

  • Per fare tutto questo, l'app deve essere firmata con la chiave di firma del sistema.

2

Hy. Sono stato in grado di recuperare un ProxyPhone attraverso questa classe (e un po 'di riflessione). È possibile utilizzare il (riflessa) PhoneFactory di seguito:

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; 

} 
} 

Con esso, utilizzare il codice:

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

Si noti che la chiamata "makeDefaultPhone" aggiornerà il valore del membro statica "static Looper privato sLooper;" e non ho ancora testato gli effetti collaterali.

Con l'oggetto "phoneProxy" ricevuto è possibile effettuare il riflesso della chiamata di PhoneProxy. (Attualmente sto implementando questa classe e potrei postarla se ritenuta utile

+0

piace come il tuo avvolto in una classe ReflectedPhone. buon modello. –

+0

Ho provato questo su un Galaxy S2 ma ho ottenuto una InvocationTargetException sulla riga 'ret = (Object) get.invoke (null, (Object []) null)'. – brianestey

0

Fyi, le classi interne Phone, CallManager e altre ancora vengono spostate da /system/framework/framework.jar a/system/framework/telephony-common .jar in Jelly bean

Problemi correlati