I'm trying to wait the response of AdvertisingIdClient.getAdvertisingIdInfo(activity) without success. This method never response until the main thread has finished.
import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesUtil;
import java.io.IOException;
public class MyActivity extends Activity {
private Activity m_activity = null;
private AdvertisingIdClient.Info m_info = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// start the thread with the getAdvertisingIdInfo()
startGoogleAdvertisingIdRequest(this);
// simulate a waiting loop, others app init, ...
for (int i=0; i<20; i++) {
SystemClock.sleep(100);
}
// get the uuid
String uuid = getGoogleAdvertisingId();
// call a method who need the uuid
Log.i("UUID", "receive uuid: " + uuid);
}
public String getGoogleAdvertisingId() {
String uuid = null;
if (m_info != null) {
if (!m_info.isLimitAdTrackingEnabled()) {
uuid = m_info.getId();
} else {
uuid = "another uuid";
}
} else {
uuid = "another uuid";
}
return uuid;
}
public void startGoogleAdvertisingIdRequest(final Activity activity) {
m_activity = activity;
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(activity) == ConnectionResult.SUCCESS) {
new Thread(new Runnable() {
@Override
public void run() {
AdvertisingIdClient.Info adInfo = null;
try {
Log.i("UUID", "before google request");
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(activity);
Log.i("UUID", "after google request");
} catch (IOException e) {
Log.w("UUID", "getAdvertisingIdInfo IOException: " + e.getMessage());
} catch (GooglePlayServicesNotAvailableException e) {
Log.w("UUID", "GooglePlayServicesNotAvailableException: " + e.getMessage());
} catch (Exception e) {
Log.w("UUID", "GooglePlayServicesException: " + e.getMessage());
} finally {
finished(adInfo);
}
}
}).start();
}
}
private void finished(final AdvertisingIdClient.Info adInfo){
if(adInfo != null){
m_activity.runOnUiThread(new Runnable() {
@Override
public void run() {
m_info = adInfo;
Log.i("UUID", "runOnUiThread id: " + adInfo.getId());
}
});
}
}
}
Logcat of this code
11:29:52.103 30810-30828/com.example.testuuid I/UUID﹕ before google request
11:29:54.107 30810-30810/com.example.testuuid I/UUID﹕ receive uuid: another uuid
11:29:54.127 30810-30828/com.example.testuuid I/UUID﹕ after google request
11:29:54.151 30810-30810/com.example.testuuid I/UUID﹕ runOnUiThread id: d5dc3bfb-4756-490c-8f8e-2bedfb5e827a
Same logcat with more waiting time (5s)
11:36:14.215 31413-31436/com.example.testuuid I/UUID﹕ before google request
11:36:19.225 31413-31413/com.example.testuuid I/UUID﹕ receive uuid: another uuid
11:36:19.293 31413-31436/com.example.testuuid I/UUID﹕ after google request
11:36:19.315 31413-31413/com.example.testuuid I/UUID﹕ runOnUiThread id: d5dc3bfb-4756-490c-8f8e-2bedfb5e827a
Each time the getAdvertisingIdInfo(), who is in another thread, is blocked by the main thread.
What is the reason ? and how to do this ?
To get the google ad ID you need not to run the method getAdvertisingIdInfo
on the main thread.
I use Async Task to manage the extraction of the google ad ID.
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
String GAID; // this is the String of the Google Ad ID that you'll receive upon onPostExecute
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetGAIDTask().execute();
}
private class GetGAIDTask extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... strings) {
AdvertisingIdClient.Info adInfo;
adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(MainActivity.this.getApplicationContext());
if (adInfo.isLimitAdTrackingEnabled()) // check if user has opted out of tracking
return "did not found GAID... sorry";
} catch (IOException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
}
return adInfo.getId();
}
@Override
protected void onPostExecute(String s) {
GAID = s;
}
}
You also need to add to the app build.gradle on the dependencies the line
compile 'com.google.android.gms:play-services-ads:7.8.0'
And be sure you have on the Android SDK manager the "EXTRAS Google Repository" updated
The issue you are seeing, where no amount of time seems long enough for the getAdvertisingIdInfo call to complete, is caused by how you are waiting and how runOnUiThread works. The key is that runOnUiThread will queue the code to be run after what is currently running on the ui thread, in this case the onCreate. The sleep calls used to "simulate waiting" will let your background thread run and do its work, but the final operation to set m_info will always be queued and executed after onCreate completes.
One solution would be to ensure that m_info is safe to access from multiple threads and simply assign it on the background thread. There would be no need for runOnUiThread. This would remove queuing, and allow your code to work with minimal changes.
A better solution would be to keep the use of runOnUiThread and remove the sleep used to wait. You would need to keep in mind that m_info will always be null in onCreate, but other events can check if the value is non null and use it as needed.
https://developer.android.com/reference/android/app/Activity#runOnUiThread(java.lang.Runnable)
Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With