How to set a button to be unclickable forever - android

In my application I have a booking system which allows users to book tee times for specific times during the day. When a booking has been completed the details are saved to my Firebase and the user can then close the alert dialog. When the alert dialog is then closed the button which was clicked is then made unusable. Problem is that when the user leaves the booking activity and comes back the button is then useable, and if a different user then accesses the page the button is also able to be clicked as well.
How do I solve this problem?
Should I be saving the UID of the user in the 9am child ?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_booking);
findViewById(R.id.profilebtn).setOnClickListener(this);
findViewById(R.id.booking9am).setOnClickListener(this);
book9am = (Button)findViewById(R.id.booking9am);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.profilebtn:
finish();
startActivity(new Intent(Booking.this, ProfileActivity.class));
break;
case R.id.booking9am:
final AlertDialog.Builder mBuilder = new AlertDialog.Builder(Booking.this);
View mView = getLayoutInflater().inflate(R.layout.dialog_booking,null);
final EditText mPlayer1 = (EditText) mView.findViewById(R.id.player1);
final EditText mPlayer2= (EditText) mView.findViewById(R.id.player2);
final EditText mPlayer3 = (EditText) mView.findViewById(R.id.player3);
final EditText mPlayer4 = (EditText) mView.findViewById(R.id.player4);
final EditText mTime = (EditText) mView.findViewById(R.id.timeedit);
final Button mBookingbtn = (Button) mView.findViewById(R.id.bookingbtn);
mBookingbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String player1= mPlayer1.getText().toString().trim();
String player2= mPlayer2.getText().toString().trim();
String player4= mPlayer4.getText().toString().trim();
String player3= mPlayer3.getText().toString().trim();
if (player1.isEmpty()) {
mPlayer1.setError("Please enter player 1");
mPlayer1.requestFocus();
return;
}
if (player2.isEmpty()) {
mPlayer2.setError("Please enter player 2");
mPlayer2.requestFocus();
return;
}
if (player3.isEmpty()) {
mPlayer3.setError("Please enter player 2");
mPlayer3.requestFocus();
return;
}if (player2.isEmpty()) {
mPlayer4.setError("Please enter player 2");
mPlayer4.requestFocus();
return;
}
String playerone = mPlayer1.getText().toString();
String playertwo = mPlayer2.getText().toString();
String playerthree = mPlayer3.getText().toString();
String playerfour = mPlayer4.getText().toString();
String teetime= mTime.getText().toString().trim();
DatabaseReference current_user_db = FirebaseDatabase.getInstance().getReference().child("Booking").child("9am");
Map newPost = new HashMap();
newPost.put("playerone",playerone);
newPost.put("playertwo",playertwo);
newPost.put("playerthree",playerthree);
newPost.put("playerfour",playerfour);
newPost.put("teetime",teetime);
current_user_db.setValue(newPost);
Toast.makeText(Booking.this, "Booking Confirmed", Toast.LENGTH_SHORT).show();
book9am.setClickable(false);
}
});
mBuilder.setNeutralButton("Close ", new DialogInterface.OnClickListener() { // define the 'Cancel' button
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
mBuilder.setView(mView);
AlertDialog dialog = mBuilder.create();
dialog.show();
}
}
}

In your onCreate method -
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Booking").child("9am");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
book9am.setClickable(false);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

well there could be multiple approaches to this problem.
One is to set a Boolean variable in local storage Shared preference against every user....
Once your click the button set the value to true and when u come back in app check if variable is true then disable button..
Second solution Store the varible against every user on firebase and check(recommended since user can change phone)

Before showing the activity you will have to make a request to your firebase to check if the booking has been completed and depending on the result make the button enabled or not.

findViewById(R.id.booking9am).setOnClickListener(this) instead of this use:-
book9am = (Button)findViewById(R.id.booking9am);
book9am.setOnClickListener(this);
and instead of book9am.setClickable(false) set book9am.setEnable(false);
OR
If you want button disable on some conditions then it can be managed at server side also.

There are two approaches to your problem, depending on your needs.
First, is saving the button's state locally (on the client side), which means that after removing and re-installing the app for example, the state will be reset as well.
In order to save the button's state "forever", you should save the wanted state on the device, and this is what SharedPreferences is made for.
This is a good example of using it.
Here is how you should implement it in your code:
public static void set_isButtonClickable(Context ctx, Boolean bool) {
SharedPreferences.Editor editor = getSharedPreferences(ctx).edit();
editor.putBoolean("BUTTON_CLICKABLE_STATE", bool);
editor.commit();
}
public static boolean getPrefIsFirstLaunch(Context ctx) {
return getSharedPreferences(ctx).getBoolean("BUTTON_CLICKABLE_STATE",false);
}
Second, is saving the button's state on the server side. Removing and re-installing the app obviously won't change its state. Make each user a variable which called "button_state" and change it as needed:

Related

How to get access of oncreate variable accesss with in the ActivityResultLauncher Method Android

I am using this Barcode Scanner Library Dependenceny in my code.
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
I am working in fragment and in fragment when i click on button there is a dialog appears and in the dialog i have an scan button to can the barcode and want to show the same text inside the the dialog's Textview. My dialog code is inside the oncreate but the ActivityResultLauncher in out of scope so how can i make my dialog variable to be in scope of ActivityResultLauncher. I am very thankful to all of you developer to answer this query.
here is the oncreate code :
fab_addproduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bottomSheetDialog = new BottomSheetDialog(getContext(), R.style.AppBottomSheetDialogTheme);
bottomSheetDialog.setContentView(R.layout.productadd_bottom_sheet);
TextInputEditText product_id = bottomSheetDialog.findViewById(R.id.product_id);
TextInputEditText product_name = bottomSheetDialog.findViewById(R.id.product_name);
TextInputEditText product_quantity = bottomSheetDialog.findViewById(R.id.product_quantity);
MaterialButton add_btn = bottomSheetDialog.findViewById(R.id.add_btn);
ImageView barcode_scanner = bottomSheetDialog.findViewById(R.id.barcode_Scanner);
TextInputEditText product_price = bottomSheetDialog.findViewById(R.id.product_price);
barcode_scanner.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ScanOptions options = new ScanOptions();
options.setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES);
options.setPrompt("Scan a barcode");
options.setCameraId(0); // Use a specific camera of the device
options.setBeepEnabled(true);
options.setBarcodeImageEnabled(true);
barcodeLauncher.launch(options);
}
});
bottomSheetDialog.show();
}
});
here is the ActivityResultLauncher code where the barcode result data is avai
public final ActivityResultLauncher<ScanOptions> barcodeLauncher = registerForActivityResult(new ScanContract(),
result -> {
if(result.getContents() == null) {
Toast.makeText(getContext(), "Cancelled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
** product_id.settext(result.getContents());// this is not accessable i want to make it accessable. here product_id is red in the code.
** }
});
I have tried many ways by using the varaiable static its also show error. i also use binding to make it accessable but i am not able to achieve my goal.

how to add counter in android studio to quit an application

I am getting an error when I set the counter to subtract and close the application. I get an error "cannot assign value to final variable counter". If the user logins in 3 times with no success quit the application.
final int counter = 3;
//Set the OKButton to accept onClick
OKButton.setOnClickListener(new View.OnClickListener() {
#Override
//once onClick is initalized it takes user to page menu
public void onClick(View v) {
//display text that was inputed for userText and passText
user = userText.getText().toString();
pass = passText.getText().toString();
//create if loop which checks if user and pass equals the credentials
if (user.equals("pshivam") && pass.equals("Bway.857661")) {
//display toast access welcome
String welcome = "Access Granted.";
//Create a Toast to display the welcome string in the MainActivity.
Toast.makeText(MainActivity.this, welcome, Toast.LENGTH_SHORT).show();
setContentView(R.layout.account_main);
}
//create else if loop which checks if user or pass does not equals the credentials
else if (!user.equals("pshivam") || !pass.equals("Bway.857661")){
//displays previous entry
userText.setText(user);
passText.setText(pass);
//allows user to re-enter credentials.
user = userText.getText().toString();
pass = passText.getText().toString();
//display toast access fail
String fail = "Access Denied! Please Try again.";
//Create a Toast to display the fail string in the MainActivity.
Toast.makeText(MainActivity.this, fail, Toast.LENGTH_SHORT).show();
counter--;
if(counter == 0){
finish();
}
}
}
});
}
}
Do something like this :
OKButton.setOnClickListener(new View.OnClickListener() {
int counter = 3;
#Override
//once onClick is initalized it takes user to page menu
public void onClick(View v) {
You can also call a function from inside onClick which will decrement the variable, or use a static field declared in your class
This How to increment a Counter inside an OnClick View Event and How do I use onClickListener to count the number of times a button is pressed? might help.
Edit:
What you are doing in else part doesn't make sense. You are setting text for userText and passText that you just got using getText() from these. Then you are storing these same values to user and pass. But you aren't using these variables anywhere and they get new values when onClick is called again. Why not keep it simple :
else {
//display toast access fail
String fail = "Access Denied! Please Try again.";
//Create a Toast to display the fail string in the MainActivity.
Toast.makeText(MainActivity.this, fail, Toast.LENGTH_SHORT).show();
counter--;
if(counter == 0){
finish();
}
}

Return Boolean value from Android AlertDialog function

In my app i have a function that checks the entered text from a displayed AlertDialog with an input text. If the text is equal to a string variable, return True, else return False, and catch this resulting value to continue conditional code.
But it seems its a little difficult to do this as i've read in other posts asking how to solve the same problem.
I've already done this:
private boolean checkAdministratorPassword() {
final enterPasswordResult[0] = false;
AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
alert.setTitle("Confirm action");
alert.setIcon(R.drawable.ic_launcher);
alert.setMessage("Enter administrator pass to continue");
final EditText input = new EditText(mContext);
input.setPadding(5, 0, 5, 0);
alert.setView(input);
alert.setPositiveButton("Accept", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String strPass = input.getEditableText().toString();
if (strPass.length() == 0) {
dialog.cancel();
}
if (strPass.equalsIgnoreCase(Constantes.ADMIN_PASS)) {
enterPasswordResult[0] = true;
dialog.cancel();
} else {
Toast.makeText(mContext, "Invalid pass..!!", Toast.LENGTH_LONG).show();
dialog.cancel();
}
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
AlertDialog alertDialog = alert.create();
alertDialog.show();
return enterPasswordResult[0];
}
And i call the function this way:
If ( checkAdministratorPassword() == True ){
//true conditions
}
But the problem is that the check function doesnt wait for the result to continue with the code, it just continue by itself and i dont get the appropiate behavior.
The issue is you're trying to handle an async event in the logcal flow of your program. You can do this if you make the Dialog it's own class and use an Interface to callback to your host activity. Check out the documentation on DialogFragment.
public interface PasswordCheckListener{
public void valid(boolean check);
}
private static class PasswordDialog extends DialogFragment {
private PasswordCheckListener listener;
public static PaswordDialog newInstance(PasswordCheckListener listener){
this.listener = listener;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//Put your dialog creation code here
}
private checkAdminPassword(){
//Whatever your check passowrd code is
listener.valid(result);
}
}
I realize I didn't implement all the code for you but that's the general idea. By using an interface you can call back to your host Activity or Fragment when the user enters the password and presses submit. You can then handle the event as it happens, rather than having to deal with it in your program flow.
Thank you all for your answers!! i've found the right way to achieve this problem by creating an Activity whith theme "Theme.Dialog", an input text and two buttons (Accept, Cancel), i start this activity for result asking the user to enter the administrator pass to continue, checking the string and then returning again to onActivityResult() from previous activity with the correct information to proceed.

How to transfer parameters value from dialog box to activity in android?

I have an activity (Main) and I inserted a button in it.
When button the user press it, a dialog box with 2 Radio boxes appear. I want to set "1" or "0" value to "ntv", based on which radiobutton is selected, and then use "ntv" value in Main activity, but it seems that this doesnot transfer "ntv" value to Main activity, what is wrong with my code?
final CharSequence[] chan = {"Minutes", "Seconds"};
builder = new AlertDialog.Builder(Main.this);
builder.setTitle("Please Select:");
builder.setSingleChoiceItems(chan, 0, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if(chan[item]=="Minutes")
{
Toast.makeText(getApplicationContext(), "Minutes", Toast.LENGTH_SHORT).show();
ntv="1";
}
else if (chan[item]=="Seconds")
{
Toast.makeText(getApplicationContext(), "Seconds", Toast.LENGTH_SHORT).show();
ntv="0";
}
}
});
AlertDialog alert = builder.create();
alert.show();
I defined "ntv" as string and this is part of code when "ntv" is compared to check if it is "0" or "1"
ImageView set1= (ImageView) findViewById(R.id.set1);
ImageView set2= (ImageView) findViewById(R.id.set2);
if (ntv.equals("0")) {
set1.setVisibility(View.INVISIBLE);
}
if (ntv.equals("1")) {
set2.setVisibility(View.INVISIBLE);
}
and because neither (set1) nor (set2) doesnot go invisible I realize that "ntv" have no value.
This all looks OK (except the suggestion to use equals() instead of == for the string compares, although, as you say, it does work (it just isn't good practice).
The only thing I can think of (without seeing all the code) is that the scope of variable ntv is wrong. Have you declared the variable inside a method? It needs to be defined as an instance variable in your class (ie: not within a method).
you should be doing .equals on the string comparison NOT ==
It is unlikely that your if statements will trigger because of this.
if(chan[item].equals("Minutes"))
{
Toast.makeText(getApplicationContext(), "Minutes", Toast.LENGTH_SHORT).show();
ntv="1";
}
else if (chan[item].equals("Seconds"))
{
Toast.makeText(getApplicationContext(), "Seconds", Toast.LENGTH_SHORT).show();
ntv="0";
}
it's not clear the complete code you use and how you call the code that change visibility. Below an example
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlertDialog.Builder builder;
final CharSequence[] chan = {"Minutes", "Seconds"};
builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Please Select:");
builder.setSingleChoiceItems(chan, 0, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if(chan[item].equals("Minutes")) {
showToast("Minutes");
} else if (chan[item].equals("Seconds")) {
showToast("Seconds");
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
private void showToast(String s){
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
}
instead of showToast function you can use a your function to change visibility

How to use Console in android

Please how can i apply this code to my android application. I am making an application that gives access to the User by entering the correct password.
I seem to be getting an error with the Console
public static void main (String args[]) throws IOException {
Console c=System.console();
String login = c.readLine("Enter your login: ");
char [] oldPassword = c.readPassword("Enter your old password: ");
if (verify(login, oldPassword)) {
boolean noMatch;
do {
char [] newPassword1 =
c.readPassword("Enter your new password: ");
char [] newPassword2 =
c.readPassword("Enter new password again: ");
noMatch = ! Arrays.equals(newPassword1, newPassword2);
if (noMatch) {
c.format("Passwords don't match. Try again.%n");
} else {
change(login, newPassword1);
c.format("Password for %s changed.%n", login);
}
Arrays.fill(newPassword1, ' ');
Arrays.fill(newPassword2, ' ');
} while (noMatch);
}
Arrays.fill(oldPassword, ' ');
}
//Dummy change method.
static boolean verify(String login, char[] password) {
// this method always returns true in this example.
// modify this method to verify password according to your rules.
return true;
}
//Dummy change method.
static void change(String login, char[] password) {
// modify this method to change password according to your rules.
}
}
Yes you can re-use your verify and change apis for android but you have discard whatever in the main method.
On Android, you will be creating an Activity having three EditText (for hide user text use android:inputType="textPassword"), one for each.
Old Password
New Password
New Password Again
Then you ll have one button call it Change Password. To this Change Password button you can add onClickListenr. When user presses this Change Password button, you will fetch the text values from EditText and then user your verify and change apis to do the actual work.
You can optionally choose a Cancel button too.
Below is how screen will look:
Snippet of handling the Change button:
// Declared in your Activity class.
EditText editTextOldPass;
EditText editTextNewPass;
EditText editTextNewPassAgain;
String login = "";
public void onCreate(Bundle savedInstanceState) {
editTextOldPass = (EditText) findViewById(R.id.editTextOldPass);
editTextNewPass = (EditText) findViewById(R.id.editTextNewPass);
editTextNewPassAgain = (EditText) findViewById(R.id.editTextNewPassAgain);
Button buttonChange = (Button) findViewById(R.id.buttonChange);
buttonChange.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (editTextNewPass.getText().equals(editTextNewPassAgain)) {
if (verify(login, editTextOldPass.getText().toString().toCharArray()))
change(login, editTextNewPass.getText().toString().toCharArray());
} else {
Log.i("PasswordActivity", "Passwords don't match. Try again.");
}
}
});
}

Categories

Resources