I have a "save" button that will upload an image to parse. It used to work really well. But for some reason, it stops working.
When I press the button, nothing happens. As if the code ignored the onClick method. I thought something is wrong with the button or the other objects being saved. So I disabled every single object and found out it works fine when I disabled the image uploading.
So if I disable the image uploading, I can still save the name. But when I enable the image uploading, nothing happens and it feels like the onClick method is being ignored.
This is very weird. I haven't changed anything in my code and now it's not working. It used to work.
Do you guys have any idea what's wrong?
This is the updated code with logs:
protected Button mSavePet;
#Override
protected void onCreate(Bundle savedInstanceState) {
mSave = (Button) findViewById(R.id.Save);
mSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Log", "save button clicked");
myUploading();
}
});
}
private void myUploading() {
Log.d("Log", "myUploadig Start");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Compress image to lower quality scale 1 - 100
mBitmap.compress(Bitmap.CompressFormat.PNG, 3, stream);
byte[] image = stream.toByteArray();
ParseUser currentUser = ParseUser.getCurrentUser();
String currentUserUsername = currentUser.getUsername();
//get the new pet info
String petname = mPetName.getText().toString();
Log.d("Log", "puting objects start");
//Save Pet to the cloud
final ParseObject petObject = new ParseObject("MyPets");
petObject.put("petName", petname);
petObject.put("user", currentUserUsername);
// Create the ParseFile for Image
final ParseFile file = new ParseFile("petImage.png", image);
// Upload the image into Parse Cloud
file.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
Log.d("Log", "SaveFileInBackground Start");
if(e == null){
Log.d("Log", "Putting ImageFile Start");
// Create a column named "ImageFile" and insert the image
petObject.put("petImage", file);
// Create the class and the columns
petObject.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("Log", "putting objects finished");
finish();
} else {
}
}
});
}
}
});
}
}
This is the code output:
08-06 20:04:56.117 29376-29376/com.example.stanleysantoso.wikipetia D/Log﹕ save button clicked
08-06 20:04:56.129 29376-29376/com.example.stanleysantoso.wikipetia D/Log﹕ myUploadig Start
08-06 20:05:08.008 29376-29376/com.example.stanleysantoso.wikipetia D/Log﹕ puting objects start
08-06 20:07:06.986 29376-29376/com.example.stanleysantoso.wikipetia D/Log﹕ save button clicked
08-06 20:07:06.986 29376-29376/com.example.stanleysantoso.wikipetia D/Log﹕ myUploadig Start
08-06 20:07:16.972 29376-29376/com.example.stanleysantoso.wikipetia D/Log﹕ puting objects start
so, it never went in file.saveInBackGround.
you're trying to call file.saveInBackground(); and in the next line Object.put("Image", file);. As saveInBackground() is asynchronous it is probably finishes after you're trying to put this file object to Object. Try to add callback and move this code to callback:
file.saveInBackground(new SaveCallback callback() {
#Override()
public void done(ParseException e) {
if (e == null) {
Object.put("Image", file);
// Create the class and the columns
petObject.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
finish();
} else {
}
}
});
} else {
}
}
});
Related
Not sure how should I phrase it, but In my app sometimes a single button click generates multiple events and hence it ends up sending multiple similar transactions to the server which is causing data integrity problem. Here is the code flow, Do note that this code runs on users phone which may have weaker connections at times, hence I store the data in SQLite and there is a separate sync service which sends data (fetching from SQLite tables) to Server when Internet is connected.
This is where the click is captured and event is posted for Main Activity (Landing Page)
#OnClick(R.id.btn_add_attempt)
public void onAttemptClick() {
try{
btnAddAttempt.setEnabled(false);
EventBus.getDefault().post(new ExampleActionEvent());
moveToHomePage();
} catch (Exception e){
e.printStackTrace();
Crashlytics.logException(e);
}
}
Here is the Event subscription from my main Activity.
#Subscribe()
public void onExampleAction(ExampleActionEvent exampleActionEvent)
{
if(application == null) application = (ExApplication) getApplication();
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
ArrayList<Something> somethings = application.getArray().getsomethings();
if (!ExUtils.validatesomethings(somethings)){
runOnUiThread(new Runnable() {
#Override
public void run() {
RiderUtils.showSimplePopup(
MainLandingActivity.this,
getString(R.string.title_alert),
getString(R.string.alert_message),
getString(R.string.done),
null,
false,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
showPendingSomething();
ExUtils.moveToPending(MainLandingActivity.this);
}
},
null,
false);
}
});
return;
}
status = application.getArray().getStatus();
imageLocalPath = application.getArray().getsomethings().get(0).getPhotoPath();
Log.d(Const.TAG, "image path is: "+imageLocalPath);
try {
ExUtils.pushExampleActionEvent(application.getArray(), MainLandingActivity.this, xyz, abc);
} catch (Exception e) {
e.printStackTrace();
}
FileWriteEvent fileWriteEvent = null;
String currentTimestamp = application.getArray().getTimestamp();
switch (status) {
case Const.UPDATE_SUCCESS:
fileWriteEvent = new FileWriteEvent(Const.EVENT_CSV_FILE_SUCCESS_VALUE, application.getArray(), "",
cachedLocation, currentTimestamp, null);
break;
case Const.UPDATE_ATTEMPTED:
fileWriteEvent = new FileWriteEvent(Const.EVENT_CSV_FILE_ATTEMPTED_VALUE, riderApplication.getBulkArray(), "",
cachedLocation, currentTimestamp, null);
ExUtils.showSnackbar(holder, getString(R.string.Example), Snackbar.LENGTH_LONG);
break;
}
if(fileWriteEvent != null)
{
EventBus.getDefault().post(fileWriteEvent);
}
createAll(); //SQLite DB call for Inserting some data
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
switch (status) {
case Const.UPDATE_SUCCESS:
RiderUtils.showSnackbar(holder, getString(R.string.Success), Snackbar.LENGTH_LONG);
break;
case Const.UPDATE_ATTEMPTED:
RiderUtils.showSnackbar(holder, getString(R.string.Failed), Snackbar.LENGTH_LONG);
break;
}
}catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
thread.start();
}
I am not able to figure out why is it misbehaving sometimes randomly otherwise it runs smoothly, Hence I am not able to regenrate the issue while debugging.
So after sometimes I looked at the problem again and found out the developer who worked before me had not declared the Main Activity as SingleInstance and hence Every time if the app was opened from Notification Drawer as we were showing it in Notification drawer if app is running, then it was creating a new Activity hence registering on EventBus which was causing the issue by creating duplicate events.
Here is my code:
automaticCountryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
progressBar.setVisibility(View.VISIBLE);
if (ContextCompat.checkSelfPermission(HomeActivity.this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
setUpLocationPermission();
return;
}
Log.d(TAG, String.valueOf(gps.canGetLocation()));
Log.d(TAG, String.valueOf(gps.getLocation()));
Log.d(TAG, String.valueOf(gps.getLatitude()));
Log.d(TAG, String.valueOf(gps.getLongitude()));
Geocoder myLocation = new Geocoder(HomeActivity.this);
try
{
myList = myLocation.getFromLocation(gps.getLatitude(), gps.getLongitude(), 1);
}
catch (Exception e)
{
Log.d(TAG, "unable");
e.printStackTrace();
}
if(myList != null) {
try {
String country = myList.get(0).getCountryName();
Log.d(TAG, country);
findCountryInArrayList(country);
}
catch (Exception e)
{
Toast.makeText(HomeActivity.this, "Didn't manage to automatically detect location.", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
});
}
I want that immediately after the view is clicked the progressbar will become visible. However, it donesn't become visable until all the code is finished, which is against the whole point.
WHy is this not happening right at the beginning of the click? I have put progressBar.setVisibility(View.VISIBLE) at the top, why is it only executed after all the code is done, which sometimes takes a few seconds.
Thanks very much.
This is because you are trying to do your work on the UI thread - the UI will not actually be updated at all until this method finishes.
Try changing up your call to this:
public void onClick(View view) {
progressBar.setVisibility(View.VISIBLE);
progressBar.post( new Runnable() {
public void run() {
// long running code that has UI interactions
}
});
}
This will show the view immediately, and submit the runnable - long running task - to the message queue; this task will be run on a background thread that can still manipulate the UI, but will not cause it to hang.
I'm trying to save an item which has a relation to my image class. I can save the item, and i can save the image seperately, but when I am saving them with the relation if throws this error:
unable to encode an association with an unsaved ParseObject
Here is my code:
myAdvert = new ParseObject("Items");
myAdvert.put("title", "some title");
if (pic1Set) {
Bitmap bitmap = ((BitmapDrawable) pic1.getDrawable())
.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
myPhoto1 = new ParseObject("Images");
filePhoto = new ParseFile("image.png", byteArray);
filePhoto.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
myPhoto1.put("image", filePhoto);
ParseRelation relation = myAdvert.getRelation("pictures");
relation.add(myPhoto1);
myAdvert.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
// TODO Auto-generated method stub
if (e != null) {
--> // THIS IS WHERE THE ERROR IS THROWN!!!!
Log.d("error", e.toString());
} else {
}
}
});
} else {
Log.d("wow, error", e.toString());
Toast.makeText(getApplicationContext(),
"Error saving: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
lets consider this a comment and some extra info rather then an answer -
I'm running to the same exception when trying to login BUT it will happen only after I have some action done offline while the local data store is working
I also have ACL on.
I'm guessing it has something to do with an attempt to save stuff pinned from my offline work in a wrong order or something.
I'm working on debugging mine - good luck to all of us - let me know if you find something.
This is a strange one and I hope that someone can at least give me a direction to look in.
My Android application uses GoogleMap API v2. In the app, I run an activity off OnClickInfoWindowListener on one of the markers. In detail, when I click on the particular marker, an InfoWindow of that marker appears. Next when I click on the InfoWindow, it launches another activity.
The problem is that when I return to GoogleMap from that activity, the particular marker which launched the activity, is not responsive. By responsive, I mean when I click on it, I do not get an InfoWindow. There is no such problem with the other markers. To fix the problem, I either move or zoom on the map or click on another marker to show its InfoWindow, then the original marker works normally. I cannot see any red stuff on the LogCat.
I also run the map off a ListView and there is no problem (that I can see).
Any suggestions on what to look at are very welcome!
Edit 1 :
This part is the InfoWindowClickListener setup ...
// Set up info Window Click Listener
googleMap
.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker mkr) {
// Default open file
// menu option : edit file information
// menu option : delete
Log.d(TAG, "InfoWindow Click detected.");
final GeoFileData gfd = getFromHashMap(mkr);
if (editGeoFile) {
editGeoFile = false;
editFileInfo(gfd);
} else if (deleteGeoFile) {
deleteGeoFile = false;
deleteFile(gfd, mkr);
} else {
openFile(gfd);
}
}
});
The openFile routine which launches the Activity
// Public and Routines used by the main loop
private void openFile (GeoFileData gfd) {
int typeIndex = gfd.getTypeIndex();
switch(typeIndex) {
case 0 :
case 1 :
case 2 :
case 3 :
// Spen file by default
Intent notePadIntent = new Intent(getBaseContext(), NotePad.class);
Bundle b = new Bundle();
b.putParcelable(MAIN_NOTEPAD_GFD, gfd);
notePadIntent.putExtras(b);
startActivityForResult(notePadIntent, SPEN_NOTEPAD_CODE);
break;
default :
Log.w(TAG, "Unknown file.");
Toast.makeText(this, getString(R.string.toast_unknown_file), Toast.LENGTH_LONG).show();
break;
}
}
The starting part of the launched activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spen_notepad);
Bundle extras = getIntent().getExtras();
if (extras != null) {
inputGfd = extras.getParcelable(PreznsActivity.MAIN_NOTEPAD_GFD);
}
extras.clear();
mContext = this;
// Spen
boolean isSpenFeatureEnabled = false;
Spen spenPackage = new Spen();
try {
spenPackage.initialize(this);
isSpenFeatureEnabled = spenPackage.isFeatureEnabled(Spen.DEVICE_PEN);
} catch (SsdkUnsupportedException e) {
if( SDKUtils.processUnsupportedException(this, e) == true) {
return;
}
} catch (Exception e1) {
Toast.makeText(mContext, "Cannot initialize Spen.",
Toast.LENGTH_SHORT).show();
e1.printStackTrace();
finish();
}
FrameLayout spenViewContainer =
(FrameLayout) findViewById(R.id.spenViewContainer);
RelativeLayout spenViewLayout =
(RelativeLayout) findViewById(R.id.spenViewLayout);
// PenSettingView
mPenSettingView =
new SpenSettingPenLayout(mContext, new String(),
spenViewLayout);
if (mPenSettingView == null) {
Toast.makeText(mContext, "Cannot create new PenSettingView.",
Toast.LENGTH_SHORT).show();
finish();
}
// EraserSettingView
mEraserSettingView =
new SpenSettingEraserLayout(mContext, new String(),
spenViewLayout);
if (mEraserSettingView == null) {
Toast.makeText(mContext, "Cannot create new EraserSettingView.",
Toast.LENGTH_SHORT).show();
finish();
}
// TextSettingView
mTextSettingView = new SpenSettingTextLayout(mContext, new String(), new HashMap<String, String>(), spenViewLayout);
if (mTextSettingView == null) {
Toast.makeText(mContext, "Cannot craeate new TextSettingView.", Toast.LENGTH_SHORT).show();
finish();
}
spenViewContainer.addView(mPenSettingView);
spenViewContainer.addView(mEraserSettingView);
spenViewContainer.addView(mTextSettingView);
// SpenSurfaceView
mSpenSurfaceView = new SpenSurfaceView(mContext);
if (mSpenSurfaceView == null) {
Toast.makeText(mContext, "Cannot create new SpenSurfaceView.",
Toast.LENGTH_SHORT).show();
finish();
}
spenViewLayout.addView(mSpenSurfaceView);
mPenSettingView.setCanvasView(mSpenSurfaceView);
mEraserSettingView.setCanvasView(mSpenSurfaceView);
mTextSettingView.setCanvasView(mSpenSurfaceView);
//
Display display = getWindowManager().getDefaultDisplay();
mScreenRect = new Rect();
display.getRectSize(mScreenRect);
// SpenNoteDoc
try {
mSpenNoteDoc =
new SpenNoteDoc(mContext, mScreenRect.width(), mScreenRect.height());
} catch (IOException e) {
Toast.makeText(mContext, "Cannot create new NoteDoc",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
finish();
} catch (Exception e) {
e.printStackTrace();
finish();
}
// NoteDoc
mSpenPageDoc = mSpenNoteDoc.appendPage();
mSpenPageDoc.setBackgroundColor(0xFFD6E6F5);
mSpenPageDoc.clearHistory();
// PageDoc
mSpenSurfaceView.setPageDoc(mSpenPageDoc, true);
initSettingInfo();
// Listener
mSpenSurfaceView.setTouchListener(mPenTouchListener);
mSpenSurfaceView.setColorPickerListener(mColorPickerListener);
mSpenSurfaceView.setTextChangeListener(mTextChangeListener);
mSpenSurfaceView.setReplayListener(mReplayListener);
mSpenPageDoc.setHistoryListener(mHistoryListener);
mEraserSettingView.setEraserListener(mEraserListener);
mSpenSurfaceView.setFlickListener(mFlickListener);
// Button
mTextObjBtn = (ImageView) findViewById(R.id.textObjBtn);
mTextObjBtn.setOnClickListener(mTextObjBtnClickListener);
mPenBtn = (ImageView) findViewById(R.id.penBtn);
mPenBtn.setOnClickListener(mPenBtnClickListener);
mEraserBtn = (ImageView) findViewById(R.id.eraserBtn);
mEraserBtn.setOnClickListener(mEraserBtnClickListener);
mUndoBtn = (ImageView) findViewById(R.id.undoBtn);
mUndoBtn.setOnClickListener(undoNredoBtnClickListener);
mUndoBtn.setEnabled(mSpenPageDoc.isUndoable());
mRedoBtn = (ImageView) findViewById(R.id.redoBtn);
mRedoBtn.setOnClickListener(undoNredoBtnClickListener);
mRedoBtn.setEnabled(mSpenPageDoc.isRedoable());
mImgObjBtn = (ImageView) findViewById(R.id.imgObjBtn);
mImgObjBtn.setOnClickListener(mImgObjBtnClickListener);
mAddPageBtn = (ImageView) findViewById(R.id.addPageBtn);
mAddPageBtn.setOnClickListener(mAddPageBtnClickListener);
mTxtView = (TextView) findViewById(R.id.spen_page);
mTxtView.setText("Page" + mSpenNoteDoc.getPageIndexById(mSpenPageDoc.getId()));
selectButton(mPenBtn);
String filePath = inputGfd.getFileDirectory();
mFilePath = new File(filePath);
if (!mFilePath.exists()) {
if (!mFilePath.mkdirs()) {
Toast.makeText(mContext, "Save Path Creation Error", Toast.LENGTH_SHORT).show();
return;
}
}
mSpenPageDoc.startRecord();
File loadFile = new File(inputGfd.getFileDirectory(), inputGfd.getFileName());
if (loadFile.exists()) {
loadNoteFile();
} else {
Log.w(TAG, "File does not exist!");
}
if(isSpenFeatureEnabled == false) {
mToolType = SpenSurfaceView.TOOL_FINGER;
mSpenSurfaceView.setToolTypeAction(mToolType,
SpenSurfaceView.ACTION_STROKE);
Toast.makeText(mContext,
"Device does not support Spen. \n You can draw stroke by finger",
Toast.LENGTH_SHORT).show();
}
}
One of the returns for the activity
private boolean saveNoteFile(final boolean isClose) {
// file save
// note file
String saveFilePath = inputGfd.getFileDirectory() + File.separator;
String fileName = inputGfd.getFileName();
if (!fileName.equals("")) {
saveFilePath += fileName;
saveNoteFile(saveFilePath);
if (isClose)
finish();
} else {
Toast
.makeText(mContext, "Invalid filename !!!", Toast.LENGTH_LONG)
.show();
}
return true;
}
and finally the destroy routine,
#Override
protected void onDestroy() {
Log.d(TAG, "NotePad onDestroy()");
super.onDestroy();
if (mSpenNoteDoc != null && mSpenPageDoc.isRecording()) {
mSpenPageDoc.stopRecord();
}
if (mPenSettingView != null) {
mPenSettingView.close();
}
if (mEraserSettingView != null) {
mEraserSettingView.close();
}
if (mTextSettingView != null) {
mTextSettingView.close();
}
if(mSpenSurfaceView != null) {
if (mSpenSurfaceView.getReplayState() == SpenSurfaceView.REPLAY_STATE_PLAYING) {
mSpenSurfaceView.stopReplay();
}
mSpenSurfaceView.closeControl();
mSpenSurfaceView.close();
mSpenSurfaceView = null;
}
if(mSpenNoteDoc != null) {
try {
if (isDiscard)
mSpenNoteDoc.discard();
else
mSpenNoteDoc.close();
} catch (Exception e) {
e.printStackTrace();
}
mSpenNoteDoc = null;
}
};
Thanks!
This is likely a bug in Google Maps Android API v2 itself.
I encounter it in my app. When you open "Declusterification" demo, click on yellow marker with 10 in the center and a new marker (red default) appears in the same spot, this new marker cannot be interacted with to show info window without moving the map.
If you happen to figure out SSCCE for it, I suggest posting it on gmaps-api-issues. I'll support it. If I do find simple example to show this issue, I'll also post an update here.
To close up this question.
GoogleMap markers exhibit the anomalies mentioned in this thread and currently the issue has been fed back to Google. There are two apparent "workarounds" to the problem but how effective they are is not clear:
1st workaround : work within the limitations of .clear(). An activated marker cannot be deactivated with .clear().
2nd workaround : after returning from the activity, perform a camera update. This apparently resets the activation of the marker.
I am pulling my hair out! At one point in the last week, I had this working.
I have an Android app that I am trying to add in-ap billing to. I followed the sample TrivialDrive, and my code worked a few times. Now it doesn't.
I am creating a simple trivia game that has a number of free questions, and the option to upgrade to get more questions. When the user completes the list of free questions, they are taken to a "Game Over" screen where they can erase their answers and start again, or upgrade.
When I click the "Upgrade" button, I can make a successful purchase, but as soon as the Google "Payment Successful" dialog goes away, my activity is destroyed and I am sent back to my main activity.
When I try to go back and do my purchase again, my code catches the error ("You already own this item") and handles it appropriately. My code explains to the user that they already own the upgrade, and allows them to click a button to continue playing. So it looks like the OnIabPurchaseFinishedListener is firing at this point.
I have updated the Google helper code with the latest files.
Any help or suggestions as to where to look for answers is much appreciated.
Thanks.
This is the relevant code for my activity:
public class GameOverActivity extends BaseActivity
{
private IabHelper mHelper;
private String m_base64EncodedPublicKey;
private static String THE_UPGRADE_SKU = "upgrade52";
public static int BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED = 7;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_over);
setTitle("Game Over");
Button butPlay = (Button) findViewById(R.id.buttonPlay);
butPlay.setVisibility(View.INVISIBLE);
PrepareIAB();
}
#Override
protected void onResume()
{
super.onResume();
CURRENT_ACTIVITY = ACTIVITY_GAME_OVER;
SetMainText();
}
#Override
protected void onDestroy()
{
super.onDestroy();
try
{
if (mHelper != null)
{
mHelper.dispose();
mHelper = null;
}
}
catch (Exception e)
{
}
}
private void PrepareIAB()
{
m_base64EncodedPublicKey = "MyKey";
// compute your public key and store it in base64EncodedPublicKey
mHelper = new IabHelper(this, m_base64EncodedPublicKey);
mHelper.enableDebugLogging( true, TAG);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener()
{
public void onIabSetupFinished(IabResult result)
{
if (!result.isSuccess())
{
ShowMessage("There was an error connecting to the Google Play Store.");
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
try
{
// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data))
{
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
else
{
// Log.d(TAG, "onActivityResult handled by IABUtil.");
}
}
catch (Exception e)
{
super.onActivityResult(requestCode, resultCode, data);
}
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =
new IabHelper.OnIabPurchaseFinishedListener()
{
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
try
{
if (result.isFailure())
{
if (result.mResponse==7)
{
UpgradeComplete();
ShowMessage("Thank you for upgrading.\r\n\r\nThis version has 400 more questions.");
}
else
{
ShowMessage("Error purchasing: " + String.valueOf(result.mResponse));
UpgradeError();
return;
}
}
else if (purchase.getSku().equals(THE_UPGRADE_SKU))
{
UpgradeComplete();
ShowMessage("Thank you for upgrading.\r\n\r\nThis version has 400 more questions.");
}
else
{
ShowMessage("Something else happened. ");
}
}
catch (Exception e)
{
Log.e(TAG, e.getLocalizedMessage());
}
}
};
private void HideUpgrade()
{
try
{
Button btnUpgrade = (Button) findViewById(R.id.buttonUpgrade);
if (btnUpgrade != null)
{
btnUpgrade.setVisibility(View.INVISIBLE);
}
TextView txtMessage = (TextView) findViewById(R.id.txtUpgradeFromGameOver);
if (txtMessage!=null)
{
txtMessage.setVisibility(View.INVISIBLE);
}
}
catch (Exception e)
{
}
}
public void onQuitButtonClick(View view)
{
finish();
}
public void onResetDBButtonClick(View view)
{
ConfirmResetDatabase();
}
private void ConfirmResetDatabase()
{
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
switch (which)
{
case DialogInterface.BUTTON_POSITIVE:
ResetDatabase();
Intent gameActivity = new Intent(getApplicationContext(), GameActivity.class);
gameActivity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
// startActivityForResult(gameActivity, ACTIVITY_GAME);
startActivity(gameActivity);
break;
case DialogInterface.BUTTON_NEGATIVE:
// No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to erase your score and start over?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
}
public void onUpgradeButtonClick(View view)
{
try
{
if (mHelper != null)
{
mHelper.launchPurchaseFlow(this, THE_UPGRADE_SKU, 10001, mPurchaseFinishedListener, m_TriviaAppInstance.AppInstallID());
}
else
{
ShowMessage("Unable to connect to Google Play Store.");
}
}
catch (Exception e)
{
ShowMessage("Unable to connect to Google Play Store.");
SendErrorMessage(e.getLocalizedMessage());
}
}
private void UpgradeComplete()
{
try
{
HideUpgrade();
Button butPlay = (Button) findViewById(R.id.buttonPlay);
if (butPlay!=null)
{
butPlay.setVisibility(View.VISIBLE);
}
TextView txtReset = (TextView) findViewById(R.id.txtGameOverRestDB);
if (txtReset!=null)
{
txtReset.setVisibility(View.INVISIBLE);
}
Button btnReset = (Button)findViewById(R.id.buttonResetDB);
if (btnReset!=null)
{
btnReset.setVisibility(View.INVISIBLE);
}
m_TriviaAppInstance.SetUpgradedStatus(true);
}
catch (Exception e)
{
}
//
}
private void UpgradeError()
{
try
{
Button butUpgrade;
butUpgrade = (Button) findViewById(R.id.buttonUpgrade);
butUpgrade.setVisibility(View.INVISIBLE);
TextView txtMessage = (TextView) findViewById(R.id.txtUpgradeScreen);
txtMessage.setText(R.string.upgradeScreenTextError);
}
catch (Exception e)
{
}
}
public void onPlayButtonClick(View view)
{
Intent myIntent = new Intent(view.getContext(), GameActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivityForResult(myIntent, ACTIVITY_GAME);
}
public void SetMainText()
{
TextView txt = (TextView) findViewById(R.id.txtScoreGlobal);
txt.setText(Integer.toString(m_TriviaAppInstance.getGlobal()) + "%");
SetPlayerScore(1);
if (m_TriviaAppInstance.getUpgradedStatus() == true)
{
HideUpgrade();
}
}
}
FYI: I think I have this figured out - for anyone else that may come across it.
The activity that I was using to launch "In App Billing" was called with a "FLAG_ACTIVITY_NO_HISTORY". I did this because I didn't want the user to be able to click to go back to this "Game Over" activity.
BUT, this causes grief with "In App Billing". So, make sure you don't try to launch "In App Billing" from an activity that has had the "FLAG_ACTIVITY_NO_HISTORY" set.
My original code:
private void GameOver()
{
m_TriviaAppInstance.setGameOver(true);
Intent gameOver = new Intent(getApplicationContext(), GameOverActivity.class);
gameOver.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(gameOver);
}
Updated code:
private void GameOver()
{
m_TriviaAppInstance.setGameOver(true);
Intent gameOver = new Intent(getApplicationContext(), GameOverActivity.class);
startActivity(gameOver);
}
Peace
I'm not high enough to comment, but bless you. I had
android:noHistory="true"
set in AndroidManifest.xml for my activity and was experiencing the same problem.
Took it out and IAB is working. Yay!
Do not forget that your IabHelper.OnIabPurchaseFinishedListener is called on a different thread and before onResume() is called on your Activity!
So your UpgradeComplete() or UpgradeError() can cause a crash on older devices (Crashed every time on my Gingerbread Sony Xperia Mini Pro and worked without any trouble on Samsung Galaxy S4 (Android 4.2.2)
Caused a 3 day delay on my game..