Autore Topic: Problema con utilizzo della classe AdnRecordLoader  (Letto 704 volte)

Offline RandomMan

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Acer Liquid E
  • Sistema operativo:
    Microsoft Windows XP
Problema con utilizzo della classe AdnRecordLoader
« il: 28 Novembre 2010, 16:22:52 CET »
0
Salve a tutti.
Stavo cercando di creare un'app in grado di accedere ai dati della SIM (non quelli classici a cui si può accedere tramite TelephonyManager). Sfogliando le classi dell'OS ho scoperto che ce n'è una di nome "AdnRecordLoader" in grado di caricare (e forse scrivere) i file SIM EF. Ho dunque provato a creare una bozza di programma che legge un Record di un generico EF. Tutte queste classi non sono disponibili nelle API pubbliche dunque le ho chiamate tutte tramite "reflection".  Ecco qui il codice...

Codice (Java): [Seleziona]
package com.example.simAdvancedTest;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity {
       
         
        // ------------ SIM FILES -------------------
       
        // GSM SIM file ids from TS 51.011
    static final int EF_ADN = 0x6F3A;
    static final int EF_FDN = 0x6F3B;
    static final int EF_SDN = 0x6F49;
    static final int EF_EXT1 = 0x6F4A;
    static final int EF_EXT2 = 0x6F4B;
    static final int EF_EXT3 = 0x6F4C;
    static final int EF_EXT6 = 0x6fc8;   // Ext record for EF[MBDN]
    static final int EF_MWIS = 0x6FCA;
    static final int EF_MBDN = 0x6fc7;
    static final int EF_PNN = 0x6fc5;
    static final int EF_SPN = 0x6F46;
    static final int EF_SMS = 0x6F3C;
    static final int EF_ICCID = 0x2fe2;
    static final int EF_AD = 0x6FAD;
    static final int EF_MBI = 0x6fc9;
    static final int EF_MSISDN = 0x6f40;
    static final int EF_SPDI = 0x6fcd;
    static final int EF_SST = 0x6f38;
    static final int EF_CFIS = 0x6FCB;
    static final int EF_IMG = 0x4f20;

    // USIM SIM file ids from TS 31.102
    public static final int EF_PBR = 0x4F30;

    // GSM SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6
    static final int EF_MAILBOX_CPHS = 0x6F17;
    static final int EF_VOICE_MAIL_INDICATOR_CPHS = 0x6F11;
    static final int EF_CFF_CPHS = 0x6F13;
    static final int EF_SPN_CPHS = 0x6f14;
    static final int EF_SPN_SHORT_CPHS = 0x6f18;
    static final int EF_INFO_CPHS = 0x6f16;
    static final int EF_CSP_CPHS = 0x6f15;

    // CDMA RUIM file ids from 3GPP2 C.S0023-0
    static final int EF_CST = 0x6f32;
    static final int EF_RUIM_SPN =0x6F41;

    // SMS record length from TS 51.011 10.5.3
    static public final int SMS_RECORD_LENGTH = 176;

    static final String MF_SIM = "3F00";
    static final String DF_TELECOM = "7F10";
    static final String DF_PHONEBOOK = "5F3A";
    static final String DF_GRAPHICS = "5F50";
    static final String DF_GSM = "7F20";
    static final String DF_CDMA = "7F25";
   
   // ----------------------------------------------------------------------
       
   // -------------------------- other variables ---------------------------
   
    String stringaDiProva;
   

   
    TextView prova;
   
    Class phoneBase;
   
    Object defaultPhone;
   
    Class adnRecordLoader;
   
    Object adnInstance;
   
    Class phoneFactory;
   
    Method phoneBuilder;
   
        Constructor adnConstructor;
       
        Method loadEF;
       
        workerThread threadLavoratore;
       
        boolean finished = false;
       
        int messaggiDaElaborare = 0;
   
   
   
       
        /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
       
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
   
        stringaDiProva = "";
       
        prova = (TextView) findViewById(R.id.view1);
       
       
        try {
                        phoneBase = Class.forName("com.android.internal.telephony.PhoneBase");
                       
                        phoneFactory = Class.forName("com.android.internal.telephony.PhoneFactory");
                       
                        adnRecordLoader = Class.forName("com.android.internal.telephony.AdnRecordLoader");
                       
                        stringaDiProva += "Ricerca classi completata con successo\n";
                //---------------------------------------------------------------------------------------------
   
                       
                        Message risposta = Message.obtain();
                       
                       
                       
                        stringaDiProva += "Inizio Thread\n";
                       
                       
                        startWork();
                       

       
       
       
        } catch (ClassNotFoundException e) {
                        // TODO Auto-generated catch block
                        stringaDiProva += e + "\n";
                e.printStackTrace();
                }
   
    }

   
   public void startWork()
   
   {
           
          try {
           
           
           if (threadLavoratore == null)
                   threadLavoratore = new workerThread();
           
           threadLavoratore.start();
           
           boolean running = true;
           
           while (running) {
           
           
           if (threadLavoratore.workerHandler == null) {

                        try {
                                Thread.sleep(400);
                        } catch (InterruptedException ie) {
                        }
                        continue;
               
           }
           
           if (threadLavoratore != null && messaggiDaElaborare == 0)
           {
                   
                   messaggiDaElaborare++;
                   
                   Message risposta = threadLavoratore.workerHandler.obtainMessage();
                   
                   threadLavoratore.workerHandler.sendMessage(risposta);
                   
                   
                   if (finished == false)
                           
                   {
                   
                   try {
                                Thread.sleep(400);
                        } catch (InterruptedException ie) {
                        }
                        continue;
                   
                   }
           
                   running = false;
                   
                   threadLavoratore.stop();
                   
                   threadLavoratore = null;
           
           }
           
           
           
           
           
           }
           

           
   } catch (RuntimeException e) { prova.setText(e.toString()); }
           
           
           
   }
   

   
    public class workerThread extends Thread {
       
      public Handler workerHandler;
     
       
        public void run() {
                        Looper.prepare();
                       
                        stringaDiProva += "Thread in esecuzione\n";
                       
                        try {
                                                phoneBuilder = phoneFactory.getMethod("getDefaultPhone", null);
                                       
                                                Log.i("PROGRESSO", "-------------------FASE 1 COMPLETATA---------------");
                                               
                                               
                                       
                                        } catch (SecurityException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                                Log.e("-------ERRORE------", e.toString());
                                        } catch (NoSuchMethodException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                                Log.e("-------ERRORE--------", e.toString());
                                        }
                               
                               

                               
                                                workerHandler = new Handler() {
                                      public void handleMessage(Message msg) {

                                          try {
                                                               
                                                  Log.i("PROGRESSO", "-------------------HANDLER IN ESECUZIONE---------------");         
                                                 
                                                 
                                                 
                                               
                                                 
                                                  //*********************************************************************************************
                                                  //------------------------- QUI HO L'ERRORE ---------------------------------------------------
                                                 
                                                 
                                                 defaultPhone = phoneBuilder.invoke(null);
                                                       

                                                //-----------------------------------------------------------------------------------------------
                                                //***********************************************************************************************
                                                 
                                                                adnConstructor = adnRecordLoader.getConstructor(phoneBase);
                                                               
                                                               
                                                                Log.i("PROGRESSO", "-------------------INIZIO FASE FINALE---------------");    
                                               

                                                                adnInstance = adnConstructor.newInstance(defaultPhone);
                                                                       
                                                                       
                                                                       
                                                                       
                                                                        Class[] paramType = new Class[3];
                                                                       
                                                                        paramType[0] = Integer.class;
                                                                        paramType[1] = Integer.class;
                                                                        paramType[2] = Message.class;
                                                               
                                                                       
                                                                        loadEF = adnRecordLoader.getMethod("loadAllFromEF", paramType);
                                                                               
                                                               
                                                                Object[] param = new Object[3];
                                                               
                                                                param[0] = EF_MSISDN;
                                                                param[1] = EF_EXT1;
                                                                param[2] = msg;
                                                               
                                                                Log.i("AVVISO", "---------------FASE FINALE----------------");

                                                                        loadEF.invoke(adnInstance, param);
                                                               

                                                                prova.setText("Fine: " + msg.obj.toString());
                                                               
                                                                finished = true;
                                     
                                          } catch (IllegalArgumentException e) {
                                                                        // TODO Auto-generated catch block
                                                                        e.printStackTrace();
                                                                        Log.e("--ERRORE--", e.toString());
                                                                        finished = true;       
                                                                } catch (IllegalAccessException e) {
                                                                        // TODO Auto-generated catch block
                                                                        e.printStackTrace();
                                                                        Log.e("--ERRORE--", e.toString());
                                                                        finished = true;                                                               
                                                                        } catch (InvocationTargetException e) {

                                                                                e.printStackTrace();
                                                                                Log.e("--ERRORE--", e.getCause().toString());
                                                                                finished = true;       
                                                                               
                                                                } catch (SecurityException e) {
                                                                        // TODO Auto-generated catch block
                                                                        e.printStackTrace();
                                                                        Log.e("--ERRORE--", e.toString());
                                                                        finished = true;                                                               
                                                                        } catch (NoSuchMethodException e) {

                                                                } catch (InstantiationException e) {
                                                                        // TODO Auto-generated catch block
                                                                        e.printStackTrace();
                                                                        Log.e("--ERRORE--", e.toString());
                                                                        finished = true;                                                                               
                                                                        } catch (RuntimeException e) {
                                                                       
                                                                                e.printStackTrace();
                                                                                Log.e("--ERRORE--", e.toString());
                                                                                finished = true;                }

                                     
                                     
                                     
                                      }
                                  };


                                        //---------------------------------------------------------
                                  Looper.loop();

                }
       
     }



}

In breve per ottenere un'instanza di AdnRecordLoader ho bisogno prima di un'istanza di PhoneBase. In teoria l'unico strumento che mi viene in aiuto è la PhoneFactory. Il problema che quando nell'handler effettuo la chiamata "PhoneFactory.getDefaultPhone()" il programma termina con l'errore Runtime: "PhoneFactory.getDefaultPhone() must be called by Looper Thread". C'è da dire che non sono molto afferrato in queste cose, tuttavia non capisco il senso di questo errore considerando che io il metodo l'ho lanciato proprio all'interno in teoria di un Looper Thread.

Il manifest ha i seguenti permessi:
android.permission.READ_PHONE_STATE
android.permission.READ_CONTACTS
android.permission.MODIFY_PHONE_STATE
android.permission.HARDWARE_TEST
android.permission.WRITE_PHONE_STATE

Qualcuno sa dirmi dove sto sbagliando (perdonate il disordine del codice) ?? Io proprio non capisco.

Grazie in anticipo per le vostre eventuali risposte :)

« Ultima modifica: 01 Dicembre 2010, 19:03:42 CET da RandomMan »

Offline RandomMan

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Acer Liquid E
  • Sistema operativo:
    Microsoft Windows XP
Re:Problema con utilizzo della classe AdnRecordLoader
« Risposta #1 il: 01 Dicembre 2010, 19:10:18 CET »
0
Ho in parte risolto il problema:

Ho cambiato "getDefaultPhone" in "getGsmPhone". In più prima di invocare il metodo in questione ho aggiunto la chiamata ad un altro metodo di PhoneFactory : "makeDefaultPhone" (essenziale a quanto pare). Dunque ora il codice "va avanti" ma mi si blocca alla riga


            loadEF = adnRecordLoader.getMethod("loadAllFromEF", paramType);


in cui praticamente cerco di prelevare il metodo "loadAllFromEF" dalla classe AdnRecordLoader.

Mi viene lanciata questa eccezione:

Codice: [Seleziona]
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.provider.Telephony.SPN_STRINGS_UPDATED from pid=319, uid=10038

C'è modo di fare qualcosa?


Offline RandomMan

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Acer Liquid E
  • Sistema operativo:
    Microsoft Windows XP
Re:Problema con utilizzo della classe AdnRecordLoader
« Risposta #2 il: 13 Dicembre 2010, 13:04:17 CET »
0
Facendo delle prove ho scoperto che la causa dell'eccezione in questione è la chiamata al metodo "makeDefaultPhone()" della classe PhoneFactory, evidentemente è un metodo in qualche modo protetto. Cambio quindi domanda: c'è un modo per ottenere un'istanza della classe GSMPhone dall'SDK senza incappare in errori di Sicurezza?

Offline alexAndroid

  • Utente normale
  • ***
  • Post: 185
  • Respect: +27
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Giò
  • Sistema operativo:
    Ubuntu 11.10; Windows XP
Re:Problema con utilizzo della classe AdnRecordLoader
« Risposta #3 il: 20 Novembre 2011, 11:27:21 CET »
0
Ciao RandomMan,
sto leggendo per la prima volta questo tuo post. Sono interessato all'argomento che stai trattando.
Hai effettuato qualche progresso a riguardo?

Saluti
Sei stato aiutato oppure il tuo problema è stato risolto? Allora premi il tasto THANKS E' un modo utile e carino per ringraziare chi ti è stato di aiuto.