Autore Topic: DTMF non sempre riconosciuti  (Letto 3046 volte)

Offline nicopasso

  • Nuovo arrivato
  • *
  • Post: 32
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 7, Mac OS X 10.5
DTMF non sempre riconosciuti
« il: 30 Maggio 2012, 17:01:04 CEST »
0
Ciao a tutti,
sto sviluppando un'applicazione che effettua una chiamata a un IVR (le voci guidate del tipo: "premi 1 per fare qualcosa, premi 2 per fare qualcos'altro...") e poi permette di attivare delle scelte tramite click di button che riproducono i suoni DTMF che l'IVR attende per procedere nel "cammino" della chiamata.
Attualmente l'applicazione s Nexus S con ICS 4.0.4 funziona correttamente. L'IVR riconosce il tasto premuto/suono generato senza problemi. Invece su altri modelli i suoni DTMF non vengono affatto riconosciuti.
Sarebbe stato ragionevole, a mio avviso, che o i DTMF non fossero riconosciuti MAI oppure che fossero riconosciuti sempre. Invece varia da dispositivo a dispsitivo. Addirittura su due Nexus S con ICS 4.0.4 ho comportamenti differenti (su uno funziona sempre, sull'altro cosi cosi).

Il codice di riproduzione dei DTMF è semplicemente questo:
Codice (Java): [Seleziona]
ToneGenerator gen = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
Button dtmf1Btn = (Button) findViewById(R.id.dtmf1);
dtmf1Btn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                               gen.startTone(ToneGenerator.TONE_DTMF_1, 500);
                               //Other stuff
                        }
//e cosi per ogni bottone da 1 a 9

Ovviamente sono a conoscenza del fatto che i suoni DTMF, come gentilmente detto su Android Developer, non possono essere inviati nella chiamata ma solamente riprodotti mediante ToneGenerator. 

Avete qualche idea in merito a tutto ciò? Al funzionamento dei DTMF e al riconoscimento da parte di un IVR di essi? In che modo lo fa se mi basta generare il tono per farglielo riconoscere?
Spero possiate aiutarmi a trovare un modo in cui sia possibile risolvere una situazione di questo tipo.
Ripeto funziona su Nexus S 4.0.4 ma ad esempio non funziona su GalaxySII 4.0.3 o su Galaxy  Next Turbo 2.3.6. E questo mi lascia molto perplesso.
ciao
nick

Offline nicopasso

  • Nuovo arrivato
  • *
  • Post: 32
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 7, Mac OS X 10.5
Re:DTMF non sempre riconosciuti
« Risposta #1 il: 01 Giugno 2012, 11:52:29 CEST »
0
Ho fatto dei passi avanti (o almeno spero). Adesso tramite Reflection riesco ad accedere al metodo sendDtmf della classe CallManager. Ora però viene lanciata un'eccezione che non riesco a risolvere.

Di seguito vi metto il codice della reflection:
Codice (Java): [Seleziona]
String className = "com.android.internal.telephony.CallManager";

                                try {
                                        Class myClass = Class.forName(className);
                                       
                                        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
                                       
                                        Class<?> classCallManager =
                                        classLoader.loadClass("com.android.internal.telephony.CallManager");
                                        Log.i("DEBUG", "Class loaded " + classCallManager.toString());
                                       
                                         //Class[] paramTypes= new Class[1];
                                         Class<?>[] paramTypes = new Class<?>[]{char.class};
                                        Method m = classCallManager.getMethod("sendDtmf", paramTypes);
                                       
                                        m.setAccessible(true);
                                        m.invoke(null, '1');
                                       
                                } catch (ClassNotFoundException e) {
                                        Log.e("ERROR", "sendDtmf", e);
                                } catch (NoSuchMethodException e) {
                                        Log.e("ERROR", "sendDtmf", e);
                                } catch (InvocationTargetException e) {
                                       
                                } catch (IllegalAccessException e) {
                                       
                                }

L'eccezione che viene lanciata è:
Codice (Java): [Seleziona]
06-01 11:44:51.902: E/AndroidRuntime(7107): FATAL EXCEPTION: main
06-01 11:44:51.902: E/AndroidRuntime(7107): java.lang.IllegalArgumentException: expected receiver of type com.android.internal.telephony.CallManager, but got null
06-01 11:44:51.902: E/AndroidRuntime(7107):     at java.lang.reflect.Method.invokeNative(Native Method)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at java.lang.reflect.Method.invoke(Method.java:511)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at it.digitalnatives.*****.ricarica.MainRicarica$2.onClick(MainRicarica.java:561)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at android.view.View.performClick(View.java:3511)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at android.view.View$PerformClick.run(View.java:14105)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at android.os.Handler.handleCallback(Handler.java:605)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at android.os.Handler.dispatchMessage(Handler.java:92)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at android.os.Looper.loop(Looper.java:137)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at android.app.ActivityThread.main(ActivityThread.java:4424)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at java.lang.reflect.Method.invokeNative(Native Method)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at java.lang.reflect.Method.invoke(Method.java:511)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-01 11:44:51.902: E/AndroidRuntime(7107):     at dalvik.system.NativeStart.main(Native Method)

Avete idea di che parametro devo passare al metodo invoke per far sì che l'eccezione non si verifichi più?
Grazie mille! Spero che possiate darmi dei consigli su come risolvere questa situazione!

Offline DarnellNajanReed

  • Utente normale
  • ***
  • Post: 359
  • Respect: +49
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus One, Acer Iconia A500/501, Asus Transformer Prime, Galaxy ACE, Galaxy S Plus, Galaxy S Advance P, Galaxy Tab 2 7.0, Google Nexus 7
  • Play Store ID:
    Luigi Notaro
  • Sistema operativo:
    OS X 10.8.3
Re:DTMF non sempre riconosciuti
« Risposta #2 il: 01 Giugno 2012, 11:59:32 CEST »
0
Codice (Java): [Seleziona]
expected receiver of type com.android.internal.telephony.CallManager, but got null

Offline nicopasso

  • Nuovo arrivato
  • *
  • Post: 32
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 7, Mac OS X 10.5
Re:DTMF non sempre riconosciuti
« Risposta #3 il: 01 Giugno 2012, 12:07:06 CEST »
0
Ti è partito il post senza completarlo o era un suggerimento nascosto?   :D

Offline DarnellNajanReed

  • Utente normale
  • ***
  • Post: 359
  • Respect: +49
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus One, Acer Iconia A500/501, Asus Transformer Prime, Galaxy ACE, Galaxy S Plus, Galaxy S Advance P, Galaxy Tab 2 7.0, Google Nexus 7
  • Play Store ID:
    Luigi Notaro
  • Sistema operativo:
    OS X 10.8.3
Re:DTMF non sempre riconosciuti
« Risposta #4 il: 01 Giugno 2012, 12:10:53 CEST »
0
Tu hai chiesto:
Citazione
Avete idea di che parametro devo passare al metodo invoke per far sì che l'eccezione non si verifichi più?
E io ti ho evidenziato una riga del logcat che ti dice che al posto di quel null si aspetta una istanza di com.android.internal.telephony.CallManager, ovvero il tipo di parametro da passare.

Offline nicopasso

  • Nuovo arrivato
  • *
  • Post: 32
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 7, Mac OS X 10.5
Re:DTMF non sempre riconosciuti
« Risposta #5 il: 01 Giugno 2012, 12:32:03 CEST »
0
Si si questo era chiaro. Il problema è che non riesco a creare un'istanza di CallManager.

Offline DarnellNajanReed

  • Utente normale
  • ***
  • Post: 359
  • Respect: +49
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus One, Acer Iconia A500/501, Asus Transformer Prime, Galaxy ACE, Galaxy S Plus, Galaxy S Advance P, Galaxy Tab 2 7.0, Google Nexus 7
  • Play Store ID:
    Luigi Notaro
  • Sistema operativo:
    OS X 10.8.3
Re:DTMF non sempre riconosciuti
« Risposta #6 il: 01 Giugno 2012, 12:43:44 CEST »
0
Perchè hai saltato il getInstance dall'esempio che ti hanno postato qui? http://stackoverflow.com/questions/10846838/using-reflection-to-access-dtmf-functionalties-in-androidandroid
Viene usato appunto per recuperare una istanza di quella che dovrebbe servire a te....

Codice (Java): [Seleziona]
Object res = mSendDtmfMethod.invoke(mCallManager,
                        new Object[]{Character.valueOf(ch)});

Offline nicopasso

  • Nuovo arrivato
  • *
  • Post: 32
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 7, Mac OS X 10.5
Re:DTMF non sempre riconosciuti
« Risposta #7 il: 01 Giugno 2012, 13:02:44 CEST »
0
Il codice è uscito dopo che avevo scritto qui!  ;-)

Adesso faccio un po' di prove! Grazie ancora per l'aiuto

Offline nicopasso

  • Nuovo arrivato
  • *
  • Post: 32
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 7, Mac OS X 10.5
Re:DTMF non sempre riconosciuti
« Risposta #8 il: 01 Giugno 2012, 16:13:17 CEST »
0
Ho fatto ulteriori passi avanti.
Ora riesco ad accedere al metodo sendDtmf tramite la Reflection.
Però non viene inviato il tono perchè non viene riconosciuta la chiamata che è in corso, come attiva.
Ho provato sia hasActiveFgCall() che hasActiveBgCall() ed entrambi restituiscono false. Inoltre lo stato del telefono è OFFHOOK (quindi la chiamata effettivamente è in corso!).
Come faccio allora a recuperare questa chiamata attiva sulla quale inviare i suoni DTMF?
Grazie

Offline DarnellNajanReed

  • Utente normale
  • ***
  • Post: 359
  • Respect: +49
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus One, Acer Iconia A500/501, Asus Transformer Prime, Galaxy ACE, Galaxy S Plus, Galaxy S Advance P, Galaxy Tab 2 7.0, Google Nexus 7
  • Play Store ID:
    Luigi Notaro
  • Sistema operativo:
    OS X 10.8.3
Re:DTMF non sempre riconosciuti
« Risposta #9 il: 01 Giugno 2012, 16:15:19 CEST »
0
Hai inserito nel manifest il permesso READ_PHONE_STATE?

Offline nicopasso

  • Nuovo arrivato
  • *
  • Post: 32
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 7, Mac OS X 10.5
Re:DTMF non sempre riconosciuti
« Risposta #10 il: 01 Giugno 2012, 17:10:51 CEST »
0
Si si l'ho messo.

Continuando con i tentativi non capisco come mai non riesco (o forse non posso) a riconoscere la chiamata in corso come chiamata "attiva".