I'm trying to suppress an error with RX plugin, but the app is still crashing. Am I doing anything wrong or plugin error handler is just for reporting and cannot prevent the crash?
public void testClick(View view) {
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
#Override
public void handleError(Throwable e) {
e.printStackTrace();
}
});
final PublishSubject<Integer> hot = PublishSubject.create();
hot
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Integer>() {
#Override
public void call(Integer value) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("Result");
}
});
Observable.range(0, 100).subscribe(hot);
}
If you look at _onError method in SafeSubscriber class you'll find :
try {
RxJavaPlugins.getInstance().getErrorHandler().handleError(e);
} catch (Throwable pluginException) {
handlePluginException(pluginException);
}
try {
actual.onError(e);
} catch {
...
}
You can see that RxJavaPlugins ErrorHandler doesn't affect further error processing and it should be used to log/report errors
I want to get users Advertising ID programmatically.I used the below code from the developer site.But its not working
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (IOException e) {
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
} catch (GooglePlayServicesNotAvailableException e) {
// Google Play services is not available entirely.
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final String id = adInfo.getId();
final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
How can I get user's advertising id programmatically ?? please help me
I might be late but this might help someone else!
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
AdvertisingIdClient.Info idInfo = null;
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String advertId = null;
try{
advertId = idInfo.getId();
}catch (NullPointerException e){
e.printStackTrace();
}
return advertId;
}
#Override
protected void onPostExecute(String advertId) {
Toast.makeText(getApplicationContext(), advertId, Toast.LENGTH_SHORT).show();
}
};
task.execute();
Get GAID(Google’s advertising ID)
1. Download latest Google Play Services SDK.
2. Import the code and add it as a library project.
3. Modify AndroidManifest.xml.
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
4. Enable ProGuard to shrink and obfuscate your code in project.properties this line
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
5. Add rules in proguard-project.txt.
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents(); }
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL; }
-keepnames #com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
#com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
6. Call AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext()).getId() in a worker thread to get the id in String.
as like this
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
AdvertisingIdClient.Info idInfo = null;
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
String advertId = null;
try{
advertId = idInfo.getId();
}catch (Exception e){
e.printStackTrace();
}
return advertId;
}
#Override
protected void onPostExecute(String advertId) {
Toast.makeText(getApplicationContext(), advertId, Toast.LENGTH_SHORT).show();
}
};
task.execute();
Enjoy!
or
https://developervisits.wordpress.com/2016/09/09/android-2/
You can call the below function in onCreate(Bundle savedInstanceState) of the activity
and in the logcat search for UIDMY then it will display the id like : I/UIDMY: a1cf5t4e-9eb2-4342-b9dc-10cx1ad1abe1
void getUIDs()
{
AsyncTask.execute(new Runnable() {
#Override
public void run() {
try {
AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(SplashScreen.this);
String myId = adInfo != null ? adInfo.getId() : null;
Log.i("UIDMY", myId);
} catch (Exception e) {
Toast toast = Toast.makeText(context, "error occurred ", Toast.LENGTH_SHORT);
toast.setGravity(gravity, 0,0);
toast.show();
}
}
});
}
Just in case someone is interested in trying out the fetching AdvertisingId part while Rx-ing then this might be helpful.
private void fetchAndDoSomethingWithAdId() {
Observable.fromCallable(new Callable<String>() {
#Override
public String call() throws Exception {
return AdvertisingIdClient.getAdvertisingIdInfo(context).getId();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
#Override
public void call(String id) {
//do what you want to do with id for e.g using it for tracking
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});
}
The modern way is to use Coroutines in Kotlin, since AsyncTask is now being deprecated for Android. Here is how I did it:
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class AdvertisingInfo(val context: Context) {
private val adInfo = AdvertisingIdClient(context.applicationContext)
suspend fun getAdvertisingId(): String =
withContext(Dispatchers.IO) {
//Connect with start(), disconnect with finish()
adInfo.start()
val adIdInfo = adInfo.info
adInfo.finish()
adIdInfo.id
}
}
When you are ready to use the advertising ID, you need to call another suspending function:
suspend fun applyDeviceId(context: Context) {
val advertisingInfo = AdvertisingInfo(context)
// Here is the suspending function call,
// in this case I'm assigning it to a static object
MyStaticObject.adId = advertisingInfo.getAdvertisingId()
}
Fetch the advertising id from background thread:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
try {
AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
String adId = adInfo != null ? adInfo.getId() : null;
// Use the advertising id
} catch (IOException | GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException exception) {
// Error handling if needed
}
}
});
I added null checks to prevent any crashes. The Google example implementation code would crash with a NullPointerException if an exception occures.
With OS validation.
Call this in an AsyncTask
/** Retrieve the Android Advertising Id
*
* The device must be KitKat (4.4)+
* This method must be invoked from a background thread.
*
* */
public static synchronized String getAdId (Context context) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
return null;
}
AdvertisingIdClient.Info idInfo = null;
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String advertId = null;
try{
advertId = idInfo.getId();
}catch (NullPointerException e){
e.printStackTrace();
}
return advertId;
}
If you are using Kotlin use this to get the Google Advertising ID of the device
CoroutineScope(Dispatchers.IO).launch {
var idInfo: AdvertisingIdClient.Info? = null
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(applicationContext)
} catch (e: GooglePlayServicesNotAvailableException) {
e.printStackTrace()
} catch (e: GooglePlayServicesRepairableException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
var advertId: String? = null
try {
advertId = idInfo!!.id
} catch (e: NullPointerException) {
e.printStackTrace()
}
Log.d(TAG, "onCreate:AD ID $advertId")
}
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException e) {
e.printStackTrace();
} catch (GooglePlayServicesAvailabilityException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
String AdId = adInfo.getId();
You need add gms libs otherwise you cannot get the advertising id. It can be reset by user or when you do a factory reset (at factory reset time the Android id also reset).
Make sure you have added play identity services, then you can get advertising id by running a thread like this:
Thread thread = new Thread() {
#Override
public void run() {
try {
AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
String advertisingId = adInfo != null ? adInfo.getId() : null;
} catch (IOException | GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException exception) {
exception.printStackTrace();
}
}
};
// call thread start for background process
thread.start();
You only need this package:
implementation("com.google.android.gms:play-services-ads-identifier:17.0.0")
It's not really listed anywhere but it's published on Mavne.
Get Google Services using
GoogleApiAvailabilityLight.getInstance
You need to run your code using Async Task
try this
Using the new Android Advertiser id inside an SDK
Using Kotlin & RxJava Observers
Import in your Gradle file
implementation 'com.google.android.gms:play-services-ads:15.0.0'
Import on top of your kotlin source file
import io.reactivex.Observable
import com.google.android.gms.ads.identifier.AdvertisingIdClient
Implement a helper function
private fun fetchAdIdAndThen(onNext : Consumer<String>, onError : Consumer<Throwable>) {
Observable.fromCallable(Callable<String> {
AdvertisingIdClient.getAdvertisingIdInfo(context).getId()
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onNext, onError);
}
Then
fetchAdIdAndThen(Consumer<String>() {
adId ->
performMyTaskWithADID(activity, 10000, adId);
}, Consumer<Throwable>() {
throwable ->
throwable.printStackTrace();
performMyTaskWithADID(activity, 10000, "NoADID");
})
I throw a exception with some message like:
public static ILSResponseEmailLookUPBO getILSUserAccounts(Resources res,
String email) throws TripLoggerCustomException,
TripLoggerUnexpectedErrorException {
String resp = null;
String lookupURL;
try {
lookupURL = TripLoggerConstants.ServerConstants.ILS_LOOKUP_URL
+ URLEncoder.encode(email, "UTF-8");
} catch (UnsupportedEncodingException e1) {
throw new TripLoggerCustomException(
res.getString(R.string.error_try_again));
}
try {
resp = ConnectionManager.getInstance().httpRequest(lookupURL,
TripLoggerConstants.RequestMethods.GET);
} catch (IOException e) {
if (e.getMessage().equals(
res.getString(R.string.network_unreachable))
|| e.getMessage().equals(
res.getString(R.string.host_unresolved))) {
throw new TripLoggerCustomException(
res.getString(R.string.network_not_reachable));
} else {
throw new TripLoggerCustomException(
res.getString(R.string.email_notfound_ils));
}
}
here my else part execute.
And my exception class is:
public class TripLoggerCustomException extends Exception {
private String customMessage;
private static final long serialVersionUID = 1L;
public TripLoggerCustomException() {
super();
}
public TripLoggerCustomException(String message) {
super(message);
this.customMessage = (message == null ? "" : message);
}
public String getCustomMessage() {
return this.customMessage;
}
public void setCustomMessage(String customMessage) {
this.customMessage = customMessage;
}
}
And here i catch this exception:
private void manageLookUpActions(final String emailID) {
new Thread() {
public void run() {
try {
listILSAccounts = ILSLookupEmailBL.getILSUserAccounts(
getResources(), emailID);
} catch (TripLoggerCustomException e) {
dismissProgressBar();
handleException(e.getMessage());
return;
} catch (TripLoggerUnexpectedErrorException e) {
dismissProgressBar();
handleException(e.getMessage());
return;
}
}
}.start();
}
but here in catch of TripLoggerCustomException e is null.why?Can anyone help me?
After looking into multiple reports on StackOverflow, it seems like this is not an actual issue. Multiple people have been saying that it is a problem in the combination of the Eclipse debugger and the Android Emulator. That is why you don't get a NullPointerException, which you would definitely get if e was null.
So this is probably not an issue you have to worry about.
I am using ormLite to store data on device.
I can not understand why but when I store about 100 objects some of them stores too long time, up to second.
Here is the code
from DatabaseManager:
public class DatabaseManager
public void addSomeObject(SomeObject object) {
try {
getHelper().getSomeObjectDao().create(object);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
public Dao<SomeObject, Integer> getSomeObjectDao() {
if (null == someObjectDao) {
try {
someObjectDao = getDao(SomeObject.class);
} catch (Exception e) {
e.printStackTrace();
}
}
return someObjectDao;
}
Any ideas to avoid this situations?
Thanks to Gray!
Solution is, as mentioned Gray, using callBatchTasks method:
public void updateListOfObjects (final List <Object> list) {
try {
getHelper().getObjectDao().callBatchTasks(new Callable<Object> (){
#Override
public Object call() throws Exception {
for (Object obj : list){
getHelper().getObjectDao().createOrUpdate(obj);
}
return null;
}
});
} catch (Exception e) {
Log.d(TAG, "updateListOfObjects. Exception " + e.toString());
}
}
Using this way, my objects (two types of objects, 1st type - about 100 items, 2nd type - about 150 items) store in 1.7 sec.
See the ORMLite documentation.
I'm having trouble handling an exception called by a method. What I'm trying to do is create an alert dialog whenever an exception is caught (I know how to create the alert dialog). The method throwing the exception is in a different class, which is why I can't create an alert dialog when the exception is caught. See below:-
protected Boolean doInBackground(final String... args) {
try{
ParserLive parser = new ParserLive();
feeds = parser.parse(); // this is the method throwing the exception
return true; //won't return true because it gets stuck here
} catch (Throwable t){
return false;
}
}
Below is the ParserLive class where the method is:-
public class ParserLive {
//variables and constructor
//Below is the method I want to handle
//Ideally I'd like to wrap the code inside this method with a try-catch,
//and put the dialog in the catch statement, but this is not allowed.
public List<Feed> parse() {
//some code
// the following code is throwing the error, when I try to create an alert dialog inside this catch statement it says "the constructor AlertDialog.Builder(ParserLive) is undefined"
try {
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
return feeds;
}
}
EDIT
I've edited the above code to include the line of code throwing the following error in LogCat - " java.lang.RuntimeException: org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: no element found
"
protected Boolean doInBackground(final String... args) {
try{
ParserLive parser = new ParserLive();
feeds = parser.parse();
return true;
} catch (Exception e){
log.d("Error", e.getMessage());
yourActivity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(context, e.getMessage(), 3000).show(); }
});
//Here you can create dialog also
return false;
}
}