Update: Thank you all for attempting to help me solve this bug. I am still unsure as to the cause, I was able to roll back to a previous commit and continue development from there. This previous commit did show the same bug, however after I commented out button.performClick() it went away. Strangely, this does not work on the most recent commit.
I still do not understand this bug and would appreciate any more assistance in helping determine the root cause. My greatest fear would be to inadvertently re-introduce it.
I have the most crazy error I have ever seen.
The OnCreate method is being called over and over again, freezing my application and giving me a slight flicker. The only solution is then to exit to the home screen and force quit the application from the settings menu.
Here is what is happening in detail:
Application starts (Main Activity)
Main Activity calls the Second Activity
Second Activity calls onCreate, sets up as normal
Second Activity randomly decides to exit onCreate <-- I think this what's happening
Second Activity's onCreate gets called again. It doesn't ever return to the Main Activity.
I have run a debugger, it appears that the second activity successfully completes the onComplete/onResume sequence, then decides to exit and restart.
Has anybody ever heard of this behavior before?
I haven't noticed any exceptions being thrown. Also, in the course of debugging, I did go ahead and check those locations that you see as silent fail. (this is the older code before I littered it with print statements)
UPDATE: When attempting to stop the process, I must turn on airplane mode. This means it has something to do with this code block (Second Activity)
else if (Network.haveNetworkConnection(Login.getContext()) && Login.checkClientId())
{...}
With no internet, it will hit the else statement and does not display this behavior.
CODE:
onResume() of the Main Activity, where I call the Second Activity:
#Override
public void onResume()
{
super.onResume();
//Check If logged in, else go to login page
Login.setContext(getApplicationContext());
//Reset Notification Number
GCMIntentService.cancelNotifications();
/** GO TO LOGIN **/
if(!Login.isLoggedIn())
{
//If user is not logged in, open login page
System.out.println("RESUMING MAIN AND STARTING LOGIN INTENT");
Intent intent = new Intent(ActivityMain.this, ActivityLogin.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else
{
Login.setupStuffOnce();
Event.pullEvents(); //Get New Events
//Update ListView
updateMainFeed();
}
}
This is the Second Activity:
public class ActivityLogin extends Activity
{
private String postData;
//private Context c;
//final Timer timer = new Timer();
//Facebook Stuff
private Facebook facebook = new Facebook(Config.FBAPPID);
private AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);
//Layout Stuff
EditText username, password;
Button loginButton, signupButton;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Open Database
Login.setContext(getApplicationContext());
Database.open(getApplicationContext());
}
/*
* #Override public void onPause() { s }
*/
#Override
public void onResume()
{
super.onResume();
// shouldn't put here but oh well
init();
//If coming from ActivitySignup
if(Transfer.username != null)
{
username.setText(Transfer.username);
password.setText(Transfer.password);
Transfer.password = null;
Transfer.username = null;
loginButton.performClick();
}
}
public void init()
{
Login.getUserLoggedIn();
if (Login.isLoggedIn())
{
//Do Any Additional Setup
Login.setupStuffOnce();
// If user is logged in, open main
Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
//intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else if (Network.haveNetworkConnection(Login.getContext()) && Login.checkClientId())
{
// Else, Make User Login
// Inflate Login and Present Website
String clientid = Login.getClientId();
System.out.println("clientid:" + clientid);
//System.exit(0);
postData = "mobile=1&client_id="+Login.getClientId();
// Inflate the view
setContentView(R.layout.activitylogin3);
username = (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
//Inflate the Button
loginButton = (Button) findViewById(R.id.loginButton);
signupButton = (Button) findViewById(R.id.signupButton);
signupButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(ActivityLogin.this, ActivitySignup.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int res = Login.sendLogin(username.getText().toString(), password.getText().toString());
if(res == 202)
{
//Login Successful
//Check if facebooked.
if(Login.isFacebooked())
{
//Just go to main
Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
//Are these flags necessary?
//intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else
{
//Go to facebook login page
//Intent intent = new Intent(ActivityLogin.this, ActivityFBLogin.class);
//startActivity(intent);
//Login via Facebook
doFacebook();
}
} else
{
System.out.println("Login Failed: "+res);
if(res == 405)
{
Toast.makeText(getApplicationContext(), "Incorrect Username/Password", Toast.LENGTH_SHORT).show();
password.setText("");
}
else
Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show(); //Not entirely true in all cases i think
}
/*Login.getUserLoggedIn();
if(Login.isLoggedIn())
{
Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "Please Login Above", Toast.LENGTH_SHORT).show();
}*/
}
});
} else
{
// Not Logged In and No Internet Access
setContentView(R.layout.activitylogintext);
EditText text = (EditText) findViewById(R.id.text);
text.setText("No Internet Connection Detected\n requires internet to login");
Button button = (Button) findViewById(R.id.refreshButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Login.getUserLoggedIn();
if(Network.haveNetworkConnection(Login.getContext()))
{
Intent intent = new Intent(ActivityLogin.this, ActivityLogin.class);
//intent.setFlags();
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "No Internet Access Detected", Toast.LENGTH_SHORT).show();
}
}
});
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
public void doFacebook()
{
facebook.authorize(this, Config.facebookPermissions, new DialogListener() {
#Override
public void onComplete(Bundle values) {
/*SharedPreferences.Editor editor = state.edit();
editor.putString("access_token", facebook.getAccessToken());
editor.putLong("access_expires", facebook.getAccessExpires());
editor.commit();
*/
//Input into database
Login.saveAccessToken(facebook.getAccessToken());
Login.setFB(facebook.getAccessToken());
//Login.sendAccessToken(facebook.getAccessToken());
//Intent into Main Activity
Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
//intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
#Override
public void onFacebookError(FacebookError error) {
Toast.makeText(getApplicationContext(), "Error: "+error.getErrorType(), Toast.LENGTH_SHORT).show();
}
#Override
public void onError(DialogError e) {
Toast.makeText(getApplicationContext(), "Error: "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
#Override
public void onCancel() {}
});
}
public boolean checkForUserID(Context c)
{
try{
String res = Network.getUrl("www.website.com/mobile.php?got_user=1&client_id="+Login.getClientId());
JSONObject json = JSON.constructObject(res);
if(JSON.handleCode(json))
{
if(json.getString("type").equals("userid"))
{
Login.setLogin(json.getString("data"));
return true;
}
}
} catch(Exception e)
{
//Silent Fail
}
return false;
}
}
I believe that the problem will be resolved if you finish your MainActivity after you call SecondActivity. The problem probably is that the onResume event is immediatelly fired when you resume your MainActivity. That is because the MainActivity was probably destroyed and recreated while it was in background. Another solution would be to save your Activity's state with onSaveInstanceState. See here for more information.
Check this code in your activity:
Button button = (Button) findViewById(R.id.refreshButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(Network.haveNetworkConnection(Login.getContext()))
{
Intent intent = new Intent(ActivityLogin.this, ActivityLogin.class);
//intent.setFlags();
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "No Internet Access Detected", Toast.LENGTH_SHORT).show();
}
}
});
Here you are calling ActivityLogin itself.
That's why the onCreate() is being called again and again.
I had a similar problem once. The problem occurred because I made configuration changes without declaring them in the android:configChanges attribute of the <activity> tag (and hence it recreates itself the whole time).
For example, if you change the locale manually you need to add locale to android:configChanges!
It seems to me there is a good chance for endless cycling here if Login is not properly shared between the activities, causing Login.isLoggedIn() to return true in ActivityLogin but false in ActivityMain.
A few critical factors are where your Login object is located, is it static, how is it referenced between Activities? It is entirely possible that ActivityMain is being destroyed while ActivityLogin is active; storing the Login data in SharedPreferences or a database, or otherwise persisting it is important. How does isLoggedIn() resolve (determine its return value?)
Suggestion 1: Consider making use of the Singleton pattern (if you haven't already.)
Suggestion 2: While discouraged, you could store Login at the Application level.
Suggestion 3: You can try using Intent.FLAG_ACTIVITY_SINGLE_TOP to reduce the likelyhood of a new ActivityMain being created - which might not have access to Login, again depending on how you have it stored.
ActivityMain
onResume() {
if(!Login.isLoggedIn()) {
/* Not logged in, launch ActivityLogin! */
Intent intent = new Intent(ActivityMain.this, ActivityLogin.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
ActivityLogin
onResume() { /* ... */ init(); }
init() {
Login.getUserLoggedIn();
if (Login.isLoggedIn()) {
/* Internet - launch ActivityMain! */
Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // <--- suggested addition
startActivity(intent);
else if (Network.haveNetworkConnection(Login.getContext()) && Login.checkClientId()) {
/* No internet, the user was unable to login. */
}
I think your main problem is with you onResume function as it gets called each time it comes back into view (eg: you start second activity, finish it, main activity onResume is called again. If you finish your second activity (or it quietly crashes for some reason) you will go back to your mainActivity and call onResume (which will start the cycle all over again).
Now i dont know if you are finishing activity 2 somehow but I would check that.
EDIT:
ALso I would put some logcats here
if (Login.isLoggedIn())
{
//Do Any Additional Setup
Login.setupStuffOnce();
// If user is logged in, open main
Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
//intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
Log.i("Some Tag", "Starting Main Activity From Activity 2");
startActivity(intent);
}
The above adding of the log.i will allow you to know if this is where the error happens, and you can go from there.
I had similar problem where the activity would be recreated all the time. Re-installing the app wouldn't help, but restarting the phone did the job.
Related
How can I use shared preference in android studio to achieve this?
On my app, Splash Screen redirects to Activity A.
There is a button on Activity A, When this button on Activity A is clicked, next time when user opens app, Activity A will not show again, Activity B must open next.
The logic here is, Activity A is my welcome screen, after user clicks get started on this activity, I don't want this Activity to open again. Activity B is my Main Activity
NB: I have checked all questions and answers on stackoverflow, they did not help, the ones available where showing activity only on first run and this not a duplicate question, any help provided is appreciated.
You can store boolean by shared preference to do that. Here your AcitivityA class.
public class ActivityA extends AppCompatActivity {
private SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
try {
prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean firsttimeLoad = prefs.getBoolean("first_time_load", true);
if (!firsttimeLoad) {
sendToB();
}
} catch (Exception e) {
e.printStackTrace();
}
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("first_time_load", false);
editor.commit();
sendToB();
}
});
}
private void sendToB() {
Intent mainIntent = new Intent(ActivityA.this, ActivityB.class);
startActivity(mainIntent);
finish();
}}
This is the code im using for save the sigin details from firebase you can check this out and try this
private fun handleSignInResult(task: Task<GoogleSignInAccount>?) {
try {
if (task!!.isSuccessful) {
val account = task.getResult(ApiException::class.java)
PreferenceHelper.writeBooleanToPreference(KEY_LOGIN_WITH_OAUTH, true)
updatePreference(account!!)
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("UserName", account.displayName)
intent.putExtra("UserEmail", account.email)
intent.putExtra("UserPhoto", account.photoUrl?.toString())
intent.putExtra("uid", account.id)
saveUser(account)
startActivity(intent)
finish()
} else {
Toast.makeText(
this,
"Login Error " + task.exception?.message,
Toast.LENGTH_SHORT
).show()
}
} catch (e: Exception) {
}
}
private fun updatePreference(account: GoogleSignInAccount) {
PreferenceHelper.writeBooleanToPreference(KEY_USER_LOGGED_IN, true)
PreferenceHelper.writeStringToPreference(KEY_USER_GOOGLE_ID, account.id)
PreferenceHelper.writeStringToPreference(
KEY_DISPLAY_NAME,
account.displayName
)
PreferenceHelper.writeStringToPreference(
KEY_USER_GOOGLE_GMAIL,
account.email
)
}
When the user selects the button on Activity A, add a value to the shared preferences. What the value is does not really matter. Every time your app is launched, check if this value exists in the shared preferences, if it does launch Activity B, if it doesn't, launch Activiy A.
In onCreate of Activity A
SharedPreferences sharedPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
if (sharedPref.contains("notFirstLaunch")) {
// Launch Activity B
}
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("notFirstLaunch", true);
editor.apply();
}
});
Hello and good luck to everyone.
I am using Intent Activity in my project. And are having bugs with it.
As follows: I have a list of the order of Activity:
A (Main) -> B (Login or SignUp) -> C (Menu) -> D (ListFoodOfMenu) -> E
(DetailsFood)
From A-B-C-D or in many different order does not occur
error.
But, since D-E has an error, the backgroud that I set for the xml
layout disappears throughout the application, replacing it with the
system color.
Who has a solution to help me and what to do to handle this error. Thank you.
This is a UI when there are no errors and then the UI is faulty:
UI is not faulty
UI is faulty
This is my code Intent:
A-B:
btnSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent moveToSignUp = new Intent(getApplicationContext(), SignUpActivity.class);
startActivity(moveToSignUp);
finishActivity(1);
}
});
btnSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent moveToSignIn = new Intent(getApplicationContext(), SignInActivity.class);
startActivity(moveToSignIn);
finishActivity(1);
}
});
B-C:
Intent moveToHome = new Intent(getApplicationContext(), Home.class);
Common.currentUser = user;
startActivity(moveToHome);
C-D:
//Get CategoryID and send to new Activity:
Intent moveToFoodList = new Intent(getApplicationContext(), FoodListActivity.class);
//Because CategoryID is Key, so we just get key of this item:
moveToFoodList.putExtra("CategoryID", adapter.getRef(position).getKey());
startActivity(moveToFoodList);
D-E:
//Start Activity FoodDetails
Intent moveToFoodDetails = new Intent(getApplicationContext(), FoodDetailsActivity.class);
moveToFoodDetails.putExtra("FoodId", searchAdapter.getRef(position).getKey());
// Send FoodId to FoodDetailsActivity
moveToFoodDetails.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(moveToFoodDetails);
E-D (At this point the error has occurred):
btnCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Database(getApplicationContext()).addToCart(new Order(
"", //Id tự tăng
Common.currentUser.getPhone(),
FoodId,
currentFood.getName(),
numberButton.getNumber(),
currentFood.getPrice(),
currentFood.getDiscount()
));
finish();
Toast.makeText(FoodDetailsActivity.this, "Added To Cart", Toast.LENGTH_SHORT).show();
}
});
I have struggled with this error for months and still can not figure
out how to fix it. We look forward to much help from Pro. Sincerely
thank.
It is because you are having library 'com.cepheuen.elegant-number-button:lib:1.0.2' & that library also has background resource named background.xml which is being override with your background.jpg, when you reach FoodDetailsActivity screen.
Solution : Rename your background.jpg to background_1.jpg.
Don't use getApplicationContext() at all places.
Use Activity's object like SignUpActivity.this or SignInActivity.this.
UPDATE
Question 1 Solved
I have solved the issue of profile pic not loading by changing the context of Glide from getApplicationContext to HomeActivity.this and image loaded quickly. :)
But still, I need your help with other two questions. If I am doing it right or wrong and how to avoid that error.
Question 1
So far, I have successfully connected my app for facebook login, but the issue is the profile picture.
What I have done is created 2 activity:-
1. login button of Facebook in Activity 1
2. Home Activity of App.
If the user is logged in, it goes to Activity 2 and if not he goes to activity 1.
On activity 1, I have fetched basic details like dob and email address as name and profile picture doesn't need to be fetched using GraphRequest. (To be able to save on my server)
On activity 2, I have fetched the user name and profile picture. Here's the code:-
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
im = (ImageView) findViewById(R.id.img);
name = (EditText) findViewById(R.id.name);
try {
String url = Profile.getCurrentProfile().getProfilePictureUri(150,150).toString();
name.setText(" "+Profile.getCurrentProfile().getName()+"\n"+Profile.getCurrentProfile().getId());
Glide.with(getApplicationContext()).load(url).into(im);
} catch (Exception e){
Toast.makeText(this, "Error : "+e , Toast.LENGTH_SHORT).show();
}
}
Until 2 days back, profile pic was loading fine but from today it's not loading at all.
Question 2
Another question, I have is that sometimes I get an error message when I log in and get in Home Activity, here's the snapshot of the same:-
Question 3
The last question is how to close the entire app on back pressed from activity 2.
What I have done right now is use handler on Activity 1 so that the above error doesn't come and then use Intent and below that use finish() method on activity 1, and on activity 2:-
public void onBackPressed() {
onStop();
onDestroy();
finish();
}
To Question 3
from Activity 1 create a function onActivityResult
and be sure to use the startActivityForResult to call the Activity 2 instead of startActivity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startActivityForResult(new Intent(this, ActivityTwo.class), 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (data.getBooleanExtra("EXIT", false)) {
finish();
}
}
}
and to close the entire app from Activity 2 using the onBackPressed.
don't forget to remove the super.onBackPressed()
#Override
public void onBackPressed() {
// super.onBackPressed();
Intent intent = new Intent();
intent.putExtra("EXIT", true);
setResult(RESULT_OK, intent);
finish();
}
So I have stored password as hash in shared preferences, when user puts password I need to make a hash of it and compare with stored one.
Should it be done in AsyncTask or Thread because calculation and comparison could freeze UI? And then do you know a clean way to recieve result (true, false) from asynctask or thread?
public void startGenerateCode(View view) {
String pinCompare = pin; //pin is class variable obtained from editText
pinCompare = tools.bin2hex(tools.getHash(pinCompare));
if(pinCompare.compareTo(session.getDetails("Pin"))==0){
generateCode();
}
else
Toast.makeText(this, "Wrong PIN", Toast.LENGTH_SHORT).show();
}
public void generateCode(){
Intent i = new Intent(this, GeneratedCode.class);
startActivity(i);
overridePendingTransition(R.anim.right_slide_in, R.anim.right_slide_out);
finish();
}
This is done in activity after button is pressed.
Zolo,
I guess this process is triggered when someone presses a Button, such as login. I don't think you need any extra Thread to process the Hash calculus.
If you then have to connect to a server and send/receive data, then you should use it due to the asynchronous flow.
Response to comments on main post:
Yes, you can start an Activity in onPostExecute.
Code example:
public void startGenerateCode(View view) {
// Disable button
Button button = (Butto) view;
button.setEnabled(false);
String pinCompare = pin; //pin is class variable obtained from editText
pinCompare = tools.bin2hex(tools.getHash(pinCompare));
if(pinCompare.compareTo(session.getDetails("Pin"))==0){
generateCode();
} else {
// If the login fails, re-enable the button to try again
button.setEnabled(true);
Toast.makeText(this, "Wrong PIN", Toast.LENGTH_SHORT).show();
}
}
I did it by heart, so there may be mistakes.
I have seen some related questions but none focusing on the specific problem I have:
I'm using the PayPal MPL Library.
I build my PayPalPayment object, then create the activity for the checkout to occur. That runs fine. My problem is, on the ResultDelegate I need to call a function from my activity, that occurs after the payment and makes some changes (such as storing SharedPreferences, etc.).
So something like this:
public class ResultDelegate implements PayPalResultDelegate, Serializable {
public void onPaymentSucceeded(String payKey, String paymentStatus) {
System.out.println("SUCCESS, You have successfully completed your transaction.");
System.out.println("PayKey: "+payKey);
System.out.println("PayStatus: "+paymentStatus);
callMyCustomAfterPaymentFunction();
}
...
}
Now the thing is, I tried to create a constructor for ResultDelegate that accepts my activity. My existing code is:
//On the activity class
public class MainMenuActivity extends Activity {
public void onCreate(Bundle savedInstanceState)
{
...
Button buy = (Button) findViewByID(R.id.buy_button);
buy.setOnClickListener(new View.OnClickListener(){
public void onClick(View v)
{
new PurchaseTask(activity).execute();
}
}
}
}
public class PurchaseTask extends AsyncTask <String, Void, String> {
protected String doInBackground()
{
...
PayPal pp = PayPal.getInstance();
CheckoutButton cb = pp.getCheckoutButton(...);
cb.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
ResultDelegate delegate = new ResultDelegate(myActivity);
Intent checkout = PayPal.getInstance().checkout(paument, activity, delegate);
activity.StartActivity(checkoutIntent);
}
}
}
}
//On the ResultDelegate class
public class ResultDelegate implements PayPalResultDelegate, Serializable {
private Activity myActivity;
public void onPaymentSucceeded(String payKey, String paymentStatus) {
System.out.println("SUCCESS, You have successfully completed your transaction.");
System.out.println("PayKey: "+payKey);
System.out.println("PayStatus: "+paymentStatus);
myActivity.performAfterPaymentOperations();
}
...
}
So the goal is to call the activity function from the ResultDelegate. Or even simpler, just to be able to store some SharedPreference changes when the ResultDelegate onPaymentSucceeded() fires.
But I get a NotSerializableException mentioning that the my MyActivity field is not Serializable.
So, then I added the transient identifier to my activity field inside the ResultDelegate, but now I get a NullPointerException.
Paypal Mobile Chekout guide
Implementation provided on paypal website is different from yours. They are doing startActivityForResult() to start PaypalActivity. and when in onActivityResult() method they are checking statusCode to check transaction status and act accordingly.
Follow that document for your implementation.
Here in your code, I donot find a point for using AsyncTask. Your ResultDelegate is Serializable where as Activity is not thats why it is throwing NotSerializableException.
Edit:
As you are developing for Google Android platform, then why not to use Google Checkout In-App?
Edit:
This method will be called when your PaypalActivity will finish. That activity will pass resultCode to this onActivityResult method.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) {
case Activity.RESULT_OK:
// The payment succeeded
String payKey = data.getStringExtra(PayPalActivity.EXTRA_PAY_KEY);
// Tell the user their payment succeeded
break;
case Activity.RESULT_CANCELED:
// The payment was canceled
// Tell the user their payment was canceled
break;
case PayPalActivity.RESULT_FAILURE:
// The payment failed -- we get the error from the EXTRA_ERROR_ID
// and EXTRA_ERROR_MESSAGE
String errorID = data.getStringExtra(PayPalActivity.EXTRA_ERROR_ID);
String errorMessage = data
.getStringExtra(PayPalActivity.EXTRA_ERROR_MESSAGE);
// Tell the user their payment was failed.
}
}
regards,
Aqif Hamid
You can create you custom listener something like this :
Create a custom listener :
OnDoubleTap mListener;
// Double tap custome listenre to edit photoes
public interface OnDoubleTap {
public void onEvent(Uri imgPath, int mPos);
}
public void setDoubleTapListener(OnDoubleTap eventListener) {
mListener = eventListener;
}
Now call this wherever you want like this :
mListener.onEvent(Uri, 1));
Now whenever you call this listener this will fire in your activity where you use this listener like this :
myCanvas.setDoubleTapListener(new OnDoubleTap() {
#Override
public void onEvent(Uri imgPath, int Pos) {
// TODO Auto-generated method stub
Toast.makeText(mContext, "LISTENER WORKING !!!", Toast.LENGTH_SHORT).show();
}
});
Where myCanvas is object of class where you create you listener.
Try this solution:
PayPalPayment thingToBuy = new PayPalPayment(new BigDecimal(price),getResources().getString(R.string.curruncy_code), getResources().getString(R.string.app_name),
PayPalPayment.PAYMENT_INTENT_SALE);
Intent intent = new Intent(CreateEventStep4.this, PaymentActivity.class);
intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy);
startActivityForResult(intent, REQUEST_PAYPAL_PAYMENT);
PaymentConfirmation confirm = data.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION);
if (confirm != null) {
try {
Log.e("paymentExample", confirm.toJSONObject().toString());
JSONObject jsonObj=new JSONObject(confirm.toJSONObject().toString());
String paymentId=jsonObj.getJSONObject("response").getString("id");
System.out.println("payment id:-=="+paymentId);
screenShotFile = takeScreenshot(frmTemplate);
uploadImage(myEvent.getEvent_id(),screenShotFile);
} catch (JSONException e) {
Log.e("paymentExample", "an extremely unlikely failure occurred: ", e);
}