2014-04-30 91 views
9

我試圖從Google Play服務API獲取廣告ID。下面是一個示例代碼:AdvertisingIdClient getAdvertisingIdInfo永遠掛起

... 
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(); 
      } 
     } 
    } 
} 

當我打電話getAdvertisingIdInfo方法,應用程序掛起永遠(不管用調試器或不)。

我使用Windows ADT 22.3,Android SDK API 19,Google Play SDK rev。 16,Android 4.4.2 Nexus設備。我正在整合API,如下所述:https://developer.android.com/google/play-services/id.html

可能是什麼原因?

回答

10

我找到了原因。它不應該阻止onStart()處理程序,因爲阻止的上下文會阻止Play API在ID設置中獲取。固定代碼如下所示:

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

如果官方說明有這樣的用法註釋將會有所幫助。

+2

我同意,谷歌的這個例子代碼就是這麼差! –

+0

當我按照他們的文檔,我得到一個很好的phat lint錯誤'無法到達GooglePlayServicesAvailabilityException的catch塊。這個異常永遠不會從try語句體中拋出。在我的一個Windows開發人員的生活中,微軟至少記錄下他們的東西 - 並允許對這些文檔提供反饋! FFS –

+0

或更好的,使用AsyncTask。 – RominaV

1

不幸的是,getAdvertisingIdInfo調用需要從後臺線程完成,在調用它的時候不應該阻塞主線程。似乎沒有選項可以同步獲取AdId。

----編輯----

我可以通過運行一個新的線程來實現這一點。這是最後爲我工作的東西。它不再掛(可能不是一個理想的)

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

}