I am creating simple system that has a windows service running, complete with a table of users, and I want to validate someone's login credentials by sending something to the service. I am trying to send their username and password, but I keep getting an error with my Async Task. I know that you're not supposed to mess with UI stuff in there and I am not. Originally I had a call to another activity in there but I commented it out. Now the only thing in doInBackground is setting a boolean value to true if the validation was good. From there I read the value after the async has executed, and then put together a bundle to move to the next place. I just don't know what's wrong here. It has been awhile since I've programmed in Android so maybe I'm missing something stupid. If anyone could help me out I would greatly appreciate it! Thank you. This could also be an issue with sending the information to the service?
UPDATE: After adding in the internet usage in the manifest, if I have the log.d in the program in my doInBackground, it prints out. If I don't have it, the result value stays false. It looks like there is some issue with the connection between my service and android app...
import java.util.ArrayList;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends Activity {
private static final int DATA_FROM_MAIN_ACTIVITY = 1;
private static final String SERVICEURL = "http://localhost:56638/ClientService.svc";
private EditText userTextBox, passTextBox;
private Button loginButton;
private String uName, pass;
private Boolean result = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
userTextBox = (EditText) findViewById(R.id.userTextBox);
passTextBox = (EditText) findViewById(R.id.passTextBox);
loginButton = (Button) findViewById(R.id.loginButton);
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
uName = userTextBox.getText().toString();
pass = passTextBox.getText().toString();
SendLoginMessage task = new SendLoginMessage();
task.execute(uName, pass);
if (result.equals(true)) {
Intent goToMainScreen = new Intent(getApplicationContext(),
MainActivity.class);
goToMainScreen.putExtra("username", uName);
goToMainScreen.putExtra("password", pass);
startActivityForResult(goToMainScreen,
DATA_FROM_MAIN_ACTIVITY);
} else {
Toast.makeText(
getApplicationContext(),
"There was an issue with your username or password.",
Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class SendLoginMessage extends AsyncTask<String, String, Void> {
#Override
protected void onPreExecute() {
// Log.d("message almost at server, " + textFromArea, selected,
// null);
}
#Override
protected Void doInBackground(String... names) {
ArrayList<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new BasicNameValuePair("username", names[0]));
postParams.add(new BasicNameValuePair("password", names[1]));
String response = null;
try {
response = HttpClient.executeHttpPost(SERVICEURL, postParams);
String newResponse = response.toString();
newResponse = newResponse.replaceAll("\\s+", "");
// if user was authenticated...
if (newResponse.equals(true)) {
result = true;
// creating an intent to take user to next page.
// load their DB objects on the
// on create in other activity
// pass the username/password to next activity
// then make a request to the server for their database
// objects.
// Intent goToMainScreen = new
// Intent(getApplicationContext(), MainActivity.class);
// goToMainScreen.putExtra("username", names[0]);
// goToMainScreen.putExtra("password", names[1]);
// startActivityForResult(goToMainScreen,
// DATA_FROM_MAIN_ACTIVITY);
}
} catch (Exception e) {
Log.d("ERROR", "exception in background");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Toast.makeText(getApplicationContext(),
// .show();
}
}
}
Do it like this:
private class SendLoginMessage extends AsyncTask<String, String, Boolean> {
#Override
protected Boolean doInBackground(String... names) {
ArrayList<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new BasicNameValuePair("username", names[0]));
postParams.add(new BasicNameValuePair("password", names[1]));
String response = null;
try {
response = HttpClient.executeHttpPost(SERVICEURL, postParams);
String newResponse = response.toString();
newResponse = newResponse.replaceAll("\\s+", "");
// if user was authenticated...
if (newResponse.equals("true")) {
return true;
}
} catch (Exception e) {
Log.d("ERROR", "exception in background");
}
return false;
}
#Override
protected void onPostExecute(Boolean result) {
if (result) {
Intent goToMainScreen = new Intent(getApplicationContext(),
MainActivity.class);
goToMainScreen.putExtra("username", uName);
goToMainScreen.putExtra("password", pass);
startActivityForResult(goToMainScreen,
DATA_FROM_MAIN_ACTIVITY);
} else {
Toast.makeText(
getApplicationContext(),
"There was an issue with your username or password.",
Toast.LENGTH_LONG).show();
}
}
}
and in your onClick() just call execute()
uName = userTextBox.getText().toString();
pass = passTextBox.getText().toString();
SendLoginMessage task = new SendLoginMessage();
task.execute(uName, pass);
After execution is finished onPostExecute() will be called and your Activity will start depending on result variable.
Don't check your result variable after you invoke execute() because execute() is invoked asynchronously. By the time you check your global result variable, your doInBackground() might not have been finished. Using my approach you don't need a global variable. Please read doc carefully before using any component.
Related
I have been developing web pages with php and MySQL for years but am new to developing for Android projects. I have searched and read through all previous questions that I found concerning the subject but have not found the answer that works for my project. Currently when I run the app, all I get is errors and no download. I am posting the complete code for my Main Activity and ask if anyone can explain what I have done wrong. The data in sharedpreferences for UserId is a integer and the Date/session is a number string and the Email/eaddress is a string
package com.example.logintest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
public class MainActivity extends AppCompatActivity {
String IgidPreference = "IgidPreference";
String UserId = "userId";
String Date = "session";
//OR SHOULD THE DECLEARATION BE??
//public static final String UserId = "userId";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
new VerifyLogin().execute();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, Login.class);
startActivity(intent);
}
});
}
public class VerifyLogin extends AsyncTask<String, Void, String> {
Context ctx;
SharedPreferences pref;
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... arg0) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
if ((pref.contains(UserId)) && (pref.contains(Date))) {
}
String eaddress = arg0[0];
String today = arg0[1];
String link;
String data;
BufferedReader bufferedReader;
String result;
try {
data = "?Email=" + URLEncoder.encode(eaddress, "UTF-8");
data += "&Date=" + URLEncoder.encode(today, "UTF-8");
link = "http://domain.com/verifylogin.php" + data;
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
result = bufferedReader.readLine();
return result;
} catch (Exception e) {
return new String("Exception: " + e.getMessage());
}
}
#Override
protected void onPostExecute(String result) {
String jsonStr = result;
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
String userId = jsonObj.getString("user_id");
String session = jsonObj.getString("session");
String error_type = jsonObj.getString("error");
String error_msg = jsonObj.getString("error_msg");
if (error_type.equals("FALSE")) {
pref = context.getSharedPreferences(IgidPreference, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(UserId, userId);
editor.putString(Date, session);
editor.apply();
Intent intent = new Intent(MainActivity.this, Account.class);
startActivity(intent);
} else if (error_type.equals("TRUE")) {
Toast.makeText(context, error_msg, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, error_msg, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(context, "Error parsing JSON data.", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "Couldn't get any JSON data.", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I know it has been some time since posting on the topic but I had to replace the computer, along with Android Studio and make all new project.
Here is what I have found to handle the original issue. I am putting comments inside the code to help anyone else who wants to use code for their next project.
public class LoginActivity extends Activity { //Standard Activity code
Button BtnLaunchSigninActivity; //Button to click
private EditText etLoginUserName, etLoginPassword; // data to submit
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
etLoginUserName = (EditText) findViewById(R.id.etLoginUserName);
etLoginPassword = (EditText) findViewById(R.id.etLoginPassword);
BtnLaunchSigninActivity = (Button) findViewById(R.id.btnLoginSignin);
BtnLaunchSigninActivity.setOnClickListener(onClickListener);
}
private View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.getId() == R.id.btnLoginSignin) {
signin(v);
}
}
};
public void signin(View v) {
String userName = etLoginUserName.getText().toString();
String passWord = etLoginPassword.getText().toString();
Toast.makeText(this, "Signing In...", Toast.LENGTH_SHORT).show();
new SignIn(this).execute(userName, passWord); // Send data to AsyncTask
}
private class SignIn extends AsyncTask<String, Void, String> {
private Context context; // context is for the SignIn()
SignIn(Context context) {
this.context = context;
}
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... arg0) {
String userName = arg0[0];
String passWord = arg0[1];
String link;
String data;
BufferedReader bufferedReader;
String result;
try {
data = "?username=" + URLEncoder.encode(userName, "UTF-8");
data += "&password=" + URLEncoder.encode(passWord, "UTF-8");
link = "url/login.php" + data;
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
result = bufferedReader.readLine();
return result; // My php returns jsonobjects
} catch (Exception e) {
return new String("Exception: " + e.getMessage());
}
}
#Override
protected void onPostExecute(String result) {
String jsonStr = result; //turn object into string
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
String status = jsonObj.getString("status");
String userid = jsonObj.getString("uid");
String hash = jsonObj.getString("security");
Log.d("tag", jsonObj.toString(4));
if (status.equals("Good")) {
Toast.makeText(context, "Sign In successful.", Toast.LENGTH_SHORT).show();
//YOU HAVE TO USE JSONSTR TO GET USERID AND SECHASH FOR UPDATING SHARED PREFERENCES
//DUE TO ANY POSSIBLE DELAYS OF PROCESSING doInBackground() SEND JSON TO NEXT ACTIVITY TO SET PREFERENCES
//ADD THE STRING TO THE INTENT BELOW, THEN PROCESS THE DATA FOR SETTING SHAREDPREFERENCES IN THE NEXT ACTIVITY
Log.d("UserID",userid);
Log.d("SecHash", hash);
Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
Bundle extras = new Bundle();
extras.putString("USERID",jsonObj.getString("uid"));
extras.putString("SECHASH",jsonObj.getString("security"));
extras.putString("USERID","userid");
extras.putString("SECHASH","hash");
intent.putExtras(extras);
startActivity(intent);
} else if (status.equals("Wrong")) {
Toast.makeText(context, "Username/Password is incorrect, could not be verified. Sign In failed.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Couldn't connect to remote database.", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(context, "Error parsing JSON data.", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "Couldn't get any JSON data.", Toast.LENGTH_SHORT).show();
}
}
}
}
In next activity get the extras from the intent and add them to the sharedPreferences. That is all there is to it.
Thanks to everyone for their assistance before. I hope this will help others who find themselves with the same problem in the future.
In doInBackground() you define a locale variable but use a members variable
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
if ((pref.contains(UserId)) && (pref.contains(Date))) {
}
Since you only assign pref in onPostExecute() you'll get NullPointerExceptions everytime. Also ctx is null and context is not even declared. So make sure you have pref defined as early as possible.
public class VerifyLogin extends AsyncTask<String, Void, String> {
private final SharedPreferences pref;
VerifyLogin() {
pref = getSharedPreferences(IgidPreference, Context.MODE_PRIVATE);
}
[...]
}
But in the end you should not implement it like this at all. You'll leak your activity here!
I am trying to make an persistent login application which then read sms from my phone and sends them to the an api with meaage body as well as the date and sender information. How can I proceed for the same.
I have made the login app but persistent login like facebook and other applications is not working.
Here is my code for the login application:
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import java.util.ArrayList;
public class LoginActivity extends ActionBarActivity {
private EditText un,pw;
private Button sign;
private TextView msg;
private String resp, errorMsg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
un = (EditText) findViewById(R.id.et_Username);
pw = (EditText) findViewById(R.id.et_Password);
sign = (Button) findViewById(R.id.bt_SignIn);
msg = (TextView) findViewById(R.id.tv_error);
sign.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/**
* According with the new StrictGuard policy, running long tasks
* on the Main UI thread is not possible So creating new thread
* to create and execute http operations
*/
new Thread(new Runnable() {
#Override
public void run() {
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("username",
un.getText().toString()));
postParameters.add(new BasicNameValuePair("password",
pw.getText().toString()));
String response = null;
try {
response = SimpleHttpClient
.executeHttpPost(
url,
postParameters);
String res = response.toString();
System.out.println(res);
resp = res.replaceAll("\\s+", "");
} catch (Exception e) {
e.printStackTrace();
errorMsg = e.getMessage();
}
}
}).start();
try {
Thread.sleep(1000);
/**
* Inside the new thread we cannot update the main thread So
* updating the main thread outside the new thread
*/
msg.setText(resp);
if (null != errorMsg && !errorMsg.isEmpty()) {
msg.setText(errorMsg);
}
} catch (Exception e) {
msg.setText(e.getMessage());
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I tried this now,got the idea for shred prefernece but somewhow its not working for me
I tried this it doesn't show my main activity:
Can you find the problem:
MainActivity:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import java.util.ArrayList;
public class MainActivity extends Activity {
private String resp, errorMsg;
private EditText username,password;
/*public static final String MyPREFERENCES = "MyPrefs" ;
public static final String name = "nameKey";
public static final String pass = "passwordKey";
SharedPreferences sharedpreferences;*/
SessionManager session;
private TextView msg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
username = (EditText)findViewById(R.id.editText1);
password = (EditText)findViewById(R.id.editText2);
msg = (TextView) findViewById(R.id.tv_error);
session = new SessionManager(this);
}
#Override
protected void onResume() {
//sharedpreferences=getSharedPreferences(MyPREFERENCES,
// Context.MODE_PRIVATE);
if (session.getuser()!=null)
{
if(session.getpassword()!=null){
Intent i = new Intent(this,
Welcome.class);
startActivity(i);
}
}
super.onResume();
}
public void login(View view){
String u = username.getText().toString();
String p = password.getText().toString();
{
/**
* According with the new StrictGuard policy, running long tasks
* on the Main UI thread is not possible So creating new thread
* to create and execute http operations
*/
new Thread(new Runnable() {
#Override
public void run() {
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("username",
username.getText().toString()));
postParameters.add(new BasicNameValuePair("password",
password.getText().toString()));
String response = null;
try {
response = SimpleHttpClient
.executeHttpPost(
"<url>",
postParameters);
String res = response.toString();
//System.out.println(res);
resp = res.replaceAll("\\s+", "");
} catch (Exception e) {
e.printStackTrace();
errorMsg = e.getMessage();
}
}
}).start();
try {
Thread.sleep(1000);
/**
* Inside the new thread we cannot update the main thread So
* updating the main thread outside the new thread
*/
msg.setText(resp);
if (null != errorMsg && !errorMsg.isEmpty()) {
msg.setText(errorMsg);
}
} catch (Exception e) {
msg.setText(e.getMessage());
}
}
if (resp.contains("false")) {
session.saveSession(u, p);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
Welcome:
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class Welcome extends Activity {
SessionManager session;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
session = new SessionManager(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//. getMenuInflater().inflate(R.menu, menu);
return true;
}
public void logout(View view){
session.logoutUser();
moveTaskToBack(true);
Welcome.this.finish();
}
public void exit(View view){
moveTaskToBack(true);
Welcome.this.finish();
}
public List<Sms> getAllSms() {
List<Sms> lstSms = new ArrayList<Sms>();
Sms objSms = new Sms();
Uri message = Uri.parse("content://sms/inbox");
ContentResolver cr = this.getContentResolver();
Cursor c = cr.query(message, null, null, null, null);
this.startManagingCursor(c);
int totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int i = 0; i < totalSMS; i++) {
if(c.getString(c.getColumnIndexOrThrow("address")).contains("icicib")|| c.getString(c.getColumnIndexOrThrow("address")).contains("hdfcbk") || c.getString(c.getColumnIndexOrThrow("address")).contains("dbalrt")
||c.getString(c.getColumnIndexOrThrow("address")).contains("citibk")||c.getString(c.getColumnIndexOrThrow("address")).contains("unionb")||c.getString(c.getColumnIndexOrThrow("address")).contains("atmsbi")
|| c.getString(c.getColumnIndexOrThrow("address")).contains("sbiinb") || c.getString(c.getColumnIndexOrThrow("address")).contains("indusb") ||c.getString(c.getColumnIndexOrThrow("address")).contains("fedbnk")
|| c.getString(c.getColumnIndexOrThrow("address")).contains("kotakb")||c.getString(c.getColumnIndexOrThrow("address")).contains("axisbk")||c.getString(c.getColumnIndexOrThrow("address")).contains("pnbsms")
|| c.getString(c.getColumnIndexOrThrow("address")).contains("hsbcin") || c.getString(c.getColumnIndexOrThrow("address")).contains("canbnk") || c.getString(c.getColumnIndexOrThrow("address")).contains("idbi")
||c.getString(c.getColumnIndexOrThrow("address")).contains("iob") || c.getString(c.getColumnIndexOrThrow("address")).contains("citibk") || c.getString(c.getColumnIndexOrThrow("address")).contains("hdfcbk")
||c.getString(c.getColumnIndexOrThrow("address")).contains("fromsc") ||c.getString(c.getColumnIndexOrThrow("address")).contains("myamex") || c.getString(c.getColumnIndexOrThrow("address")).contains("26463872")
|| c.getString(c.getColumnIndexOrThrow("address")).contains("sbicrd") || c.getString(c.getColumnIndexOrThrow("address")).contains("icici?") || c.getString(c.getColumnIndexOrThrow("address")).contains("syndbk")
|| c.getString(c.getColumnIndexOrThrow("address")).contains("121") || c.getString(c.getColumnIndexOrThrow("address")).contains("best deal(121)") || c.getString(c.getColumnIndexOrThrow("address")).contains("airtel")
|| c.getString(c.getColumnIndexOrThrow("address")).contains("vfcare") || c.getString(c.getColumnIndexOrThrow("address")).contains("vodafone") || c.getString(c.getColumnIndexOrThrow("address")).contains("mytsky")||c.getString(c.getColumnIndexOrThrow("address")).contains("dishpy") ) {
objSms = new Sms();
objSms.setAddress(c.getString(c .getColumnIndexOrThrow("address")));
objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body")));
objSms.setTime(c.getString(c.getColumnIndexOrThrow("date")));
lstSms.add(objSms);
}
c.moveToNext();
}
}
// else {
// throw new RuntimeException("You have no SMS");
// }
c.close();
return lstSms;
}
}
SessionManager:
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
public class SessionManager {
SharedPreferences pref;
SharedPreferences.Editor editor;
Context _context;
int PRIVATE_MODE = 0;
private static final String PREFER_NAME = "AndroidExamplePref";
public static final String KEY_USER = "username";
public static final String KEY_PWD = "password";
public SessionManager(Context context){
this._context = context;
pref = _context.getSharedPreferences(PREFER_NAME, PRIVATE_MODE);
editor = pref.edit();
}
public void saveSession(String user, String pwd){
editor.putString(KEY_USER, user);
editor.putString(KEY_PWD, pwd);
editor.commit();
}
public String getuser()
{
String s = pref.getString(KEY_USER,"");
return s;
}
public String getpassword()
{
String p = pref.getString(KEY_PWD,"");
return p;
}
public void logoutUser(){
editor.clear();
editor.commit();
Intent i = new Intent(_context,.MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
_context.startActivity(i);
}
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package=".sample" >
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.read_sms" />
<uses-permission android:name="android.permission.SEND_SMS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Welcome"
android:label="#string/title_activity_welcome" >
</activity>
</application>
</manifest>
UPDATED ANSWER:
IT works now
i made session as static and before logging I am checking the shared preference value and accordingly going ahead. Everything is working now.
I guess you are meaning "persistent login application" -> User will log in once & for the next time they will not need to log in again with user name & password, right?
For this the naive approach would be storing the username & password in shared preference / db. But its not a good approach as it stores the password.
Instead of doing this, you can store, the userId/access token (obtained from the response). You should also have an expiration time so that you can prompt for log in validating the userId/access token after certain time.
Facebook seems to do the same thing I guess. E.g. if you clear data from on facebook app, then you does need to log in again.
I hope this gives you a direction.
Updated Answer
I guess you are not clear about pref.getString() method. The overloaded method (with 2 param) will return the 2nd param you sent, if any value with the query KEY (the 1st param)is not found.
In your case, in
public String getuser()
{
String s = pref.getString(KEY_USER,""); // here is the error, "" is not null, its an empty String.
return s;
}
So you can change this trouble causing line into either of the following line-
String s = pref.getString(KEY_USER,null);
or
String s = pref.getString(KEY_USER);
Same problem in the getuser(). Hopefully this will solve your problem :)
![here there are 3 edit text box. where i am using json to check the login id and password details and another text box is for the selection of the server address. the only criteria is that all these should be done with a single button ie the login button.
can any one help me with the code]1
the code is as follows
package com.example.catxam;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.catxam.JSONParser;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.EditText;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
public class Login extends Activity {
private EditText inputUserid, inputPassword, server;
TextView forgotPassword;
private Button b1;
public String serve;
// Progress Dialog
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String Flag = "flag";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.login);
inputUserid = (EditText) findViewById(R.id.Username_edit);
inputPassword = (EditText) findViewById(R.id.User_password);
server = (EditText) findViewById(R.id.serverSelection);
forgotPassword = (TextView) findViewById(R.id.forgotPassword);
forgotPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent passForget = new Intent(getApplicationContext(),
ForgotPassword.class);
startActivity(passForget);
}
});
b1 = (Button) findViewById(R.id.loginbutton); // login button
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
new CreateNewUser().execute();
new SelectServerAddress().execute();
}
});
}
// this class is for selection of the server address
class SelectServerAddress extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... arg0) {
return null;
}
}
// this class is for the checking of the user login and password
//i.e. of first login and the next consecutive logins
class CreateNewUser extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Login.this);
pDialog.setMessage("Checking..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Checking creditenials
* */
protected String doInBackground(String... args) {
String user = inputUserid.getText().toString();
String pswrd = inputPassword.getText().toString();
//if (serve == "")
//{
//serve = "192.168.0.101/gly_prov_V1";
//}
//else
//{
//serve = "glydenlewis.esy.es";
//}
// URL to check username & password
final String url_check_user = "http://" + serve +"/gly_prov_V1/android_check.php";
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("uname", user));
params.add(new BasicNameValuePair("psd", pswrd));
params.add(new BasicNameValuePair("server",serve));
// getting JSON Object
// Note that create product url accepts POST method
JSONObject json = jsonParser.makeHttpRequest(url_check_user,
"POST", params);
// check log cat from response
Log.d("Create Response", json.toString());
// check for success tag
try {
int success = json.getInt(TAG_SUCCESS);
int flag_ck = json.getInt(Flag);
if (success == 1) {
if (flag_ck == 0)
{
//First Time Login By User
Intent i = new Intent(getApplicationContext(), UpdateDetails.class);
startActivity(i);
finish(); // closing this screen
}
else
{
// successfully login
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
finish(); // closing this screen
}
} else {
Toast.makeText(getApplicationContext(), "Wrong Credentials", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
}
You can execute tasks in serial manner. Take the output of first task as input to the second task.
But you have to implement a cancel mechanism if the activity is destroyed while your tasks is actually running. a simple approach is to make tasks references as a class member and cancel it when activity's onStop() method is called.
class static SelectServerAddress extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... urls) {
return getAddress(urls[0]);
}
#Override
protected void onPostExecute(String serverAddress) {
// Call login service
mLoginTask = new CreateNewUser(serverAddress);
mLoginTask.execute();
}
}
Edit:
Update button click listener code to this:
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
new SelectServerAdress().execute();
}
});
Then update SelectServerAdress class and add this method:
#Override
protected void onPostExecute(String serverAddress) {
serve = serverAddress;
new SelectServerAddress().execute();
}
I am trying to establish a chatting application between a server and a client, but the application could not run because of this line of code : message = (String) input.readObject();
because at first, inputStream is null ! any one can help please ? here is my code
package com.example.test;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.net.Socket;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button send;
private Button connect;
private EditText userText;
private TextView chatWindow;
private String serverIP;
private ObjectOutputStream output;
private ObjectInputStream input;
private String message = "";
private Socket connection;
#SuppressLint({ "NewApi", "NewApi", "NewApi" })
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
serverIP = "192.168.1.4";
//userText.setEnabled(false);
send = (Button)findViewById(R.id.button1);
connect = (Button)findViewById(R.id.button2);
chatWindow =(TextView)findViewById(R.id.textView1);
userText = (EditText)findViewById(R.id.editText1);
userText.setHint("Enter your message here");
connect.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//connect to the server
try{
connectToServer();
setupStreams();
}catch(EOFException eofException){
showMessage("\n client terminated the connection");
}catch(IOException ioException){
ioException.printStackTrace();
}
}
});
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String message = userText.getText().toString();
sendMessage(message);
userText.setText("");
}
});
while(true){
try{
message = (String) input.readObject();
showMessage("\n" + message + " NULL ");
chatWindow.refreshDrawableState();
}catch(ClassNotFoundException classNotFoundException){
showMessage("\n I don't know that object type");
}
catch(NullPointerException e){
e.printStackTrace();
}
catch (OptionalDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} // end of onCreate
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
//connect to the server
private void connectToServer() throws IOException {
showMessage("Attempting connection... \n");
connection = new Socket( "192.168.1.4", 6789);
showMessage("Connected to " + connection.getInetAddress().getHostName() );
}
//setup streams to send and receive messages
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n Your streams are now good to go! \n ");
}
//whileChatting with server
private void whileChatting() throws IOException{
try{
message = (String) input.readObject();
showMessage("\n" + message + " NULL ");
chatWindow.refreshDrawableState();
}catch(ClassNotFoundException classNotFoundException){
showMessage("\n I don't know that object type");
}
}
//close the streams and sockets
private void closeCrap(){
showMessage("\n closing crap down");
ableToType(false);
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException){
ioException.printStackTrace();
}
}
// gives user permission to type into the text box
private void ableToType(final boolean tof){
userText.setEnabled(tof);
}
// send messages to server
private void sendMessage(String message){
try{
output.writeObject("CLIENT - " + message);
output.flush();
showMessage("\nCLIENT - " + message);
}catch(IOException ioException){
chatWindow.append("\n somethine messed up sending message!");
}
}
//change/update chatWindow
private void showMessage(final String m){
chatWindow.append(m);
chatWindow.refreshDrawableState();
}
} // end of class MainActivity
Your code is definitely not following any good UI guidelines: You are doing network operations on the Main (UI) Thread, and you have an infinite loop in onCreate(). Android should actually offer to force close your app if nothing crashes. Now, a likely cause for the null problem you are facing:
setupStreams() is only called upon a button click. However, your while (true) loop is in the root of onCreate(). This means that as soon as the click listeners are made and set, the loop runs, attempts to read in from input and fails since setupStreams() hasn't been called.
So please don't do away with StrictMode - it's there to help, and thing about your code from an event driven standpoint ("Once X happens, then do Y"). And also get rid of loops in the Main (UI) Thread. Loops are fine for Console windows, but with UIs (which have their own complex lifecycle), you can't do this without freezing a lot of things.
Do all of your network tasks in doInBackground() ofAsyncTask then update your UI variables in onPostExecute(). Something like
public class TalkToServer extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected String doInBackground(String... params) {
//do your work here
return something;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// do something with data here-display it or send to mainactivity
}
Here is the documentation on AsyncTask
Another thing to consider is you are using the variable message in different places which may cause you problems. It looks like you have it defined as a member variable then as a local variable to other methods. You don't want to re-use the same variable name this way. Don't define String message multiple times in the same Activity
I've written an app that sits in the 'Share via' menu (for quickly emailing myself links to things I find on the web or look at in RSS readers) For this I'm using an intent.action.SEND intent-filter:
<activity
android:name="uk.co.baroquedub.checkit.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Here's the MainActivity package, it grabs the page title and url from the Intent and uses a separate GMailSender class to directly email me this info:
package uk.co.baroquedub.checkit;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private static Dialog dialog;
String title;
String url;
String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );
String action = intent.getAction();
// if this is from the share menu
if (Intent.ACTION_SEND.equals(action)) {
title = intent.getStringExtra(Intent.EXTRA_SUBJECT);
url = intent.getStringExtra(Intent.EXTRA_TEXT);
// Flipboard fix (remove title in URL)
url = url.replace(title, "");
if (url != null){
url = title+"\n"+url;
} else {
url = "error getting URL";
}
// Asynch Task
doSendTask task = new doSendTask();
task.execute(new String[] { url });
}
}
protected void showDialog (String response){
dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog);
dialog.setTitle(response);
Button button = (Button) dialog.findViewById(R.id.Button01);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
finish();
}
});
dialog.show();
}
private class doSendTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
String senderPassword = getResources().getString(R.string.senderPassword);
String senderEmail = getResources().getString(R.string.senderEmail);
String recipientEmail = getResources().getString(R.string.recipientEmail);
String subjectText = getResources().getString(R.string.subjectText);
GMailSender sender = new GMailSender(senderEmail, senderPassword);
try {
sender.sendMail(subjectText,
url,
senderEmail,
recipientEmail);
response = "Email sent";
} catch (Exception e) {
//Log.e("SendMail", e.getMessage(), e);
response = "Error sending email";
}
return response;
}
#Override
protected void onPostExecute(String result) {
showDialog(result);
}
}
#Override
public void onDestroy() {
super.onDestroy();
/*
* Kill application when the root activity is killed.
*/
UIHelper.killApp(true);
}
}
Version 1 worked fine but I was sending the email from within 'onCreate' which meant that until the "Email sent" notification appeared, the phone's browser would be unresponsive (I wasn't able to scroll or navigate to a new page). I then changed the code (as per above) to place the email sending code inside an AsyncTask class - but although the app still works the browser remains unresponsive until the dialog appears. AsyncTask seems to have made no difference.
Can anyone explain why, and hopefully suggest a solution?
ANSWER?... I've massively simplified the above code to try to work out what might be wrong. I created a bog standard App and used the following:
package uk.co.baroquedub.testcheck;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
doSendTask task = new doSendTask();
task.execute(new String[] { "urlString" });
}
protected void showDialog (String response){
Toast.makeText(this, response, Toast.LENGTH_SHORT).show();
finish();
}
private class doSendTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
try {
Thread.sleep(5000);
response = "Waited";
}
catch (InterruptedException ex) { }
return response;
}
#Override
protected void onPostExecute(String result) {
showDialog(result);
}
}
}
This has allowed me to see what's going wrong: my app is opening on top of the browser (a white screen appears with a title bar showing the name of the app) I wasn't aware of this with my proper app (above) because I was using a Theme that used a transparent background.
See: screencast for demo of problem
So although the email is being sent as an AsyncTask, while this is happening the app itself is appearing on top of the browser - which is what is stopping it from being accessible. (I'll post a request for help on this as a separate question)
No, AsyncTask is not bond to your UI thread and you will not be blocking it as you did while doing some lengthy operation in your onCreate().
I think you have a mistake in your code:
doSendTask task = new doSendTask();
task.execute(url); // if you want to put more urls task.execute(url,url1,url2);
try {
sender.sendMail(subjectText,
url[0], // get the first url
senderEmail,
recipientEmail);
response = "Email sent";
} catch (Exception e) {
//Log.e("SendMail", e.getMessage(), e);
response = "Error sending email";
}
ASyncTasks are, indeed, executed on their own thread, as written on their reference page.
When you create the intent for this activity, you pass the flag 'FLAG_ACTIVITY_CLEAR_TOP', which reads something like '...all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.'. Doesn't this mean that the old activity is locked until this new one terminates?