2014-04-30 12 views
9

Sto cercando di ottenere ID pubblicità dall'API dei servizi di Google Play. Ecco un esempio di codice:AdvertisingIdClient getAdvertisingIdInfo si blocca per sempre

... 
import com.google.android.gms.ads.identifier.AdvertisingIdClient; 
import com.google.android.gms.common.GooglePlayServicesNotAvailableException; 
import com.google.android.gms.common.GooglePlayServicesRepairableException; 
... 

public class MyActivity extends Activity { 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     Thread thr = new Thread(new Runnable() { 
      @Override 
      public void run() { 
      try { 
       Context ctx = MyActivity.this.getApplicationContext(); 
       AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(ctx); 
      } catch (IllegalStateException e) { 
       e.printStackTrace(); 
      } catch (GooglePlayServicesRepairableException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (GooglePlayServicesNotAvailableException e) { 
       e.printStackTrace(); 
      } 
     }); 

     thr.start(); 
     synchronized (thr) { 
      try { 
       thr.join(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Quando sto chiamando il metodo getAdvertisingIdInfo, l'applicazione si blocca per sempre (non importa con debugger o meno).

Utilizzo Windows ADT 22.3, Android SDK API 19, Google Play SDK rev. 16, dispositivi Android 4.4.2 Nexus. Sto integrando API come descritto qui: https://developer.android.com/google/play-services/id.html

Quale potrebbe essere un motivo?

risposta

10

Ho trovato il motivo. Non dovrebbe bloccare il gestore onStart() perché blocchi di contesto bloccati riproducono l'API nelle impostazioni dell'ID che ottengono. Il codice risolto è il seguente:

@Override 
protected void onStart() { 
    super.onStart(); 
    Thread thr = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       Context ctx = MyActivity.this.getApplicationContext(); 
       AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(ctx); 
       finished(adInfo); 
      } catch (...) { 
       // All exceptions blocks 
      } 

      finished(null); 
     } 
    }); 

    thr.start(); 
} 

private void finished(final AdvertisingIdClient.Info adInfo){ 
    if(adInfo!=null){ 
     // In case you need to use adInfo in UI thread 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       // Do some stuff with adInfo 
      } 
     }); 
    } 
} 

Sarebbe utile se le istruzioni ufficiali avessero tali commenti di utilizzo.

+2

Sono d'accordo, il codice di esempio di Google su questo è piss povero! –

+0

e quando seguo il loro documento, ottengo un bel errore di filaccia di phat 'Blocco catch non raggiungibile per GooglePlayServicesAvailabilityException. Questa eccezione non viene mai generata dal corpo della dichiarazione try '. In tutta la mia vita di sviluppatore di Windows, Microsoft ha almeno documentato correttamente le loro cose e ha permesso di ottenere un feedback sui documenti! FFS –

+0

O meglio, usa un AsyncTask. – RominaV

1

Sfortunatamente la chiamata getAdvertisingIdInfo deve essere eseguita da un thread in background, non è necessario bloccare il thread principale durante il richiamo. Sembra che non ci sia alcuna opzione per ottenere l'AdID in modo sincrono.

---- ---- EDIT

ho potuto raggiungere questo obiettivo in esecuzione su un nuovo thread. Ecco cosa finalmente funziona per me. Non è più appeso (potrebbe non essere un ideale)

getGAIDSync(){ 
final CountDownLatch latch = new CountDownLatch(1); 
new Thread(new Runnable() { 
      @Override 
      public void run() {    
       getGoogleAdsIDAsyncTask.execute().get(5000, TimeUnit.MilliSecond); 
       latch.countDown();     
    }}).start(); 
    try { 
     latch.await(5000,TimeUnit.MILLISECONDS); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

}