Android Background Runnable not working on older devices - android

I have the following running at startup inside of an IntentService
threadManager.postBackgroundRunnableDelayed(() -> {
try {
// Calling getToken and getId must be on separate thread. Otherwise, it blocks UI thread.
String token = instanceID.getToken(SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE);
String id = instanceID.getId();
Timber.d("id: " + id);
Timber.d("token: " + token);
lazyRestQueue.get().sendGcmToken(new GcmPushRequest(id, token), getSendGcmTokenCallback());
setupAnalytics(token);
} catch (IOException e) {
Timber.e(e, "Exception during registration");
Crashlytics.logException(e);
setHasToken(false);
} catch (RuntimeException e) {
// This will be thrown if Localytics was not properly setup
Timber.e(e, "Exception during registration");
}
});
When I run it on anything below API 18 it causes the app to close (not crash oddly, just close)
can someone give me advice on this? I know it probably has to do with the service or something not timing properly

Related

Ad SDKs can't seem to get the Advertising info from the device

This is what we see from Mopub and other ad networks:
java.io.IOException: Connection failure
com.google.android.gms.ads.identifier.AdvertisingIdClient.g(Unknown
Source)
com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(Unknown
Source)
They all seem to have the same problem.
The weird thing is that we have no problem getting the advertising id from our app whatsoever with the following source. We get the right advertising id and we have no error logs.
All the SDKs are hitting the same issue (Connection failure).
Any help appreciated.
private void getAdvertisingId(AdvertisingIdHolder receiver) {
AdvertisingIdClient.Info adInfo = null;
String id = null;
boolean isLAT = false;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(App.getCtx());
id = adInfo.getId();
isLAT = adInfo.isLimitAdTrackingEnabled();
} catch (IOException e) {
SLog.e("error", e);
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
} catch (GooglePlayServicesNotAvailableException e) {
SLog.e("error", e);
// Google Play services is not available entirely.
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
}
receiver.receive(id, isLAT);
}
I went through trials and errors these days on getting advertising id. Finally I got it!
The connection error can be solved if we pass in getApplicationContext() instead of the context of current activity. Below is my working code:
private void getGaid() {
new Thread(new Runnable() {
#Override
public void run() {
try {
String gaid = AdvertisingIdClient.getAdvertisingIdInfo(
getApplicationContext()).getId();
if (gaid != null) {
Log.d("DEBUG", gaid);
// gaid get!
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
}
}).start();
}
getGaid() can be put in onCreate(), onResume(), or onClick() of a view, as long as the thread is called by the main ui thread.
Another thing you may need is to update google play services library to latest version. As the official document here mentioned, IOException is probably caused because the old version of the service doesn't support getting AdvertisingId.
Feel free to comment if there is any other questions.

How to get google access token after successfull login?

I need to get access token from Google after successful login.I used below code but I'm getting this error([ERROR] IO Exception: java.io.IOException: NetworkError). Please can any one help me.
try {
token = GoogleAuthUtil.getToken(
DoctorDetailsActivity.this, // Context context
accountName, // String accountName
"http://www.google.com/m8/feeds/"
);
} catch (IOException transientEx) {
// network or server error, the call is expected to succeed if you try again later.
// Don't attempt to call again immediately - the request is likely to
// fail, you'll hit quotas or back-off.
Log.e("getAccessToken()", "[ERROR] IOException: " + transientEx);
} catch (UserRecoverableAuthException e) {
// Recover
Log.e("getAccessToken()", "[ERROR] UserRecoverableAuthException: " + e);
} catch (GoogleAuthException authEx) {
// Failure. The call is not expected to ever succeed so it should not be
// retried.
Log.e("getAccessToken()", "[ERROR] GoogleAuthException: " + authEx);
} catch (Exception e) {
Log.e("getAccessToken()", "[ERROR] Exception: " + e);
throw new RuntimeException(e);
}

Google coordinate authentication

When I try to connect to Google coordinate, I always get an exception GoogleAuthException.
I have a Google Maps Coordinate license.
I did create my client Id in google console with my package application name and my SHA1.
I added the permissions to my manifest file:
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.NETWORK"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.INTERNET"/>
I use this code:
final String SCOPE = "oauth2:https://www.googleapis.com/auth/coordinate";
try {
mGoogleCoordinatetoken = GoogleAuthUtil.getToken(activity, email, SCOPE);
Log.e(getClass().getSimpleName(), "token ="+mGoogleCoordinatetoken);
} catch (GooglePlayServicesAvailabilityException playEx) {
Log.e(getClass().getSimpleName(), "GooglePlayServicesAvailabilityException "+playEx.getMessage());
} catch (UserRecoverableAuthException userAuthEx) {
// Start the user recoverable action using the intent returned by
// getIntent()
Log.e(getClass().getSimpleName(), "UserRecoverableAuthException "+userAuthEx.getMessage());
} catch (IOException transientEx) {
// network or server error, the call is expected to succeed if you try again later.
// Don't attempt to call again immediately - the request is likely to
// fail, you'll hit quotas or back-off.
Log.e(getClass().getSimpleName(), "IOException "+transientEx.getMessage());
} catch (GoogleAuthException authEx) {
// Failure. The call is not expected to ever succeed so it should not be
// retried.
Log.e(getClass().getSimpleName(), "GoogleAuthException "+authEx.getMessage());
}
Any idea how I can fix this exception?
Exception:
01-30 22:24:53.968: E/getAccessToken()(24800): [ERROR] GoogleAuthException: com.google.android.gms.auth.GoogleAuthException: Unknown
01-30 22:24:53.998: E/AccessTokenTask(24800): mGoogleCoordinatetoken =null
String WEB_APPLICATION_CLIENT_ID = "656631023202-9jsg9faqe87n1uo7f5g6iupti1jl2nps.apps.googleusercontent.com";
String scopes = String.format("audience:server:client_id:" + WEB_APPLICATION_CLIENT_ID );
Log.e(getClass().getSimpleName(), "email ="+email);
String code = null;
try {
code = GoogleAuthUtil.getToken(
LoginActivity.this, // Context context
email, // String accountName
scopes
);
mGoogleCoordinatetoken = code;
} catch (IOException transientEx) {
// network or server error, the call is expected to succeed if you try again later.
// Don't attempt to call again immediately - the request is likely to
// fail, you'll hit quotas or back-off.
Log.e("getAccessToken()", "[ERROR] IOException: " + transientEx);
} catch (UserRecoverableAuthException e) {
// Recover
Log.e("getAccessToken()", "[ERROR] UserRecoverableAuthException: " + e);
code = null;
} catch (GoogleAuthException authEx) {
// Failure. The call is not expected to ever succeed so it should not be
// retried.
Log.e("getAccessToken()", "[ERROR] GoogleAuthException: " + authEx);
} catch (Exception e) {
Log.e("getAccessToken()", "[ERROR] Exception: " + e);
throw new RuntimeException(e);
}
I had the exact same problem and resolved by modifying the scope to :
"oauth2:https://www.googleapis.com/auth/[API YOU WANT]"
(the beggining is very important !)
Hope it will help someone :)
The question is why do you need to get a token. As you commented in my question, you should be fine with GoogleAccountCredential object. Once you have the credential object, you can make calls to Google APIs
credential = GoogleAccountCredential.usingOAuth2(this, scopes);
if (TextUtils.isEmpty(appPreferences.getUserName()))
{
try
{
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(this, getString(R.string.gps_missing), Toast.LENGTH_LONG).show();
return;
}
}

Android 4.1 SQL server connection

I am working with android 4.1.1, IDE= eclipse, and SQL Server 2008.
Device= Note 2
android:minSdkVersion="10"
When I run the code snippet on the UI thread It gives me the error "Unable to get information from SQL Server:", but if I run the code in a background thread or AsyncTask Thread it works. Any help in understanding the two processes would be greatly appreciated?
Note: "The issue occurred when I upgrade the minSDKVersion from 8 to 10."
public Boolean open() {
Boolean res = false;
try {
String s = "jdbc:jtds:sqlserver://" + "xx.xxx.x.xx" + "/" + "FOO" + ";instance=SQLEXPRESS";
Class.forName("net.sourceforge.jtds.jdbc.Driver");
con = DriverManager.getConnection(s, "UserFoo", "1234");
res = true;
} catch (SQLException sx) {
Log.e(TAG, "DB:Open - " + sx.toString());
} catch (ClassNotFoundException e) {
Log.e(TAG, "DB:Open - " + e.toString());
}
return res;
}
Starting with Android 3.0, trying to access the network on the main (UI) thread results in:
NetworkOnMainThreadException
I'm guessing that you didn't see it because somewhere higher in your call stack you have:
catch (Exception)
which leads to:
"Unable to get information from SQL Server:"
As you have already discovered, a separate thread is the solution.

setPin() shows error in eclipse that "setPin() is undefined for BluetoothDevice"

I don't find many BluetoothDevice methodes such as , setPasskey(), setPin(), setPairingConfirmation(), setRemoteOutOfBandData().
I searched on Android site as well but I don't find it. When I use these methods in my program in eclipse it shows me an error: its undefined for the type BluetoothDevice.
Are these obsolete now? If yes then what are the new methods of same type.
It is assumed that paring process is performed only by applications delivered with a platform!
This means that this application have access to hidden API. For example you can find hidden API for Bluetooth here.
It is strongly recommended to not use hidden API since it can change without warning in next Android release.
If you are still planning to use this API safest way is to use reflection:
try {
Class<? extends BluetoothDevice> c = device.getClass(); // BluetoothDevice.class
Method createBond = c.getMethod("createBond");
Object result = createBond.invoke(device);
Boolean castedResult = (Boolean)result;
Log.d(TAG, "Result: " + castedResult.toString());
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
There is also alternative way to easy use hidden API, but I didn't try it.

Categories

Resources