I've got the following crash in GameHelper.java:
[main] java.lang.NullPointerException at
com.google.android.gms.common.ConnectionResult.startResolutionForResult(Unknown
Source) at
com.google.example.games.basegameutils.GameHelper.resolveConnectionResult(GameHelper.java:752)
at
com.google.example.games.basegameutils.GameHelper.onConnectionFailed(GameHelper.java:729)
The only reason I think that could happen is if mActivity == null at GameHelper.java:752:
mConnectionResult.startResolutionForResult(mActivity, RC_RESOLVE);
mActivity gets null on onStop()
Is it possible that GameHelper.java has bug and can crash if onConnectionFailed() happens after onStop() is called?
Thanks.
EDITED:
It happened after update to the latest Play API (rev 15) together with the updated GameHelper.java.
EDIT:
This now has been fixed in latest GameHelper version:
https://github.com/playgameservices/android-samples/commit/e7b3758c136b5b434f1dfd9ca8c03f75aad70f09
OLD ANSWER:
For me it happens on the start of the app, when Google Play Services asks me to sign in and if I click cancel, this same error happens.
So when leaving from your own activity to sign in activity, it dispatches onStop event, and fails to connect because of the user initiated process, which is resolvable, thus the error happens.
So my quick hack was changing:
catch (SendIntentException e)
to simply
catch (Exception e)
So it would also catch Null pointer exception
Of course in this case the signup process might not proceed, so I initate relogin on another action and it seems to work for now.
More thorough hack could be trying to resolve the result on activity start, for that we define pending resolution variable:
// Are we expecting the result of a resolution flow?
boolean mExpectingResolution = false;
boolean mPendingResolution = false;
Then on the error line we check if activity is not null
if(mActivity != null)
mConnectionResult.startResolutionForResult(mActivity, RC_RESOLVE);
else
mPendingResolution = true;
And on start we check and try to resolve it:
if(mPendingResolution && mConnectionResult != null)
try {
mConnectionResult.startResolutionForResult(mActivity, RC_RESOLVE);
} catch (SendIntentException e) {
e.printStackTrace();
}
This should help until the official resolution from lib supporters :)
Today is 16th september 2014 and I still facing this problem.
I don't know why anyone else did not answer about to comment GameHelper line.
In onStop method there is a line to set mActivity variable as null.
I commented this line (like below) and my app is working properly.
/** Call this method from your Activity's onStop(). */
public void onStop() {
debugLog("onStop");
assertConfigured("onStop");
if (mGoogleApiClient.isConnected()) {
debugLog("Disconnecting client due to onStop");
mGoogleApiClient.disconnect();
} else {
debugLog("Client already disconnected when we got onStop.");
}
mConnecting = false;
mExpectingResolution = false;
// let go of the Activity reference
//mActivity = null; //COMMENT THIS LINE!!!!
//COMMENT ABOVE LINE
}
Is there any problem doing that:?
Related
Started to experiment with In-app updates. Everything seems to work prefect.
But... when entering some edge cases, like for example, canceling the process of update in the process of downloading the update, the API for some reason stops working as intended.
Example: I start my activity and the first thing in onResume(), I do this:
//In app update code. Only works for Android 5.0 and above.
if (Build.VERSION.SDK_INT >= 21) {
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(this);
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
try {
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.IMMEDIATE, this, 1333);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
// If an in-app update is already running, resume the update.
try {
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.IMMEDIATE,this, 1333);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
}
When I click on Update button and the screen for updating appears, I immediately cancel the update. It returns with onActivityResult the request code (1333) and result code (STATUS_UNKNOWN = 0) . I call finish() in that if statement, because this is a critical update that has to be updated.
The problem is now, when entering the app for the second time, onActivityResult is fired again, without showing any dialog from in-app update API and just returning the request/result code in onActivityResult callback.
Anyone with a similar problem?
looks like there is open bug for the same issue. https://issuetracker.google.com/issues/133092990 . As per comment its Play-store issue and will be released in next few weeks.
We are using crashlyticsDidDetectCrashDuringPreviousExecution to detect java crashes and report them to our BI systems, but our app is mostly C++ and we are using crashlytics NDK, we can't find anything similar to crashlyticsDidDetectCrashDuringPreviousExecution.
Is there any way that we can actually detect an NDK crash when the app starts?
thanks
Oded
Mike from Fabric here.
Currently, there isn't a way to do this within Fabric or the SDK for an NDK crash.
NOTE: This works on older version only (Crashlytics 2.6.7 and CrashlyticsNDK 1.1.6)
I'm also looking for a solution for this.
We currently found a partial solution. I'm not sure how good it is, it's definitely not official, plus it's asynchronic (which we're trying to overcome by looping), but it's the best solution I found and it seems like it's working
Fabric.with(this, new Crashlytics.Builder().core(core.build()).build(), new CrashlyticsNdk(), new Crashlytics());
if (!userLeft) { // our handling to fix bug, see explanation below
new Thread(new Runnable() {
#Override
public void run() {
SessionEventData crashEventData = null;
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000); // in ms
} catch (InterruptedException e) { }
crashEventData = CrashlyticsNdk.getInstance().getCrashEventData();
if (crashEventData != null)
{
// there was a crash!
// crash timestamp can be found at crashEventData.timestamp
break;
}
}
}
}).start();
}
Explaination for userLeft:
We had some bug with reporting crash for users that exited app, and this is the solution for that. We set this flag to true, and save it on the device (SharedPreferences). We do it on our main activity (which extends NativeActivity), on finish() func.
Code:
#Override
public void finish() {
// set some key such as USER_LEFT to TRUE
super.finish();
}
After that, just get that USER_LEFT value, assign it into userLeft param, and set it back to false on SharedPerferences.
Any insights about this solution?
I'm building a DPC (Device Policy Controller), and one of the issues I'm seeing is that while the Play Store and Play Services are being updated, the Google Contact Sync service crashes -- leaving the typical crash dialog on the screen. Since part of the idea of the initial set up process is to have as little user interaction as possible, how can I dismiss this dialog programmatically (since I seem to be pretty much guaranteed that this will happen)?
I've tried dismissing system dialogs...
ctx.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
... but that doesn't seem to do the trick.
Since this is a DPC, anything that requires device ownership/administration is fine.
edit: Usually I have no UI on screen at the time, so if one is necessary please do mention it. Also, preferably the solution should work on at least 6.0+, if not 4.0+.
Try to do it onWindowsFocusChanged method like this for example :
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
Intent ctx= new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(ctx);
}
}
I'm not sure about app crash Dialog but maybe it'll help you
AppErrorDialog can be dismissed by broadcasting ACTION_CLOSE_SYSTEM_DIALOGS if Android version is N.
ctx.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
However, AppErrorDialog won't be displayed if phone is locked.
public boolean canShowErrorDialogs() {
return mShowDialogs && !mSleeping && !mShuttingDown
&& mLockScreenShown != LOCK_SCREEN_SHOWN;
} // ActivityManagerService
Please try this code.
try {
Class ActivityManagerNative = Class.forName("android.app.ActivityManagerNative");
Class IActivityManager = Class.forName("android.app.IActivityManager");
Method getDefault = ActivityManagerNative.getMethod("getDefault", null);
Object am = IActivityManager.cast(getDefault.invoke(ActivityManagerNative, null));
Method closeSystemDialogs = am.getClass().getMethod("closeSystemDialogs", String.class);
closeSystemDialogs.invoke(am, "DPC close");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
I'm getting exception reports of DeadObjectException from some devices when requesting prices for in app purchases. The exception occurs when I call getSkuDetails on my billing service connection.
I don't find the documentation on this particularly clear.
The object you are calling has died, because its hosting process no longer exists.
Am I understanding this correctly if I assume that the billing service has been killed by Android for some reason?
Why?
Is there a way to stop this from happening?
Should I stop this from happening?
How should I deal with the exception?
Is there a way I can reproduce this scenario for testing?
I have two methods
void bindToBillingService() {
AndroidLauncher.getActivity().bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"),
mServiceConn, Context.BIND_AUTO_CREATE);
}
public void unbindBillingService() {
if (getBillingServiceConnection() != null) {
AndroidLauncher.getActivity().unbindService(mServiceConn);
}
}
Should I be doing something like this?
try {
// Do something billing related
} catch (DeadObjectException e) {
unbindBillingService();
bindToBillingService();
// Wait for a connection and then try again
}
I have some code that connects my app to Facebook. When you log in you proceed to the next activity. If you are already logged in when you start the app you miss out the log in section. On the following page I want to be able to log out, every time I press logout I get a null pointer. Can anyone help?
My code for log out is:
private void logout() {
try {
facebookConnector.getFacebook().logout(getApplicationContext());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The code that is run when the app is started to check if the person has logged on is:
if (facebookConnector.getFacebook().isSessionValid()) {
Intent i = new Intent(facebook.this, facebook2.class);
startActivity(i);
finish();
}
A print screen of my error can be seen here:
Any help would be great. If you need more info please comment and I will provide asap.
facebookConnector.getFacebook() seems to return null