I am trying to make a request to a server to a php script which will check to see if a user exists in a database. Currently I just want to make sure I am receiving some sort of response. I try to output the value of responseString when the user presses the login button but every time it comes back as null. Does anyone know why??
This is my MainActivity
public class MainActivity extends Activity {
EditText username;
EditText password;
Button loginBtn;
LinearLayout loginform;
String passwordDetail;
String usernameDetail;
String url = "http://www.mysite.com/example/checklogin.php";
String responseString = null;
#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);
Toast.makeText(getApplicationContext(), "Login Successful" + responseString, Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "Login Unsuccessful", Toast.LENGTH_SHORT).show();
}
}
});
}
}, 2000);
}
//Check the login details before proceeding.
public boolean checkLoginDetails(){
usernameDetail = username.getText().toString();
passwordDetail = password.getText().toString();
new RequestTask().execute(url, usernameDetail, passwordDetail);
return true;
}
This is the php script I'm requesting - At moment I've hard coded details I know to exist in db and just want to focus on getting back a response to say user exists.
<?php
mysql_connect("xxx.xxx.xxx.xxx", "username", "password") or die("Couldn't select database.");
mysql_select_db("databasename") or die("Couldn't select database.");
//$username = $_POST['username'];
//$password = $_POST['password'];
$pwdMD5 = md5(123);
$sql = "SELECT * FROM membership WHERE Username = 'user1' AND Password = '$pwdMD5' ";
$result = mysql_query($sql) or die(mysql_error());
$numrows = mysql_num_rows($result);
if($numrows > 0)
{
echo 'user found';
return true;
}
else
{
echo 'user not found';
return false;
}
?>
This is my AsyncTask.
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
responseString = null;
try {
response = httpclient.execute(new HttpPost(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
It is null because you execute the code asynchronously. You Toast the result while the HTTP request is not yet finished executing your PHP script.
Try putting your Toast to onPostExecute(String result) method in your AsyncTask class.
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Toast result.
}
You are not getting something from the respose but putting in it... use ByteArrayInputStream instead of output stream.....
Related
I have a Login Fragment that execute AsynkTask and in onPost() I want to update Login Fragment UI .I am already done that need some correction in That.How can I make non-ui thread.
here is my code:-
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
m_Main = inflater.inflate(R.layout.login_screen, container, false);
((AppCompatActivity) getActivity()).getSupportActionBar().hide();
CMainActivity.m_Drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
m_oLoginSession = new CLoginSessionManagement(getActivity());
init();// initialize controls
return m_Main;
}
public void init() {
m_MainLayout = (LinearLayout) m_Main.findViewById(R.id.mainLayout);
m_InputMobile = (EditText) m_Main.findViewById(R.id.input_mobile);
m_InputPassword = (EditText) m_Main.findViewById(R.id.input_password);
m_LoginBtn = (AppCompatButton) m_Main.findViewById(R.id.btn_Login);
m_ChangePass = (AppCompatButton) m_Main.findViewById(R.id.btn_ChangePass);
m_ChangePass.setBackgroundColor(Color.TRANSPARENT);
m_ChangePass.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, new CChangePasswordScreen()).commit();
}
});
m_RegisterBtn = (AppCompatButton) m_Main.findViewById(R.id.btn_Register);
m_RegisterBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, new CRegistrationScreen()).commit();
}
});
m_LoginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new LoginAttempt().execute();
}
});
}
private class LoginAttempt extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setCancelable(false);
pDialog.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
// and now the magic
pDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
pDialog.getWindow().setGravity(Gravity.BOTTOM);
pDialog.getWindow().getAttributes().verticalMargin = 0.5f;
pDialog.show();
// CProgressBar.getInstance().showProgressBar(getActivity(), "Please wait while Logging...");// showing progress ..........
}
#Override
protected String doInBackground(String... params) {
getLoginDetails();// getting login details from editText...........
InputStream inputStream = null;
m_oJsonsResponse = new CJsonsResponse();
isFirstLogin = true;
try {
// 1. create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 2. make POST request to the given URL
HttpPost httpPost = new HttpPost(s_szLoginUrl);
String json = "";
// 3. build jsonObject
JSONObject jsonObject = new JSONObject();
jsonObject.put("agentCode", s_szMobileNumber);
jsonObject.put("pin", s_szPassword);
jsonObject.put("firstloginflag", m_oLoginSession.isLogin());
// 4. convert JSONObject to JSON to String
json = jsonObject.toString();
// 5. set json to StringEntity
StringEntity se = new StringEntity(json);
// 6. set httpPost Entity
httpPost.setEntity(se);
// 7. Set some headers to inform server about the type of the content
// httpPost.setHeader("Accept", "application/json"); ///not required
httpPost.setHeader("Content-type", "application/json");
// 8. Execute POST request to the given URL
HttpResponse httpResponse = httpclient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
// 9. receive response as inputStream
inputStream = entity.getContent();
System.out.print("InputStream...." + inputStream.toString());
System.out.print("Response...." + httpResponse.toString());
StatusLine statusLine = httpResponse.getStatusLine();
System.out.print("statusLine......" + statusLine.toString());
////Log.d("resp_body", resp_body.toString());
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
// 10. convert inputstream to string
if (inputStream != null) {
s_szresult = m_oJsonsResponse.convertInputStreamToString(inputStream);
//String resp_body =
EntityUtils.toString(httpResponse.getEntity());
}
} else
s_szresult = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
return s_szresult;
}
#Override
protected void onPostExecute(final String response) {
super.onPostExecute(response);
m_Handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
m_Handler.post(new Runnable() {
#Override
public void run() {
CProgressBar.getInstance().hideProgressBar();// hide progressbar after getting response from server......
try {
m_oResponseobject = new JSONObject(response);// getting response from server
new Thread() {// making child thread...
public void run() {
Looper.prepare();
try {
getResponse();// getting response from server ........
Looper.loop();
} catch (JSONException e) {
e.printStackTrace();
}
}
}.start();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}).start();
}
public void getResponse() throws JSONException {
if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Transaction Successful")) {
m_oLoginSession.setLoginData(s_szResponseMobile, s_szResponsePassword);
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, new CDealMainListing()).commit();
CToastMessage.getInstance().showToast(getActivity(), "You are successfully Logged In");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Agentcode Can Not Be Empty")) {
CToastMessage.getInstance().showToast(getActivity(), "Please Enter Valid Mobile Number");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Pin Can Not Be Empty")) {
CToastMessage.getInstance().showToast(getActivity(), "Please Enter Password");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Invalid PIN")) {
CToastMessage.getInstance().showToast(getActivity(), "Please enter correct Password");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Blocked due to Wrong Attempts")) {
CToastMessage.getInstance().showToast(getActivity(), "You are blocked as You finished your all attempt");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Connection Not Available")) {
CToastMessage.getInstance().showToast(getActivity(), "Connection Lost ! Please Try Again");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Not Found")) {
CToastMessage.getInstance().showToast(getActivity(), "User not found ! Kindly Regiter before Login");
} else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("OTP not verify")) {
CToastMessage.getInstance().showToast(getActivity(), "Otp not Verify ! Kindly Generate Otp on Sign Up");
}
}
public void getLoginDetails() {
s_szMobileNumber = m_InputMobile.getText().toString();
s_szPassword = m_InputPassword.getText().toString();
}
}
}
Move the code that is in a thread in onPostExecute() to doInBackground() because this is running in other thread and them refresh you UI in onPostExecute()
A mock example:
#Override
protected String doInBackground(String... params) {
//RUN ALL THAT YOU WANT IN A DIFFERENT THREAD
}
#Override
protected void onPostExecute(final String response) {
//REFRESH THE UI
}
If you are using AsynkTask, you can have a try on onPreExecute and onPostExecute methods that both runs on the UI thread.
Or you can use a handler to update UI.
In your UI thread create an object of Handler like this
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
//Update UI here
//use msg.obj if you have sent Object from background thread
//use msg.what if you have sent Integer from background thread
//Update UI if you have just trigger the handler using sendEmptyMessage(your UI/View gets data from Global Variable)
}
};
Two ways we can trigger Hanler which is created in UI thread
1)handler.sendMessage(Message);
2)handler.sendEmptyMessage(0);
Inside on postExecute of your AsyncTask write below Code based on your requirement
//Message msg=Message.obtain();
//msg.obj=YourObject;//If you want to pass Object
//msg.what=Integer;//If you want to pass Integer
//handler.sendMessage(msg);//to send Message objectdefined above
handler.sendEmptyMessage(0);//If you simply want to trigger
Hi I'm new to android and have task to create a login page that will connect with server and check user exist using http Get and AsyncTask and PHP API for this is ready. i went through few tutorials on AsyncTask and i understood but i m not sure how to work with http Get and AsyncTask. can anyone please help how to link both and create login page.
P.S: i have two EditText to accept username and password and two Buttons one for login and other for register and have corresponding DB as well.
This is sample code-
public class LoginActivity extends Activity
{
Intent i;
Button signin, signup;
String name = "", pass = "";
byte[] data;
HttpPost httppost;
StringBuffer buffer;
HttpResponse response;
HttpClient httpclient;
InputStream inputStream;
SharedPreferences app_preferences, pref;
List<NameValuePair> nameValuePairs;
EditText editTextId, editTextP;
SharedPreferences.Editor editor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
signin = (Button) findViewById(R.id.signin);
signup = (Button) findViewById(R.id.signup);
editTextId = (EditText) findViewById(R.id.editTextId);
editTextP = (EditText) findViewById(R.id.editTextP);
app_preferences = PreferenceManager.getDefaultSharedPreferences(this);
String Str_user = app_preferences.getString("username", "0");
String Str_pass = app_preferences.getString("password", "0");
String Str_check = app_preferences.getString("checked", "no");
if (Str_check.equals("yes"))
{
editTextId.setText(Str_user);
editTextP.setText(Str_pass);
}
signin.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
signin.setEnabled(false);
signup.setEnabled(false);
name = editTextId.getText().toString();
pass = editTextP.getText().toString();
String Str_check2 = app_preferences.getString("checked", "no");
if (Str_check2.equals("yes")) {
SharedPreferences.Editor editor = app_preferences.edit();
editor.putString("username", name);
editor.putString("password", pass);
editor.commit();
}
if (name.equals("") || pass.equals(""))
{
Toast.makeText(LoginActivity.this, "Blank Field..Please Enter", Toast.LENGTH_SHORT).show();
signin.setEnabled(true);
signup.setEnabled(true);
}
else
{
String emailPattern = "[a-zA-Z0-9._-]+#[a-z]+\\.+[a-z]+";
if(name.matches(emailPattern))
new LoginTask().execute();
signin.setEnabled(false);
signup.setEnabled(false);
}
}
});
signup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
Move_next();
}
});
}
public void Move_to_next()
{
final Handler handle = new Handler();
Runnable delay = new Runnable() {
public void run() {
startActivity(new Intent(LoginActivity.this, SplashActivity.class));
finish();
}
};
handle.postDelayed(delay,2000);
}
public void Move_next()
{
startActivity(new Intent(LoginActivity.this, SignUpActivity.class));
finish();
}
#SuppressLint("NewApi")
private class LoginTask extends AsyncTask <Void, Void, String>
{
#SuppressLint("NewApi")
#Override
protected void onPreExecute()
{
super.onPreExecute();
// Show progress dialog here
}
#Override
protected String doInBackground(Void... arg0) {
try {
httpclient = new DefaultHttpClient();
httppost = new HttpPost("http://website.com/yourpagename.php");
// Add your data
nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("UserEmail", name.trim()));
nameValuePairs.add(new BasicNameValuePair("Password", pass.trim()));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
response = httpclient.execute(httppost);
inputStream = response.getEntity().getContent();
data = new byte[256];
buffer = new StringBuffer();
int len = 0;
while (-1 != (len = inputStream.read(data))) {
buffer.append(new String(data, 0, len));
}
inputStream.close();
return buffer.toString();
}
catch (Exception e)
{
e.printStackTrace();
}
return "";
}
#SuppressLint("NewApi")
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Hide progress dialog here
if (buffer.charAt(0) == 'Y')
{
Toast.makeText(LoginActivity.this, "login successfull", Toast.LENGTH_SHORT).show();
Move_to_next();
}
else
{
Toast.makeText(LoginActivity.this, "Invalid Username or password", Toast.LENGTH_SHORT).show();
signin.setEnabled(true);
signup.setEnabled(true);
}
}
}
}
I am trying to create a native login screen, where the username and password boxes slide off the screen while the request is being processed (and slide back up if the login is unsuccessful).
In order to achieve that, I have defined my animation (DropDownAnimation) and I assign it to my LinearLayout (footer). When the user clicks the Login button, I start the animation, and then call a function (tryLogin()) which starts an AsyncTask. The AsyncTask handles all the work of creating and sending the login request, and getting the JSONObject response.
However, my problem is that the slideDown animation doesn't start until after the AsyncTask has completed. This doesn't look so bad on a successful login, but on a failed login it means that the LinearLayout never slides down - it jumps to the bottom of the screen, to begin the slideUp animation back to its original position.
This seems like a similar problem to this question, but I'm not doing using bindService() and all my non-UI code seems (to me) to be contained in the AsyncTask already. LogCat tells me:
06-24 04:37:35.141: I/Choreographer(5347): Skipped 137 frames! The application may be doing too much work on its main thread.
I assume those are the frames where the footer would be sliding down - but I can't figure out where it is that I'm executing things on the main thread. Here's my code for LoginPage and LoginTask.
LoginPage.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_page);
login = (Button) findViewById(R.id.login);
username = (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
footer = (LinearLayout) findViewById(R.id.footer);
// We must wait for the layout to be finalised before trying to find heights.
ViewTreeObserver vto = footer.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
initAnimations();
}
});
loading = (TextView) findViewById(R.id.loading);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String mUsername = username.getText().toString();
String mPassword = password.getText().toString();
// Neither of these two things happen until after LoginTask is done.
footer.startAnimation(slideDown);
loading.setVisibility(TextView.VISIBLE);
tryLogin(mUsername, mPassword);
}
});
}
protected void tryLogin(String mUsername, String mPassword) {
Exception e;
String loginUrl = getString(R.string.login_url);
String clientId = getString(R.string.client_id);
String clientSecret = getString(R.string.client_secret);
LoginTask loginTask = (LoginTask) new LoginTask().execute(mUsername, mPassword, loginUrl, clientId, clientSecret);
if ((e = loginTask.getException()) != null) {
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
} else {
JSONObject response;
try {
response = loginTask.get();
Log.d("login", response.toString());
if (!response.has("access_token")) {
loading.setVisibility(TextView.INVISIBLE);
footer.startAnimation(slideUp);
Toast.makeText(this, "Login error", Toast.LENGTH_LONG).show();
} else {
Intent i = new Intent(this, FullscreenWebView.class);
i.putExtra("accessToken", response.get("access_token").toString());
startActivity(i);
overridePendingTransition(0, 0);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
Thread.currentThread().interrupt();
} catch (ExecutionException e1) {
e1.printStackTrace();
} catch (JSONException e1) {
e1.printStackTrace();
throw new RuntimeException(e);
}
}
}
LoginTask.java
class LoginTask extends AsyncTask<String, Void, JSONObject> {
private Exception exception;
#Override
protected JSONObject doInBackground(String... params) {
HttpURLConnection connection;
OutputStreamWriter request = null;
URL url = null;
JSONObject response = null;
String parameters = "grant_type=password&username="+params[0]+"&password="+params[1]+"&client_id="+params[3]+"&client_secret="+params[4];
try {
url = new URL(params[2]);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
connection.setRequestMethod("POST");
request = new OutputStreamWriter(connection.getOutputStream());
request.write(parameters);
request.flush();
request.close();
// username or password is probably wrong
Log.d("login", ""+connection.getResponseCode());
if (connection.getResponseCode() != 200) {
return new JSONObject();
}
String line = "";
InputStreamReader isr = new InputStreamReader(connection.getInputStream());
BufferedReader reader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
Log.d("login", sb.toString());
response = new JSONObject(sb.toString());
isr.close();
reader.close();
} catch (Exception e) {
this.exception = e;
}
return response;
}
}
I've also tried making LoginTask be a member class of LoginPage, and starting the animation in the onPreExecute() method, but that didn't change anything.
Any help is much appreciated!
When you use AsyncTask.get(), you are blocking the UI thread. As the animation runs on the UI thread, it appears as if it is not running (while in fact it is blocked by your long running tryLogin method).
Instead, you should move the code that relies on the result from the LoginTask to its onPostExecute method:
protected void tryLogin(String mUsername, String mPassword) {
String loginUrl = getString(R.string.login_url);
String clientId = getString(R.string.client_id);
String clientSecret = getString(R.string.client_secret);
new LoginTask().execute(mUsername, mPassword,
loginUrl, clientId, clientSecret);
}
LoginTask.java
class LoginTask extends AsyncTask<String, Void, JSONObject> {
private Exception exception;
#Override
protected JSONObject doInBackground(String... params) {
// Unchanged
}
public void onPostExecute(JSONObject response) {
if (exception != null) {
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
} else {
Log.d("login", response.toString());
if (!response.has("access_token")) {
loading.setVisibility(TextView.INVISIBLE);
footer.startAnimation(slideUp);
Toast.makeText(this, "Login error", Toast.LENGTH_LONG).show();
} else {
Intent i = new Intent(this, FullscreenWebView.class);
i.putExtra("accessToken", response.get("access_token").toString());
startActivity(i);
overridePendingTransition(0, 0);
}
}
}
}
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 a login.php script which will validate the username and password entered in the android. The code is below
<?php
include('dbconnect.php');
$data=file_get_contents('php://input');
$json = json_decode($data);
$tablename = "users";
//username and password sent from android
$username=$json->{'username'};
$password=$json->{'password'};
//protecting mysql injection
$username = stripslashes($username);
$password = stripslashes($password);
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
$password = md5($password);
$sql = "SELECT id FROM $tablename WHERE u_username='$username' and password='$password'";
//Querying the database
$result=mysql_query($sql);
//If found, number of rows must be 1
if((mysql_num_rows($result))==1){
//creating session
session_register("$username");
session_register("$password");
print "success";
}else{
print "Incorrect details";
}
?>
I also have an android class from which the user will enter the username and password. The code is below.
public class LoginActivity extends Activity {
public static final String loginURI="http://.../login.php";
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
buttonSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String userID = "";
userID=login(editTextUsername.getText().toString(), editTextPassword.getText().toString());
if (editTextPassword.getText().toString() != null & editTextUsername.getText().toString() != null){
//Used to move to the Cases Activity
Intent casesActivity = new Intent(getApplicationContext(), CasesActivity.class);
startActivity(casesActivity);
casesActivity.putExtra("username", userID);
}
else{
//Display Toaster for error
Toast.makeText(getApplicationContext(),"this is an error message", Toast.LENGTH_LONG).show();
}
}
});
private String login(String username, String password){
JSONObject jsonObject = new JSONObject();
String success = "";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(loginURI);
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams,10000);
HttpConnectionParams.setSoTimeout(httpParams,10000);
try {
jsonObject.put("username", username);
Log.i("username", jsonObject.toString());
jsonObject.put("password", password);
Log.i("password", jsonObject.toString());
StringEntity stringEntity = new StringEntity(jsonObject.toString());
stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPost.setEntity(stringEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
success = EntityUtils.toString(httpResponse.getEntity());
Log.i("success", success);
}
}catch (IOException e){
Log.e("Login_Issue", e.toString());
}catch (JSONException e) {
e.printStackTrace();
}
return success;
}
}
I get the following error: ERROR/AndroidRuntime(29611): FATAL EXCEPTION: main android.os.NetworkOnMainThreadException.
I understand that I need another thread and I was thinking of using AsyncTask, but I do not know where to put it in this class.
Could you also give me some advice in using JSON for sending and receiving data from android.
Thank you for your help,
you can change your code using AsyncTask by calling login method inside doInBackground and start next Activity on onPostExecute when login successful as :
private class LoginOperation extends AsyncTask<String, Void, String> {
String str_username=;
String str_password=;
public LoginOperation(String str_username,String str_password){
this.str_password= str_password;
this.str_username= str_username;
}
#Override
protected void onPreExecute() {
// show progress bar here
}
#Override
protected String doInBackground(String... params) {
// call login method here
String userID=login(str_username,str_password);
return userID;
}
#Override
protected void onPostExecute(String result) {
// start next Activity here
if(result !=null){
Intent casesActivity = new Intent(getApplicationContext(),
CasesActivity.class);
casesActivity.putExtra("username", result);
Your_Activiy.this.startActivity(casesActivity);
}
}
and start LoginOperation AsyncTask on button click as:
buttonSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (editTextPassword.getText().toString() != null
& editTextUsername.getText().toString() != null){
// start AsyncTask here
new LoginOperation(editTextUsername.getText().toString(),
editTextPassword.getText().toString()).execute("");
}
else{
// your code here
}
}
});
}
The simple answer is to create a thread and only call the login within that thread, or an Async task(you can define it as a new class, and just call execute). Like this:
old code:
userID=login(editTextUsername.getText().toString(), editTextPassword.getText().toString());
new code:
Runnable runnable = new Runnable() {
void run() {
login(editTextUsername.getText().toString(), editTextPassword.getText().toString());
}
(new Thread(runnable)).start();