I have a method which retrieves an array of user requests. I iterate through this array, showing a Dialog with positive and negative buttons. When the last Dialog has been confirmed whether with yes or no, a httppost is sended to a server to process the data. I builded up the function like this:
private void processRequests(String resJSON){
try {
JSONArray array = new JSONArray(resJSON);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Neue Herausvorderung");
builder.setCancelable(false);
final int ARRAY_LENGTH = array.length();
for(int i=0; i<array.length(); i++){
JSONObject obj = array.getJSONObject(i);
final String NAME= obj.getString("userName");
final long ID= obj.getLong("userID");
final int INDEX= i;
builder.setMessage(name + " fordert dich zu einem Duell heraus! Willst du annehmen?");
builder.setPositiveButton("JA", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
acceptedUsers.add(new User(ID, NAME));
if(INDEX== ARRAY_LENGTH-1){
sendRequestStuff();
}
}
});
builder.setNegativeButton("NEIN", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
declinedUsers.add(new User(ID, NAME));
if(INDEX== ARRAY_LENGTH-1){
sendRequestStuff();
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The problem is, as soon as the first Dialog is confirmed, sendRequestStuff() gets called. I suspect the Listeners to cause the bug, but I am not sure. How can this be solved?
You send the request after getting a response from the last dialog: if(INDEX== ARRAY_LENGTH-1).
Because you are running a loop over the whole array (from 0 to ARRAY_LENGTH-1) and show a dialog for each, the dialogs will be shown in this order: 0, 1, 2, 3, ...., ARRAY_LENGTH-1, which means that the last one that will be shown is ARRAY_LENGTH-1. This is the first dialog that you confirm/decline, and when you do it, you actually make a callback for setPositiveButton or setNegativeButton, and (INDEX== ARRAY_LENGTH-1) is true.
To solve this, just change the condition in the callbacks: if(INDEX == 0).
Related
I practice in creating an app using a movie API.
The idea is :
1- user input the movie name .
2- take this name and putting it in a link form like:
Constants.URL_LEFT + searchTerm + Constants.URL_RIGHT + Constants.API_KEY
And here I have two probabilities:
1- the input word are correct and match a movie name e.g ("Batman"), then every thing is right.
2- the input word are incorrect e.g ("Bamtan"), then I have error message
"No value for search"
Note :
1- I try to use onErrorResponse() method but it works in noInternetConnection only!
2- I try to solve the problem using try/catch , My App stayed in the catch area!
My Question is :
How could I handle the incorrect input (Wrong URL)?
Here is my code for that :
public List<Movie> getMovies(final String searchTerm){
movieList.clear();
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET, Constants.URL_LEFT + searchTerm + Constants.URL_RIGHT + Constants.API_KEY,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray moviesArray = response.getJSONArray("Search");
for (int i = 0 ; i < moviesArray.length() ; i++){
JSONObject movieObj = moviesArray.getJSONObject(i);
Movie movie = new Movie();
movie.setTitle(movieObj.getString("Title"));
movie.setYear(" Released on : " + movieObj.getString("Year"));
movie.setMovieType("Type : " + movieObj.getString("Type"));
movie.setPoster(movieObj.getString("Poster"));
movie.setImdbId(movieObj.getString("imdbID"));
movieList.add(movie);
}
// notify the adapter for changes! very important...
movieRecyclerViewAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
// app just save the exception and repeat it after that for correct values also!
if (e.getMessage().equals("No value for Search")){
Toast.makeText(MainActivity.this, "Can not find any movie with this name!", Toast.LENGTH_SHORT).show();
MainActivity.this.onRestart();
popupDialog();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// dealing with losing network connection
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilder.setTitle("Error Found!")
.setMessage("Make Sure you have a network Connection!")
.setCancelable(false);
alertDialogBuilder.setPositiveButton("Refresh", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// re-check the internet connection!
getMovies(searchTerm);
}
})
.setNegativeButton("Exit!", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// close the App!
finish();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
});
queue.add(objectRequest);
return movieList;
}
Many Thanks in Advance!
Check if moviesArray is null after JSONArray moviesArray = response.getJSONArray("Search");, if its null that would mean the search was not found and its not present in the json response and you can display your message saying movie is not found.
Below is how it looks with the changes
JSONArray moviesArray = response.getJSONArray("Search");
if(moviesArray==null){
Toast.makeText(MainActivity.this, "Can not find any movie with this name!", Toast.LENGTH_SHORT).show();
}
else
{
for (int i = 0 ; i < moviesArray.length() ; i++){
JSONObject movieObj = moviesArray.getJSONObject(i);
Movie movie = new Movie();
movie.setTitle(movieObj.getString("Title"));
movie.setYear(" Released on : " + movieObj.getString("Year"));
movie.setMovieType("Type : " + movieObj.getString("Type"));
movie.setPoster(movieObj.getString("Poster"));
movie.setImdbId(movieObj.getString("imdbID"));
movieList.add(movie);
}
// notify the adapter for changes! very important...
movieRecyclerViewAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
First of all , Thanks to #Psypher and #GautamSurani for helping .
The problem fixed by:
1- Remove the new update of HAXM and install old version and create a new virtual Device.
2- update if(moviesArray==null) which I wrote above with if (!response.has("Search")) cause of response always having response!
what I think
The Emulator saves the last error value of SharedPreferences (Which entered by the user) and keep it on even if The user entered a correct one.
In one of my Activity there are some calculations and total price will be calculated.After pressing the submit button it should show an alert dialog with Are you sure you want to pay Rupees:XXX...? here XXX should be the final price which I'm storing in the variable.
in alertdialog.setTitle() I should able to access the variable.
Please help me to solve this.
public void onPay()
{
getItems();
int rate = 0;
if(spare1_item.equals("Tyres") || qty_1.equals("Quantity"))
{
}
else
{
//Toast.makeText(getApplicationContext(), "Now you can pay", 5000).show();
db = this.openOrCreateDatabase("mobile_cycle_clinic", MODE_PRIVATE, null);
c = db.rawQuery("select price from sparelist where name = '"+spare1_item+"'", null);
if(c.moveToNext())
{
do{
price = c.getInt(c.getColumnIndex("price"));
}
while(c.moveToNext());
}
fianl1_qty = Integer.parseInt(qty_1);
rate = rate + price * fianl1_qty;
db.execSQL("insert into spares_items(cycle_id,item_name,quantity,total_price)values('"+cycle_id+"','"+spare1_item+"',"+fianl1_qty+","+rate+")");
//Toast.makeText(getApplicationContext(), ""+rate, 5000).show();
}
Here rate is a static variable and in another method I should use that variable in alertDialog.setMeaasge().
public void storeData(View v)
{
cycle_id = id.getText().toString();
if(cycle_id.equals("") || cycle_id.equals("null"))
{
Toast.makeText(getApplicationContext(), "Please Scan Cycle",5000).show();
}
else
{
AlertDialog.Builder pauseBuild = new AlertDialog.Builder(this);
pauseBuild.setTitle("Pay Alert");
pauseBuild.setMessage("Do you really want to Pay..?"+rate);
pauseBuild.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
//time = sdf.format(new Date());
onPay();
finish();
return;
} });
pauseBuild.setNegativeButton("No",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// show it
pauseBuild.show();
}
You can use a function to show or create the AlertDialog.
For example:
private void showConfirmAlertDialog(int price) {
AlertDialog.Builder builder = new AlertDialog.Builder();
builder.setTitle("Are you sure you want to pay rupees: " + price);
....
builder.show();
}
If you perfer getting an instance of AlertDialog, you can change the function to private AlertDialog createConfirmAlertDialg(int price), and use return builder.create(); at the end of function.
I am creating a custom Hash map array adapter.In that,when the user clicks on an element, an AlertDialog pops up,in that user can see his messaages,
For this I am using this code,
final AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("PassWord Protected Message");
alert.setMessage("Please Enter The Password to See The Messages");
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int whichButton)
{
// Editable value = input.getText();
// Do something with value!
String we=input.getText().toString();
// Toast.makeText(getApplicationContext(), we, Toast.LENGTH_SHORT ).show();
if (we.equalsIgnoreCase("password"))
{
try
{
String[] splitted = smsList.get( pos ).split("\n");
String sender = splitted[0];
for ( int i = 1; i < splitted.length; ++i )
{
//some code here
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
This AlertDialog will ask user to enter a password.Then user will be able to see the messages.
But I am getting error ,
String[] splitted = smsList.get( pos ).split("\n");
In this,I am getting error on split function and the error is "The method split(String) is undefined for the type HashMap".
You'll have to type cast the smsList to String
String[] splitted = ((String)smsList.get( pos )).split("\n");
I created a Dialog with a TextEdit as a number input to convert it to a double value.
I want to prevent an exception by checking, if the TextEdit input is empty but it always jumps to the else statement and therefore creates an exception when the EditText is blank.
final Builder builder = new Builder(this);
final EditText input = new EditText(this);
input.setKeyListener(DigitsKeyListener.getInstance(false, true));
builder
.setTitle(R.string.dialog_title_addmark)
.setMessage(R.string.dialog_addmark)
.setView(input)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (input.toString().trim().length() == 0) {
Toast.makeText(Marks.this, R.string.input_empty, Toast.LENGTH_SHORT).show();
} else {
Double value = Double.valueOf(input.getText().toString());
db.insertMark(selection, value);
getData();
}
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
I also tried it checking
(input.toString() != null)
but that does not work either.
Thanks for your help
If you want the text from a EditText object, you should use the following line of code:
input.getText().tostring();
where input is a EditText-object.
Using the code
input.toString();
will give you a string representation of the object, and as long as the object is not null, the toString of that object will be not null, so using input.toString() != null will not give you any useful information.
That means that you should do the following validation:
if (input.getText().toString().trim().length() == 0) to figure out if the input object contains some text.
Try this way..
if (input.toString().trim().length()< 0) {
Toast.makeText(Marks.this, R.string.input_empty, Toast.LENGTH_SHORT).show();
} else {
Double value = Double.valueOf(input.getText().toString());
db.insertMark(selection, value);
getData();
}
input.toString() will return the reference value of the Edittext not the text inside the Edittext.
Use below condition
if(input.getText().toString() != null || !input.getText().toString().isEmpty())
I want to delete an array index from an array, then reload listView with my new array and then write a string to an existing file in android. I am using following code:
OnItemLongClickListener longClickListener = new OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
itemPosition = position;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Warning");
alertDialogBuilder
.setMessage("Are you sure?")
.setCancelable(false)
.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
ArrayList<String> itemsList = new ArrayList<String>();
for(int i=0; i<items.length; i++){
itemsList.add(items[i]);
}
itemsList.remove(itemPosition);
items = new String[itemsList.size()];
for(int i=0; i<itemsList.size(); i++){
items[i] = itemsList.get(i);
}
adapter.notifyDataSetChanged();
String newData = "";
for(int i=0; i<items.length; i++){
newData = newData+items[i];
if(i < items.length-1){
newData = newData+"NEXTLINE";
}
}
// write string to existing file
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(newData.getBytes());
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
})
.setNegativeButton("No",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
return true;
}
};
when i click yes on alert then my app doesn't respond and after some time my phone ask to kill the app? Can anybody please tell me that whats wrong with this code? thanks in advance.
the problem is in following snippt of code... MIght be your list have a too lagre of size and you are looping it thrice and in between you are also refreshing on list.
ArrayList<String> itemsList = new ArrayList<String>();
for(int i=0; i<items.length; i++){
itemsList.add(items[i]);
}
itemsList.remove(itemPosition);
items = new String[itemsList.size()];
for(int i=0; i<itemsList.size(); i++){
items[i] = itemsList.get(i);
}
adapter.notifyDataSetChanged();
String newData = "";
for(int i=0; i<items.length; i++){
newData = newData+items[i];
if(i < items.length-1){
newData = newData+"NEXTLINE";
}
Try to debug and reduce code and loop on this click ...