OK my question is a lot bigger than the Title. But can't describe everything in a Title. So here we go.
I am writing an App that when a NFC cards get detected by Phone, it will be able to WRITE and READ a NDEF message on / from it.
I use two buttons READ and WRITE to trigger these events. Everything works fine, just the thing that EVERYTHING REPEATS ITSELF FOUR (4x) TIMES!
Only the TAG "UltraLightCard Detected" and "Connected" pops once.
Everything else that you see in code in "ShowMessage" will pop out 4x times also the AlertDialog box gets triggered 4x times and you have to write the text 4 times.
If you wrote it only once and then clicked "Save" 3x times just to close it, it wont store the string.
Here's my code:
protected void ultralightCardLogic() {
final Button b_write = (Button)findViewById(R.id.b_write);
final Button b_read = (Button)findViewById(R.id.b_read);
b_write.setId(1);
b_read.setId(2);
//showImageSnap(R.drawable.ultralight);
ShowMessage("UltraLight Card Detected :" + mifareUL.getTagName(), 'a');
try {
mifareUL.connect();
mifareUL.formatT2T();
ShowMessage("Connected!" , 'd');
b_write.setOnTouchListener(new MyTouchListener());
b_read.setOnTouchListener(new MyTouchListener());
} catch (IOException e) {
e.printStackTrace();
}
}
Here is MyTouchListener:
public class MyTouchListener implements OnTouchListener{
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stu
int id = v.getId();
switch(id){
case 1:
onCreateDialog();
break;
case 2:
readNDEFmsg();
break;
case 3:
break;
}
return false;
}
}
Here is the OnCreateDialog:
final View v = getLayoutInflater().inflate(R.layout.dia_box,null);
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setView(v)
.setPositiveButton("SAVE", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int id) {
// TODO Auto-generated method stub
final EditText mEdit=(EditText)v.findViewById(R.id.et_dia);
String str = mEdit.getText().toString();
writeNDEFmsg(str);
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
If you guys need some more of the code, I can add it then. Don't want to write too much code, because my experience tells me that then noone will try to help me out.
Please, help me out
Thanks to your help I figured out my issue.
I used onTouchListener, which triggers more than once, since it has more MotionEvents available.
After I changed on to OnClickListener everything works smoothly!
Just be sure to implement View.OnClickListener
if you are doing it like I do in my public class MyClickListener.
Then Eclipse will auto-generate your necessary code. Extract the id of your buttons and do the switch statement (again, if you`re doing it this way):
public class MyClickListener implements android.view.View.OnClickListener{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int id = v.getId();
switch(id){
case 1:
onCreateDialog();
break;
case 2:
readNDEFmsg();
break;
case 3:
break;
}
}
Thanks again for the help! Hope it will help someone else too.
Related
I'm working on a soundboard and I want to implement a long click to share the sound.
I am working with a switch Case for each button
public void MainMMP(View view){
switch (view.getId()) {
case R.id.button1:
MainMMP.release();
MainMMP = MediaPlayer.create(this, R.raw.xxx1);
MainMMP.start();
break;
case R.id.button2:
MainMMP.release();
MainMMP = MediaPlayer.create(this, R.raw.xxx2);
MainMMP.start();
break;
case R.id.button3:
MainMMP.release();
MainMMP = MediaPlayer.create(this, R.raw.xxx3);
MainMMP.start();
break;
And now I want to implement the long click. I tried a lot of different code here but it is not working for me.
I do not know where to put the onLongClick statement and how.
Can somebody show me a working method and in case of long click it should just send me a Toast that I know the method works?
You could add the OnLongClickListener where you want, in the onCreate method for example.
Try to use the following code:
Button button = (Button)findViewById(R.id.button);
button.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//Your code
return false; // True if you want to execute simple click code too
}
});
You can use this
private View.OnLongClickListener listener = new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
switch (view.getId())
case R.id.button1:
// Do something...
break;
case R.id.button2:
// Do something else...
break;
// If you still want to get normal click callbacks return true,
// if you do not then return false.
return true;
}
}
Somewhere in your code
Button button1 = (Button)findViewById(R.id.button1);
Button button2 = (Button)findViewById(R.id.button2);
button1.setOnLongClickListener(listener);
button2.setOnLongClickListener(listener);
Or better this
One common recommended way to get onClick/onLongClick/whatever callbacks is to make the Activity implement the callback interfaces.
class YourActivity extend Activity implements View.OnLongClickListener {
#Override
public boolean onCreate(/* ... */) {
// ...
button1.setOnLongClickListener(this);
button2.setOnLongClickListener(this);
}
#Override
public boolean onLongClick(View view) {
// Same code as the one above
}
}
Okay so I have this message popup that asks the user to kindly rate the app. They can choose Yes or No. If Yes is pressed, the app in the app store will be opened. If no is pressed, the dialog box closes (for now). I want it so that if Yes is pressed, the dialog box will no longer ever show (even if the user only presses yes but does not actually rate the app..) even after they close and re-open the app.
The purpose of this is so that the user doesn't keep getting asked to rate the app even when they may have already done that.
Dialog Class:
public class CustomDialogClass extends Dialog implements
android.view.View.OnClickListener {
public Activity c;
public Dialog d;
public Button yes, no;
public CustomDialogClass(Activity a) {
super(a);
// TODO Auto-generated constructor stub
this.c = a;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.custom_dialog);
yes = (Button) findViewById(R.id.btn_yes);
no = (Button) findViewById(R.id.btn_no);
yes.setOnClickListener(this);
no.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_yes:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=com.nianticlabs.pokemongo&hl=en"));
getContext().startActivity(intent);
dismiss();
break;
case R.id.btn_no:
dismiss();
break;
default:
break;
}
dismiss();
}
}
(I know the link is for pokemon go lol its just for trial purposes.)
any help will be greatly appreciated :)
________edit_______
code where i show the dialog (occurs when the user enters a specific class):
public class Final1 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.final1);
CustomDialogClass cdd=new CustomDialogClass(Final1.this);
cdd.show();
You may need to store a state about whether the user pressed YES button. And before you want to show your dialog, check the state.
Since you only need a Boolean value, SharedPreferences is recommended.
It would be helpful if I could see where you show the actual dialog box, the code you provide for that only goes to the market page again... but we can still work with this.
If you want to never show this box to the user again, I recommend using SharedPreferences. This will enable us to store (basically) permanent variables.
Example:
SharedPreferences settings = getContext().getSharedPreferences("your-app", 0);
if(settings.getBoolean("btn_pressed", false)){
//show dialog
}
This will make sure the dialog doesn't open if we have the Shared Preferences boolean "btn_pressed" set to true.
To set this boolean after the yes button is pressed:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_yes:
SharedPreferences.Editor edit = c.getSharedPreferences("your-app", 0).edit();
edit.putBoolean("btn_pressed", true);
edit.apply();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=com.nianticlabs.pokemongo&hl=en"));
getContext().startActivity(intent);
dismiss();
break;
case R.id.btn_no:
dismiss();
break;
default:
break;
}
dismiss();
}
Shared Preferences is an easy way for your app to remember permanent user settings or things of this nature. Hope this helps!
EDIT: please note syntax correction, the editor has a capital (SharedPreferences.editor becomes SharedPreferences.Editor)
It's supposed to be a very common thing: having dialog boxes to confirm to proceed the flow of the interaction with users. But the best I can come up with with the information I've dug doesn't seem good to me. I primarily extended DialogFragment (following the first searches for examples) and implement the NoticeDialogListener.
I came to believe that this is not the better way because as far as program flow is concerned, it's very cumbersome. Program flow-wise I understand it can be cumbersome anyway as Dialog appears as another thread from the main to begin with, but I suppose there should be a better way to assign different responding method to different dialog. But I haven't been able to find a way except what's following.
Hopefully I've described my question clearly. Thanks in advance for the response.
public class Confirm extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(sQ);
builder
.setPositiveButton(sYes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mListener.Yes();
}
})
.setNegativeButton(sNo, null);
return builder.create();
}
public interface NoticeDialogListener {
void Yes();
}
private NoticeDialogListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = (NoticeDialogListener) activity;
}
}
public class Main extends ActionBarActivity
implements Confirm.NoticeDialogListener {
...
private int iDialogMode;
private final static int DIALOG_ST_0 = 0;
private final static int DIALOG_ST_1 = DIALOG_ST_1 + 1;
private final static int DIALOG_ST_2 = DIALOG_ST_1 + 1;
#Override
public void Yes() {
switch (iDialogMode) {
case DIALOG_ST_0: // follow up HERE0 for what that dialog prompted
break;
case DIALOG_ST_1: // HERE1: feeling not smart
break;
case DIALOG_ST_2: // HERE2: believe there should be a better way
break;
}
}
public ... State_0_doing_something (...) {
...
Confirm diaBox = new Confirm (...);
iDialogMode = DIALOG_ST_0;
diaBox.show(getSupportFragmentManager(), "State_0");
// what's supposed to continue if confirmed will be followed up in HERE0 in Yes()
}
public ... State_1_doing_something_else (...) {
...
Confirm diaBox = new Confirm (...);
iDialogMode = DIALOG_ST_1;
diaBox.show(getSupportFragmentManager(), "State_2");
// what's supposed to continue if confirmed will be followed up in HERE1 in Yes()
}
public ... State_2_doing_yet_something_else (...) {
...
Confirm diaBox = new Confirm (...);
iDialogMode = DIALOG_ST_2;
diaBox.show(getSupportFragmentManager(), "State_3");
// what's supposed to continue if confirmed will be followed up in HERE2 in Yes()
}
}
I am thinking if I can attach a different click listener to each Confirm dialog box created instead of setting the dialog mode/state using global variable/member like that. Am missing function pointers here...
"By the way, how come I couldn't properly post the beginning declaration and ending bracket in the grey box? "
Add 4 blank spaces before that text, or add the ` character at the beggining and end of the code text.
Example:
Fake code that does nothing
"Program flow-wise I understand it can be cumbersome anyway as Dialog appears as another thread from the main to begin with"
This is basically why its not intended for the user to keep on using dialog boxes. The way I saw most programs so far, is that only actions that could severely delay the application or that could possibly charge the user would use dialogs.
Also, note the Activity lifecycle will make you keep its "state" remembered, this can further add to issues with onPause/onResume with your app.
Solved: the only problem is that it's not as nice looking
AlertDialog.Builder builder = new AlertDialog.Builder(Home.theContext);
builder.setMessage(R.string.confirm_delete);
builder.setCancelable(true);
builder.setPositiveButton(R.string.confirm_yes, vCabDelete());
builder.setNegativeButton(Home.theContext.getString(R.string.confirm_no), null);
AlertDialog dialog = builder.create();
dialog.show();
....
private static DialogInterface.OnClickListener vCabDelete() {
return new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di, int id) {
....
}
};
}
I'm having troubles with a custom Dialog in Eclipse.
in the first place, I created a Class that extend Dialog.
public class ModificarGrupoBCDialog extends Dialog {
private static final int CANCELAR = 999;
private static final int MODIFICAR = 1;
...
somewhere I create the buttons...
protected void createButtonsForButtonBar(Composite parent) {
this.createButton(parent, MODIFICAR, "Modificar", true);
this.getButton(MODIFICAR).setEnabled(puedeAltaGrupoBC());
this.bt_ok = this.getButton(MODIFICAR);
this.createButton(parent, CANCELAR, "Cancelar", false);
Display display = window.getShell().getDisplay();
Image image = new Image(display, ModificarGrupoBCDialog.class.getResourceAsStream("/icons/modificar.png"));
this.getButton(MODIFICAR).setImage(image);
image = new Image(display, ModificarGrupoBCDialog.class.getResourceAsStream("/icons/cancelar.png"));
this.getButton(CANCELAR).setImage(image);
}
and when the user clicks...
protected void buttonPressed(int buttonId) {
switch (buttonId) {
case MODIFICAR:
// Some Code, for Change Button
break;
case CANCELAR:
setReturnCode(CANCELAR);
close();
break;
}
Finally, this is how I open and get the returnCode, in the caller object.
...
ModificarGrupoBCDialog modificarGrupoBC = new ModificarGrupoBCDialog(window.getShell(), window, gr_bc);
if (modificarGrupoBC.getReturnCode() == Window.OK) {
//... Some code on OK
} else {
//another code when cancel pressed.
}
;
as you can see, after trying a while, I have to write setReturnCode() in CANCELAR switch block, is that OK ?
I spect that Dialog class automatically asign the correct return code.
May be someone could point me to a good sample.
I'm reading Vogela's blog, and may be the solution is to override okPressed() method ?
Best Regards.
The standard dialog sets the return code in two places:
protected void okPressed() {
setReturnCode(OK);
close();
}
protected void cancelPressed() {
setReturnCode(CANCEL);
close();
}
so your code doing:
setReturnCode(xxxx);
close();
should be fine as long as the button id you are using does not match the Cancel or OK button ids.
You could also use the approach used by MessageDialog which simply does this:
protected void buttonPressed(int buttonId) {
setReturnCode(buttonId);
close();
}
I have over 900 lines in my MainActivity because I can't figure out how to make other classes work.
It works but it makes it hard to read and tedious to update.
I will give an example of what I would want to separate to another class.
I would like to call this from the main activity.
MainActivity:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.apm:
apm();
return true;
}
}
public void apm() {
AlertDialog levelDialog;
final CharSequence[] items = {" Reboot ", " Reboot Recovery ", " Hot Reboot "};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("What do you want to do?");
builder.setCancelable(true);
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch (item) {
case 0:
rooted();
reboot();
break;
case 1:
rooted();
recovery();
break;
case 2:
rooted();
softreboot();
break;
//case 3:
//shutdown();
//break;
}
}
});
levelDialog = builder.create();
levelDialog.show();
}
Create a new class called Util (for example) in a new file, Util.java.
In this class put:
public static void apm(MainActivity activity){
//Put the code from your old apm method here.
//Whenever you need to call a method that is part of MainActivity
//just prepend activity. in front of the method call.
}
Then in MainActivity, call Util.apm(this);.
EDIT:
Here's more detail. Put the following in Util.java and call Util.apm(this); in your MainActivity.
public static void apm(MainActivity activity) {
AlertDialog levelDialog;
final CharSequence[] items = {" Reboot ", " Reboot Recovery ", " Hot Reboot "};
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("What do you want to do?");
builder.setCancelable(true);
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch (item) {
case 0:
activity.rooted();
activity.reboot();
break;
case 1:
activity.rooted();
activity.recovery();
break;
case 2:
activity.rooted();
activity.softreboot();
break;
//case 3:
//activity.shutdown();
//break;
}
}
});
levelDialog = builder.create();
levelDialog.show();
}
you can write your apm method in another class. From your mainActivity, you can instanciate that class and pass the context of the activity to the constructor of the class.
then from mainActivity, just call the methods of that class using the class instance.
I hope you understand what I try to say. In your new class, you can access mainActivity components using the context you received in constructor.