I was able to implement an in app billing processor, and it tests fine without my intent to go to a new activity.
However, after a customer pays for the paid content I want a new intent to be
run automatically whereby a new activity is launched (the activity with the paid content).
However, when I do this the intent overtakes the billing processor, and switches to the paid
activity without any billing or payment. I understand how to use a button with an intent to launch the new activity. However, another button won't work because this too would
be an easy way to go around the in app billing.
Any suggestions to get around this sticky wicket? Thanks much. Yes, this is my first android app. I’m sure you can tell…
BillingProcessor bp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
bp = new BillingProcessor(this, "null", this);
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bp.purchase(MainActivity.this, "android.test.purchased");
//THE PROBLEM IS WHAT FOLLOWS: It overtakes .bp
startActivity(new Intent(MainActivity.this, paidstuff.class));
}
});
}
#Override
public void onProductPurchased(#NonNull String productId, #Nullable TransactionDetails details) {
Toast.makeText(this, "You just bought something great!", Toast.LENGTH_SHORT).show();
}
#Override
public void onPurchaseHistoryRestored() {
}
#Override
public void onBillingError(int errorCode, #Nullable Throwable error) {
}
#Override
public void onBillingInitialized() {
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!bp.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onDestroy() {
if (bp != null) {
bp.release();
}
super.onDestroy();
}
}
cant you just put
startActivity(new Intent(MainActivity.this, paidstuff.class));
inside
#Override
public void onProductPurchased(#NonNull String productId, #Nullable TransactionDetails details) {
Toast.makeText(this, "You just bought something great!", Toast.LENGTH_SHORT).show();
}
Related
I managed to set up google sign-in into my app and it works fine. I also added a log-out button that works. The problem I face is that whenever I open the app, it requires the user to log into google (or just press the button) before moving on to the next activity. I have tried many different ways to solve this, but none seem to work. Can someone help me make a persistent google sign-in, in which even if the user closes the app, it keeps them logged in, and they never see the login activity (unless if they sign out)?
Here is my code to my LoginActivity:
public class LoginActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener {
SignInButton signInButton;
private GoogleApiClient googleApiClient;
private SharedPreferences prefs;
private int progress;
private int SIGN_IN;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build();
googleApiClient = new GoogleApiClient.Builder(this).enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso).build();
prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
progress = prefs.getInt("SIGN_IN", 0);
signInButton = findViewById(R.id.signInWithGoogle);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
startActivityForResult(intent, SIGN_IN);
SharedPreferences.Editor editPrefs = prefs.edit();
editPrefs.putInt("SIGN_IN", 1);
editPrefs.apply();
}
});
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == SIGN_IN){
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()){
startActivity(new Intent(LoginActivity.this, StudentInformationFormActivity.class));
finish();
} else {
Toast.makeText(this, "Login Failed!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onPause() {
super.onPause();
}
}
I had the same problem once, I looked at my old code and saw such thing:
#Override
protected void onStart() {
super.onStart();
GoogleSignInAccount lastSignedInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (lastSignedInAccount != null) {
startActivity(new Intent(LogInActivity.this, MainActivity.class));
finish();
}
}
So you can check if user is logged in Actovity's onStart and if so, move to the next activity. Hope helps :)
From the first activity I would like to go to the second, then from the second to the third. In the third activity I would like to enter the name in EditText, then after pressing the button, go to the first activity and at the same time send the information entered in the third activity.
Unfortunately, after pressing the button in the third activity, instead of returning to the first activity, I return to the second activity. Was the first activity killed? What could I do to ensure that the information is correct for the first activity? This is my code:
First:
public class MainActivity extends AppCompatActivity {
TextView textViewInformation;
Button button_GoToSecond;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewInformation = findViewById(R.id.textView);
button_GoToSecond = findViewById(R.id.button);
button_GoToSecond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, Second.class);
startActivity(i);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent i) {
if((requestCode == 1) &&(resultCode == RESULT_OK)) {
String name = i.getStringExtra("name");
textViewInformation.setText(name);
}
}
}
Second:
public class Second extends AppCompatActivity {
Button button_GoToThird;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
button_GoToThird = findViewById(R.id.button2);
button_GoToThird.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(Second.this, Third.class);
startActivity(i);
}
});
}
}
Third:
public class Third extends AppCompatActivity {
EditText editText_Data;
Button button_SendData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
editText_Data = findViewById(R.id.editText);
button_SendData = findViewById(R.id.button3);
button_SendData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
}
public void finish() {
String name;
name = editText_Data.getText().toString();
Intent i = new Intent(Third.this, MainActivity.class);
i.putExtra("name", name);
setResult(RESULT_OK, i);
super.finish();
}
}
just remove finish(); thats it
The reason that it goes to the second activity is because of this:
button_SendData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
public void finish() {
String name;
name = editText_Data.getText().toString();
Intent i = new Intent(Third.this, MainActivity.class);
i.putExtra("name", name);
setResult(RESULT_OK, i);
super.finish(); //This kills the current activity.
}
You should do:
public void finish() {
String name;
name = editText_Data.getText().toString();
Intent i = new Intent(Third.this, MainActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name", name);
startActivityForResult(i, RESULT_OK, bundle);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent i) {
if((requestCode == 1) &&(resultCode == RESULT_OK)) {
Bundle bundle = i.getExtras();
String name = bundle.getString("name");
textViewInformation.setText(name);
}
}
When you call finish, it just kills the current activity. If you want to go back to the first activity, just start a new activity for the first activity and pass the data in a Bundle.
If you want to have more of a stack concept, you can use Fragments.
How can i make the buy button disappear immediately after a successful purchase using Iab Billing Processor in my app?
I'm using a Bottom Navigation activity with Fragments for the pages. I have three fragment pages. The third fragment page I have a button on there that is an in-app buy option. Everything works fine, my only problem is, when the purchase is successful the buy button will not disappear and Toast will not popup confirming the purchase is successful even though I have it added to the onProductPurchased Method. I have to click the buy button a second time to pull the method below. I don't want that. I want the below method to pull immediately after the purchase is successful.
Here's what I have for the onProductPurchased method and the other methods:
#Override
public void onProductPurchased(#NonNull String productId, #Nullable
TransactionDetails details) {
removeAds.setVisibility(View.GONE);
Toast.makeText(getContext(), "Purchase Complete! Thank You!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onPurchaseHistoryRestored() {
removeAds.setVisibility(View.GONE);
Toast.makeText(getContext(), "Your Purchase has been restored!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onBillingError(int errorCode, #Nullable Throwable error) {
removeAds.setVisibility(View.VISIBLE);
Toast.makeText(getContext(), "Purchase Failed!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onBillingInitialized() {
bp.loadOwnedPurchasesFromGoogle();
}
The onActivityResult seems to not be pulling the requestCode, resultCode, and it's not pulling the Intent data. I've tried it two ways and to no avail.
Way 1 (Failed):
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (!bp.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode,resultCode,data);
}
}
Way 2 (Failed):
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
Fragment f = getFragmentManager().findFragmentById(this.getId());
f.onActivityResult(requestCode, resultCode, data);
}
Both of them are not working.
#Override
public void onDestroy() {
if (bp != null) {
bp.release();
}
super.onDestroy();
}
The beginning of my Java Class:
public class MenuOptions extends Fragment implements
BillingProcessor.IBillingHandler {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
BillingProcessor bp;
private OnFragmentInteractionListener mListener;
public MenuOptions() {
}
public static MenuOptions newInstance(String param1, String param2) {
MenuOptions fragment = new MenuOptions();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_menu_options, container,
false);
bp = new
BillingProcessor(Objects.requireNonNull(getActivity())
.getApplicationContext(), null, MenuOptions.this);
removeAds.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bp.purchase(getActivity(), "android.test.purchased");
}
});
return v;
}
I think that the buy button isn't disappearing immediately after successful purchase because of the requestCode and resultCode not being retrieved properly. I've tested it and it doesn't seem to be pulling nothing. Nothing I'm doing is fixing that problem. I've researched online for my problem and I have found the same question asked but unfortunately the answers didn't resolve my problem. I've never done buy options with fragments before. Is there anything I am forgetting? I appreciate the help in advanced!
I have an app that scans QR code. And it to show in another activity. How to pass QR Code text to another activity? Or save it in memory?
MainActivity
public class MainActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler{
private ZXingScannerView zXingScannerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
zXingScannerView = new ZXingScannerView(getApplicationContext());
setContentView(zXingScannerView);
zXingScannerView.setResultHandler(this);
zXingScannerView.startCamera();
}
#Override
protected void onPause() {
super.onPause();
zXingScannerView.stopCamera();
}
#Override
public void handleResult(Result result) {
Toast.makeText(getApplicationContext(), result.getText(),Toast.LENGTH_SHORT).show();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Result");
builder.setMessage(result.getText());
AlertDialog alertDialog = builder.create();
alertDialog.show();
zXingScannerView.resumeCameraPreview(this);
}
}
Call method startActivityForResult(new Intent(this, YourCallbackActivity.class), 1001);
Use setResult() method for get call back in another activity.
#Override
public void handleResult (Result result) {
Intent returnIntent = new Intent();
returnIntent.putExtra("result",String.valueOf(rawResult));
setResult(Activity.RESULT_OK,returnIntent);
finish();
}
now
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1001) {
if (resultCode == RESULT_OK && data != null) {
String result = data.getStringExtra("result");
//do whatever you want
}
}
}
I already did, hope it will help you!!
I have 3 activities that start in a sequence.With the first activity needing a result from the last activity.
I have it so that if Activity B is started for result (By activity A) then Activity B starts activity C for result. Then once the result is captured at activity C it is finished which calls Activity B's onActivityResult which sets the result and finishes and Activity A's onActivityResult gets the final result.
Activity A starts Activity B for a result which Activity C contains thus the sequence is like so
A->B->C (get result) C->B->A (result retrieved)
This works just fine if everything happens in sequence. However, If I navigate to activity C then press the toolbars back arrow and which leads me to activity B then navigate back to activity C and select the result. The result returned to activity A is null.
A->B->C->B->C(get result) C->B->A (result == null)
Activity A
public class AlertCreationActivity extends AppCombatActivity {
// OnCreate methods left out to shorten code
#OnClick(R.id.locationButton)
public void locationButtonClicked() {
Intent intent = new Intent(this, StateActivity.class);
intent.putExtra(StateActivity.IS_STARTED_FOR_RESULT, StateActivity.STARTED_FOR_RESULT);
startActivityForResult(intent, ALERT_CREATION_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ALERT_CREATION_REQUEST_CODE && resultCode == RESULT_OK) {
String title = data.getStringExtra(ALERT_CREATION_REQUEST_DATA);
if ( ! title.isEmpty()) {
mLocationButton.setVisibility(View.INVISIBLE);
mLocationTextView.setText(title);
mLocationTextView.setVisibility(View.VISIBLE);
}
}
}
}
Activity B
public class StateActivity extends AppCompatActivity {
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AlertCreationActivity.ALERT_CREATION_REQUEST_CODE) {
Intent intent = new Intent();
intent.putExtra(AlertCreationActivity.ALERT_CREATION_REQUEST_DATA, data.getStringExtra(AlertCreationActivity.ALERT_CREATION_REQUEST_DATA));
setResult(RESULT_OK, intent);
finish();
}
}
}
Activity B's adapter is where the next intent happens
public class StateAdapter extends RecyclerView.Adapter<StateAdapter.StateViewHolder> {
// Other Adapter methods not shown
public class StateViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// Other View Holder methods not shown
#Override
public void onClick(View v) {
State selectedState = getStateBy(mLocationLabel.getText().toString());
// Save state ID
LocationStorage storage = new LocationStorage(mActivity);
storage.setSelectedStateId(selectedState.getId());
storage.setSelectedStateName(selectedState.getName());
Intent intent = new Intent(mActivity, SpotActivity.class);
mActivity.startActivityForResult(intent, AlertCreationActivity.ALERT_CREATION_REQUEST_CODE);
}
}
}
Activity C
public class SpotActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// Initialize actionbar and recyclerview adapter
// a click on a recyclerview's list item triggers this method
adapter.setSurfSpotSelectedListener(new SurfSpotSelectedListener() {
#Override
public void onSpotSelected(String spotName) {
Intent intent = new Intent();
intent.putExtra(AlertCreationActivity.ALERT_CREATION_REQUEST_DATA, spotName);
setResult(RESULT_OK, intent);
finish();
}
});
}
}
What does navigate back to activity C mean?If you dont start C By startActivityForResult,you will get no result in B.
You should set your result by overriding OnBackPressed(), for example:
#Override
public void onBackPressed() {
setResult(111, new Intent().putExtra("result", "from c"));
super.onBackPressed();
}
For Actionbar, you should overriding onOptionsItemSelected(MenuItem item)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
//here
setResult(111, new Intent().putExtra("result", "from c"));
this.finish();
default:
return super.onOptionsItemSelected(item);
}
}
I ended up solving it by setting the setNavigationOnClickListener for the toolbar in Acitvity B andActivity C and calling onBackPressed() to mimic back navigation. Thanks for all your help Tiny Sunlight and Good Try. Here is my Activity B & C. I hope this helps others.
Activity B
public class StateActivity extends AppCompatActivity {
#Bind(R.id.toolBar) Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spot_selection);
ButterKnife.bind(this);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
// Recyclerview and Adapter left out for brevity
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AlertCreationActivity.ALERT_CREATION_REQUEST_CODE) {
Intent intent = new Intent();
intent.putExtra(AlertCreationActivity.ALERT_CREATION_REQUEST_DATA, data.getStringExtra(AlertCreationActivity.ALERT_CREATION_REQUEST_DATA));
setResult(RESULT_OK, intent);
finish();
}
}
}
Activity C
public class SpotActivity extends AppCompatActivity {
#Bind(R.id.toolBar) Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spot_selection);
ButterKnife.bind(this);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
// Setting up Recyclerview and Adapter omitted
adapter.setSurfSpotSelectedListener(new SurfSpotSelectedListener() {
#Override
public void onSpotSelected(String spotName) {
Intent intent = new Intent();
intent.putExtra(AlertCreationActivity.ALERT_CREATION_REQUEST_DATA, spotName);
setResult(RESULT_OK, intent);
finish();
}
});
}
}