I am trying to perform simple form validation whereby I use EditText.setError() to notify the user of the wrong input or blank field. Unfortunately, when I do that it only shows error when I click on the field again after incomplete form submission. This is weird because I want it to show as soon as I click button and form incomplete.
I believe it has something to do with the placement of the code that does the validation? Following is my code:
public class AddDiscountActivity extends Activity implements OnItemSelectedListener{
String shopCategory;
Spinner spinner;
String shopName;
String shopCity;
String shopLocation;
String discountRate;
String discountDuration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.adddiscount_activity);
spinner = (Spinner) findViewById(R.id.categoriesSpinner);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.categoriesArray, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}
public void SubmitData(View view)
{
new PostDataAsyncTask().execute();
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
{
// TODO Auto-generated method stub
shopCategory = spinner.getItemAtPosition(pos).toString();
Log.v("SHOP CATEGORY***********: ", shopCategory);
}
public class PostDataAsyncTask extends AsyncTask<String, String, String>
{
ProgressDialog progressDialog;
#Override
protected void onPreExecute()
{
progressDialog= ProgressDialog.show(AddDiscountActivity.this, "Please Wait","Update Ads listings", true);
//do initialization of required objects objects here
};
#Override
protected String doInBackground(String... strings) {
// TODO Auto-generated method stub
try {
postAdData();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String lenghtOfFile) {
// do stuff after posting data
super.onPostExecute(lenghtOfFile);
progressDialog.dismiss();
//Intent intent = new Intent(MainActivity.this, ThankYouAcitivty.class);
// startActivity(intent);
}
}
private void postAdData() throws JSONException{
try{
// url where the data will be posted
String postReceiverUrl = "http://hye.com/displaypost.php";
// HttpClient
HttpClient httpClient = new DefaultHttpClient();
// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
//All user input
EditText shopNameEditText = (EditText)findViewById(R.id.shopName);
EditText shopLocationEditText = (EditText)findViewById(R.id.shopLocation);
EditText shopCityEditText = (EditText)findViewById(R.id.shopCity);
EditText discountRateEditText = (EditText)findViewById(R.id.shopDiscount);
EditText discountDurationEditText = (EditText)findViewById(R.id.shopDiscountDuration);
shopNameEditText.getText().toString();
shopLocationEditText.getText().toString();
shopCityEditText.getText().toString();
discountRateEditText.getText().toString();
discountDurationEditText.getText().toString();
/*******Fields Validation*********/
if(shopNameEditText.getText().toString().length() == 0)
shopNameEditText.setError("يجب ادخال اسم المحل");
if(shopLocationEditText.getText().toString().length() == 0)
shopLocationEditText.setError("يجب ادخال العنوان");
if(shopCityEditText.getText().toString().length() == 0)
shopCityEditText.setError("يجب ادخال المدينة");
if(discountRateEditText.getText().toString().length() == 0)
discountRateEditText.setError("يجب ادخال نسبة التخفيض");
/*********************************/
nameValuePairs.add(new BasicNameValuePair("name", shopName));
nameValuePairs.add(new BasicNameValuePair("location", shopLocation));
nameValuePairs.add(new BasicNameValuePair("city", shopCity));
nameValuePairs.add(new BasicNameValuePair("rate", discountRate));
nameValuePairs.add(new BasicNameValuePair("duration", discountDuration));
nameValuePairs.add(new BasicNameValuePair("category", shopCategory));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
String responseStr = EntityUtils.toString(resEntity).trim();
Log.v("", "Response: " + responseStr);
// you can add an if statement here and do other actions based on the response
}
} catch (IOException e) {
e.printStackTrace();
}
}
try by putting // All user input // // Fields Validation // inside public void SubmitData(View view) and use if{} else{}
you will Also get null pointer Exception because you are not assigning any value to
String shopName;
String shopCity;
String shopLocation;
String discountRate;
String discountDuration;
so your public void SubmitData(View view) should be like :
public void SubmitData(View view)
{
//All user input
EditText shopNameEditText = (EditText)findViewById(R.id.shopName);
EditText shopLocationEditText = (EditText)findViewById(R.id.shopLocation);
EditText shopCityEditText = (EditText)findViewById(R.id.shopCity);
EditText discountRateEditText = (EditText)findViewById(R.id.shopDiscount);
EditText discountDurationEditText = (EditText)findViewById(R.id.shopDiscountDuration);
if(shopNameEditText.getText().toString().length() == 0)
shopNameEditText.setError("يجب ادخال اسم المحل");
else if(shopLocationEditText.getText().toString().length() == 0)
shopLocationEditText.setError("يجب ادخال العنوان");
else if(shopCityEditText.getText().toString().length() == 0)
shopCityEditText.setError("يجب ادخال المدينة");
else if(discountRateEditText.getText().toString().length() == 0)
discountRateEditText.setError("يجب ادخال نسبة التخفيض");
else
{
shopName = shopNameEditText.getText().toString();
shopLocation = shopLocationEditText.getText().toString();
shopCity = shopCityEditText.getText().toString();
discountRate = discountRateEditText.getText().toString();
discountDuration = discountDurationEditText.getText().toString();
new PostDataAsyncTask().execute();
}
}
What I would recommend doing is using TextWatcher. If you do it this way, I believe these steps will help:
First, implement android.text.TextWatcher
Second, implement the necessary methods, most importantly, afterTextChanged(Editable)
Third, add textlisteners for your EditText's
For example...
EditText shopNameEditText = (EditText)findViewById(R.id.shopName);
shopNameEditText.addTextChangedListener(this);
#Override
public void afterTextChanged(Editable s) {
//check validation
if(shopNameEditText.getText().toString().length() == 0){
...
}
}
This is the expected behavior. Note that EditText extends the TextView class. And, the method that you are using: setError(CharSequence) is inherited by EditText from TextView.
Here is what it is designed to do:
Sets the right-hand compound drawable of the TextView to the "error"
icon and sets an error message that will be displayed in a popup when
the TextView has focus. The icon and error message will be reset to
null when any key events cause changes to the TextView's text. If the
error is null, the error message and icon will be cleared.
When the click is encountered, the EditText loses focus and waits until it regains focus to post the error.
To show the user that an error has occured, instead of calling setError(CharSequence), you can set warning text inside the EditText using myEditText.setText("Required"). You can also call requestFocus() on the EditText to show the error immediately after setError(CharSequence), but I am not sure how this would behave in case of 2 or more errors.
Related
I need to delete a list item from listview on clicking a delete button in android eclipse. The list values are populated from mysql database(JSON), so on deleting, I need to delete the same from database also.
Here is my main Activity; I need to delete a listitem from a listview on clicking a delete button on each item in the listview:
public class MainActivity extends Activity implements AsyncResponse2 {
private ProgressDialog dialog;
ListView l1;
//for getting count
TextView count;
private static final String TAG_COUNT = "cnt";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //to hide title bar
setContentView(R.layout.activity_main);
l1=(ListView)findViewById(R.id.listView1);
/** Reference to the delete button of the layout main.xml */
Button btnDel = (Button) findViewById(R.id.deleteid);
initView();
//str for getting count
count=(TextView)findViewById(R.id.countid);
//to display count while loading(so outside buttonclick)
String key1 = "saasvaap123";
String signupid1 = "8";
String url2 = "http://gooffers.in/omowebservices/index.php/webservice/Public_User/saved_offers_list?";
//http://gooffers.in/omowebservices/index.php/webservice/Public_User/saved_offers_list?key=saasvaap123&signup_id=8
//put the below lines outside button onclick since we load the values into edittext when opening the app
CustomHttpClient2 task2 = new CustomHttpClient2();
task2.execute(url2,key1,signupid1);
task2.delegate = MainActivity.this;
//end
}
//str getting count
//str customhttp2
private class CustomHttpClient2 extends AsyncTask<String, String, String>{
public AsyncResponse2 delegate=null;
private String msg;
#Override
protected void onPostExecute(String result2) {
// TODO Auto-generated method stub
super.onPostExecute(result2);
delegate.processFinish2(result2);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
if(params == null) return null;
// get url from params
String url2 = params[0];
String key1 = params[1];
String signupid1 = params[2];
ArrayList<NameValuePair> postParameters;
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("key",key1));
postParameters.add(new BasicNameValuePair("signup_id",signupid1));
try {
// create http connection
HttpClient client = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url2);
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// connect
HttpResponse response = client.execute(httppost);
// get response
HttpEntity entity = response.getEntity();
if(entity != null){
return EntityUtils.toString(entity);
}
else{
return "No string.";
}
}
catch(Exception e){
return "Network problem";
}
}
}
public void processFinish2 (String output2){
Toast.makeText(MainActivity.this,output2, Toast.LENGTH_SHORT).show();
try{
//str
JSONObject jsonResponse = new JSONObject(output2);
JSONArray aJson = jsonResponse.getJSONArray("gen_off");
// create apps list
for(int i=0; i<aJson.length(); i++) {
JSONObject json = aJson.getJSONObject(i);
//end
//str
String strCount = json.getString(TAG_COUNT);
count.setText(strCount);//setting name to original name text
//end
}
}catch (JSONException e) {
Toast.makeText(MainActivity.this,"Exception caught!", Toast.LENGTH_SHORT).show();
}
}
//end getting count
private void initView() {
// show progress dialog
// dialog = ProgressDialog.show(this, "", "Loading...");
String key="saasvaap123";
String signup_id="8";
String url = "http://gooffers.in/omowebservices/index.php/webservice/Public_User/saved_offers_list?";
FetchDataTask task = new FetchDataTask();
task.execute(url,key,signup_id);
}
public class FetchDataTask extends AsyncTask<String, Void, String>{
// private final FetchDataListener listener;
private String msg;
#Override
protected String doInBackground(String... params) {
if(params == null) return null;
// get url from params
String url = params[0];
String key1 = params[1];
String signupid1 = params[2];
ArrayList<NameValuePair> postParameters;
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("key",key1));
postParameters.add(new BasicNameValuePair("signup_id",signupid1));
//str
try {
// create http connection
HttpClient client = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// connect
HttpResponse response = client.execute(httppost);
// get response
HttpEntity entity = response.getEntity();
if(entity != null){
return EntityUtils.toString(entity);
}
else{
return "No string.";
}
}
catch(Exception e){
return "Network problem";
}
}
//end
//
#Override
protected void onPostExecute(String sJson) {
try {
JSONObject jsonResponse = new JSONObject(sJson);
JSONArray aJson = jsonResponse.getJSONArray("gen_off");
Toast.makeText(MainActivity.this, aJson.toString(),Toast.LENGTH_SHORT).show();
// create apps list
List<SavedOffers> apps = new ArrayList<SavedOffers>();
for(int i=0; i<aJson.length(); i++) {
JSONObject json = aJson.getJSONObject(i);
SavedOffers app = new SavedOffers();
app.setTitle(json.getString("title"));
app.setOriginalRate(json.getString("price"));
app.setOfferRate(json.getString("off_price"));
app.setPercentage(json.getString("percent"));
app.setSavings(json.getString("savings"));
app.setUrl(json.getString("image"));
// add the app to apps list
apps.add(app);
}
SavedOffersAdapter adapter = new SavedOffersAdapter(MainActivity.this, apps);
// set the adapter to list
l1.setAdapter(adapter);
//for delete
// adapter.notifyDataSetChanged();
/** Defining a click event listener for the button "Delete" */
Button btnDel = (Button) findViewById(R.id.deleteid);
OnClickListener listenerDel = new OnClickListener() {
#Override
public void onClick(View v) {
/** Getting the checked items from the listview */
SparseBooleanArray checkedItemPositions = l1.getCheckedItemPositions();
int itemCount = l1.getCount();
for(int i=itemCount-1; i >= 0; i--){
if(checkedItemPositions.get(i)){
adapter.remove(l1.get(i));
}
}
checkedItemPositions.clear();
adapter.notifyDataSetChanged();
}
};
/** Setting the event listener for the delete button */
btnDel.setOnClickListener(listenerDel);
/** Setting the adapter to the ListView */
l1.setAdapter(adapter); //end delete
//notify the activity that fetch data has been complete
// if(listener != null) listener.onFetchComplete(apps);
} catch (JSONException e) {
// msg = "Invalid response";
// if(listener != null) listener.onFetchFailure(msg);
// return;
}
}
/**
* This function will convert response stream into json string
* #param is respons string
* #return json string
* #throws IOException
*/
public String streamToString(final InputStream is) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
}
catch (IOException e) {
throw e;
}
finally {
try {
is.close();
}
catch (IOException e) {
throw e;
}
}
return sb.toString();
}
}
}
// this is my adapter class , I think change is only needed in main activity
// , I need to delete a specific list item from listview on clicking the delete button
public class SavedOffersAdapter extends ArrayAdapter<SavedOffers>{
private List<SavedOffers> items;
Bitmap bitmap;
ImageView image;
public SavedOffersAdapter(Context context, List<SavedOffers> items) {
super(context, R.layout.app_custom_list, items);
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
private class ViewHolder {
//TextView laptopTxt;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// ViewHolder holder;//added
View v = convertView;
if(v == null) {
LayoutInflater li = LayoutInflater.from(getContext());
v = li.inflate(R.layout.app_custom_list, null);
}
SavedOffers app = items.get(position);
if(app != null) {
TextView productName = (TextView)v.findViewById(R.id.nameid);
TextView originalRate = (TextView)v.findViewById(R.id.originalid);
originalRate.setPaintFlags(originalRate.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
TextView offerRate = (TextView)v.findViewById(R.id.offerid);
TextView percentage = (TextView)v.findViewById(R.id.discountid);
TextView savings = (TextView)v.findViewById(R.id.savingsid);
image =(ImageView)v.findViewById(R.id.prctimgid);
if(productName != null) productName.setText(app.getTitle());
if(originalRate != null) originalRate.setText(app.getOriginalRate());
if(offerRate != null) offerRate.setText(app. getOfferRate());
if(percentage != null) percentage.setText(app. getPercentage());
if(savings != null) savings.setText(app. getSavings());
if(image!=null){
new DownloadImageTask(image).execute(app.getUrl());
}
}
return v;
}
In your listviews adapter's getView method you link to the button on the layout your inflating and just attach a setOnClickListener... to the button and have it remove that item from your list or array that your adapter uses and then notifyDataHasChanged.
Delete that item from items in that position.
So 1. you want to delete the item from the ListView
2. you want to delete the item from the SQL DB.
The first one is very easy, but you kind of need to know the underlining adapter and how it serves data to your ListView. When you instantiate a BaseAdapter for the ListView you pass in a List or an array. This array will be the data your BaseAdapter serves to your ListView, each view in the listview will be showing an element from the array (done in getView()). If you dynamically delete one of those items, then adjust your array (or just use a List and it's .remove(), and finally notifyDataSetChanged(); your BaseAdapter will refresh your list without that View (or rather that View will be replaced with the new one). So for instance below I pass in a List<WeatherLocation> (WeatherLocation is a containing class that has weather stuff for a particular area (city, zipcode, degree"Biddeford", 04005, 72) to my BaseAdapter.
// Instantiate ListView
ListView lvLocations = (ListView) findViewById(R.id.lvLocations);
// Instantiate our BaseAdapter (pass in the List<WeatherLocation>)
WeatherLocationAdapter mWeatherLocationAdapter = new WeatherLocationAdapter(savedList, this, R.layout.view_weather_location);
lvLocations.setAdapter(mWeatherLocationAdapter);
This is an example of a regular ListView setting an Adapter to a custom BaseAdapter.
The BaseAdapter is so simple, that really the only method you care about (majorly) is the getView() method.
R.layout.view_weather_location is just a `LinearLayout` I made, it has 3 TextViews in it that I tie (show) my data with, by attaching data to those TextViews in the `getView()` method of the `BaseAdapter`. You would put a `Button there and tie it to what you want (to delete the data item)`.
public class WeatherLocationAdapter extends BaseAdapter{
private List <WeatherLocation> mLocations;
private Context mContext;
private int rowForLocationToInflate;
private LayoutInflater inflater;
public WeatherLocationAdapter(List<WeatherLocation> mLocations, Context mContext, int rowForLocationToInflate) {
this.mLocations = mLocations;
this.mContext = mContext;
this.rowForLocationToInflate = rowForLocationToInflate;
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
//TODO just built up layout now must tie to it.
private void addLocation(WeatherLocation newLocation){
mLocations.add(newLocation);
//TODO maybe invalidate after adding new item.
}
#Override
public int getCount() {
return mLocations.size();
}
#Override
public WeatherLocation getItem(int position) {
return mLocations.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//TODO build a viewholder
View rowView = inflater.inflate(rowForLocationToInflate, parent, false);
TextView tvZipcode = (TextView) rowView.findViewById(R.id.tvZipCode);
TextView tvCity = (TextView) rowView.findViewById(R.id.tvCity);
TextView tvTemp = (TextView) rowView.findViewById(R.id.tvDegree);
tvZipcode.setText(mLocations.get(position).getZipcode());
tvCity.setText(mLocations.get(position).getCity());
tvTemp.setText(String.valueOf(mLocations.get(position).getTemperature()));
// If you had a Button in your LinearLayout you were attaching to you that you wanted to delete that view/item with, it would look something like this in my case.
Button bDel = (Button) row.findViewById(R.id.bDel);
bDel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mLocations.remove(position);
}
});
return rowView;
}
}
In the onClick you would also remove the item from the SQL db. I can show that too, but I feel you have some coding to do as it stands.
While sending the message I got application error and the app stops. I wanted to submit the form using POST method. Please help me to correct the code as i am new to android.
I have taken code reference from http://www.onlymobilepro.com/2013/03/16/submitting-android-form-data-via-post-method/
public class MainActivity extends Activity {
EditText msgTextField;
Button sendButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.form);
//make message text field object
msgTextField = (EditText) findViewById(R.id.msgTextField);
//make button object
sendButton = (Button) findViewById(R.id.sendButton);
}
public void send(View v)
{
//get message from message box
String msg = msgTextField.getText().toString();
//check whether the msg empty or not
if(msg.length()>0) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yourdomain.com/serverside-script.php");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "01"));
nameValuePairs.add(new BasicNameValuePair("message", msg));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpclient.execute(httppost);
msgTextField.setText(""); //reset the message text field
Toast.makeText(getBaseContext(),"Sent",Toast.LENGTH_SHORT).show();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
//display message if text field is empty
Toast.makeText(getBaseContext(),"All fields are required",Toast.LENGTH_SHORT).show();
}
}
You are doing network operation on Main Thread , it needs to be done in seperate Thread .
Do something like this:
To know how to use AsyncTask and set its parameters, see this :
What arguments are passed into AsyncTask<arg1, arg2, arg3>?
EditText msgTextField;
Button sendButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.form);
//make message text field object
msgTextField = (EditText) findViewById(R.id.msgTextField);
//make button object
sendButton = (Button) findViewById(R.id.sendButton);
}
public void send(View v) {
//get message from message box
String msg = msgTextField.getText().toString();
if (!msg.isEmpty()) {
new PostData().execute(msg);
} else {
//display message if text field is empty
Toast.makeText(getBaseContext(), "All fields are required", Toast.LENGTH_SHORT).show();
}
}
public class PostData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yourdomain.com/serverside-script.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "01"));
nameValuePairs.add(new BasicNameValuePair("message", params[0]));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
try {
HttpResponse response = httpclient.execute(httppost);
String op = EntityUtils.toString(response.getEntity(), "UTF-8");//The response you get from your script
return op;
} catch (IOException e) {
e.printStackTrace();
}
//reset the message text field
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
msgTextField.setText("");
Toast.makeText(getBaseContext(), "Sent", Toast.LENGTH_SHORT).show();
}
}
I'm trying to make a login system for my application. Currently the user can create an account online and download the app. They are then prompted for their username and password.
When they press the login button I want to make a request to a php script on the server to check the results and return true if the user does exist and false if they do not exist.
I am a little bit confused about how I should implement this?
I am trying to create a seperate class that extends AsyncTask.
This is my MainActivity
EditText username;
EditText password;
Button loginBtn;
LinearLayout loginform;
String passwordDetail;
String usernameDetail;
String url = "http://www.jdiadt.com/example/checklogindetails.php";
HttpTask httptask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Hide the Action Bar
ActionBar ab;
ab = this.getActionBar();
ab.hide();
//Get references to XML
username = (EditText)findViewById(R.id.username);
password = (EditText)findViewById(R.id.password);
loginBtn = (Button)findViewById(R.id.loginBtn);
loginform = (LinearLayout)findViewById(R.id.loginform);
//Animation
final AlphaAnimation fadeIn = new AlphaAnimation(0.0f , 1.0f );
AlphaAnimation fadeOut = new AlphaAnimation( 1.0f , 0.0f ) ;
fadeIn.setDuration(1200);
fadeIn.setFillAfter(true);
fadeOut.setDuration(1200);
fadeOut.setFillAfter(true);
fadeOut.setStartOffset(4200+fadeIn.getStartOffset());
//Run thread after 2 seconds to start Animation
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
public void run() {
//display login form
loginform.startAnimation(fadeIn);
loginBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//display();
Toast.makeText(getApplicationContext(), "Checking login details...", Toast.LENGTH_SHORT).show();
if(checkLoginDetails()){
//OPENS NEW ACTIVITY
//Close splash screen
finish();
//start home screen
Intent intent = new Intent(v.getContext(), SectionsActivity.class);
startActivity(intent);
//creates fade in animation between two activities
overridePendingTransition(R.anim.fade_in, R.anim.splash_fade_out);
}
else{
}
}
});
}
}, 2000);
}
//Check the login details before proceeding.
public boolean checkLoginDetails(){
usernameDetail = username.getText().toString();
passwordDetail = password.getText().toString();
httptask = new HttpTask();
httptask.execute(url, usernameDetail, passwordDetail);
//if exists return true
//else return false
return false;
}
}
This is my HttpTask
public class HttpTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
String url = params[0];
String username = params[1];
String password = params[2];
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
List <NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
try {
httpClient.execute(httpPost);
return true;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
This is my php script on my webserver checklogindetails.php
require_once 'db_connect.php';
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$pwdMD5 = md5($password);
$sql = "SELECT * FROM users WHERE username = '$username' AND password='$pwdMD5'";
$result = mysql_query($sql);
$count = mysql_num_rows($result);
if($count == 1){
echo "Log in successful";
//RETURN TRUE
}
else{
echo "Wrong username or password";
//RETURN FALSE
}
I guess the place I'm most confused about is how to constuct the php script to check the login details and how I can decide what to do based on it returning true or false.
I'd appreciate any advice or help on this subject! Many thanks
The above code looks good except that you are missing the last step.
Returning something from the PHP and then reading it in the app.
I would suggest changing the output of the PHP to something easier to parse/maintain like "OK" and "ERROR"
Then add the following code to the HttpTask.
final HttpResponse response = httpClient.execute(httpPost, localContext);
if (response != null)
{
// parse response
final HttpEntity entity = response.getEntity();
if (entity == null)
{
// response is empty, this seems an error in your use case
if (BuildConfig.DEBUG)
{
Log.d(HttpClient.TAG, "Response has no body"); //$NON-NLS-1$
}
}
else
{
try
{
// convert response to string
this.mResponseAsString = EntityUtils.toString(entity);
if (BuildConfig.DEBUG)
{
Log.d(HttpClient.TAG, "Response: " + this.mResponseAsString); //$NON-NLS-1$
}
// parse the string (assuming OK and ERROR as possible responses)
if (this.mResponseAsString != null && this.mResponseAsString.equals("OK")
{
// add happy path code here
}
else
{
// add sad path here
}
}
catch (final ParseException e)
{
Log.e(HttpClient.TAG, e.getMessage(), e);
}
catch (final IOException e)
{
Log.e(HttpClient.TAG, e.getMessage(), e);
}
}
this.mResponseCode = response.getStatusLine().getStatusCode();
}
Personally I would also refactor the "OK" in the HttpTask to a constant (for easy reading and maintaining) and also refactor most the HTTP based code to some kind of base class or utility class so you can reuse it.
I have an issue with with multiple clicks on a ListView using custom adapter.
I'm catching the onClick events all fine, the problem is that I need to start an AsyncTask on each row click that calls a webservice.
Its the same AsyncTask, just with different params.
If the user clicks on multiple rows fast, only the last AsyncTask is fired and that row is only updated.
Code to handle onClick()
myListView.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Item item = (Item) mylLstView.getAdapter().getItem(position);
//execute AsyncTask
}
});
My AsyncTask
private class CheckItemInOrOutTask extends AsyncTask<Context, Void, Boolean>
{
private int position;
Item singleItem;
public CheckItemInOrOutTask(int position, Item singleItem)
{
this.position = position;
this.singleItem = singleItem;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Context... params)
{
try
{
HttpClient client = HttpUtil.getHttpClient();
String reqString = "Items?action=checkin";
HttpPost post = HttpUtil.makePost(reqString);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("item_id", singleItem.getId()));
nameValuePairs.add(new BasicNameValuePair("type_id", singleItem.getTypeId()));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200)
{
String result = HttpUtil.responseToString(response);
JSONObject jsonItem = new JSONObject(result);
Item item = new Item();
// parse json
// set item properties
itemList.set(position,item);
}
}
catch (Exception e)
{
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result)
{
super.onPostExecute(result);
//if (result)
{
updateAdapter();
}
}
}
Can someone shed some light on it?
Thanks a lot.
Figured out it wasn't the AsyncTask that was the culprit.
It was because I was reusing my HttpClient.
Here I am trying to retrieve the response from the server and display it, but I am failed to do so, the response text does not appear in my text view, insetead the default value of the string does, may I ask how can I achieve my goal. And why my code cannot finish the task.
Here is my android program:
public class Chico extends Activity {
GrabURL grab;
TextView mRespond;
String line;
#Override
public void onCreate(Bundle savedInstanceState) {
//create the activity
super.onCreate(savedInstanceState);
//set up the layout
setContentView(R.layout.activity_chico);
mRespond = (TextView) findViewById(R.id.Respond);
mRespond.setVisibility(View.GONE);
grab = new GrabURL();
line = "line";
//set up the button for check in
Button btnin = (Button) findViewById(R.id.inbutton);
btnin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//set the values
grab.onPreExecute("TechID", Build.SERIAL);
grab.onPreExecute("Type", "Checkin");
//set the destination and send the request
grab.execute(new String[]{"http://192.168.1.150/Me/testing.php"});
//close the activity
mRespond.setVisibility(View.VISIBLE);
mRespond.setText(line);
//finish();
}
});
}
private class GrabURL extends AsyncTask<String, Void, Void>{
//ArrayList object for storing the string pairs
ArrayList<NameValuePair> nameValuePairs;
public GrabURL() {
//constructor of the class
nameValuePairs = new ArrayList<NameValuePair>();
}
protected void onPreExecute(String key, String value) {
//store the pair of values into the ArrayList
nameValuePairs.add(new BasicNameValuePair(key,value));
}
#Override
protected Void doInBackground(String... urls) {
// TODO Auto-generated method stub
//Operation being executed in another thread
try{
//set up the type of HTTPClient
HttpClient client = new DefaultHttpClient();
//set up the location of the server
HttpPost post = new HttpPost(urls[0]);
//translate form of pairs to UrlEncodedFormEntity
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8);
//set up the entity being sent by post method
post.setEntity(ent);
//execute the url and post the values
HttpResponse responsePOST = client.execute(post);
HttpEntity resEntity = responsePOST.getEntity();
line = EntityUtils.toString(resEntity);
} catch (Exception e) {
//catch the exception
line = "Can't connect to server";
}
return null;
}
protected void onPostExecute(Void unused) {
Toast.makeText(getApplicationContext(), "Value updated", Toast.LENGTH_SHORT).show();
}
}
}
And here is the php file, it just prints a line:
<?php
print "testing";
?>
Move this code to your AsyncTask's onPostExecute():
...
mRespond.setVisibility(View.VISIBLE);
mRespond.setText(line);