I'm trying to create a secure login with android but I have no way of testing it's functionality as the registration feature doesn't work. I have ensured I'm properly connected to the DB and I currently do not receive any errors.
functions.php
This file contains functions for checking whether the user exists not, functions for generating password salt and hashes. I made use of random salt generator so that a unique salt and hash is generated for each user.
<?php
$random_salt_length = 32;
function userExists($username){
$query = "SELECT username FROM member WHERE username = ?";
global $con;
if($stmt = $con->prepare($query)){
$stmt->bind_param("s",$username);
$stmt->execute();
$stmt->store_result();
$stmt->fetch();
if($stmt->num_rows == 1){
$stmt->close();
return true;
}
$stmt->close();
}
return false;
}
function getSalt(){
global $random_salt_length;
return bin2hex(openssl_random_pseudo_bytes($random_salt_length));
}
function concatPasswordWithSalt($password,$salt){
global $random_salt_length;
if($random_salt_length % 2 == 0){
$mid = $random_salt_length / 2;
}
else{
$mid = ($random_salt_length - 1) / 2;
}
return
substr($salt,0,$mid - 1).$password.substr($salt,$mid,$random_salt_length - 1);
}
?>
register.php
<?php
$response = array();
include 'db/db_connect.php';
include 'functions.php';
//Get the input request parameters
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE); //convert JSON into array
//Check for Mandatory parameters
if(isset($input['username']) && isset($input['password']) && isset($input['full_name'])){
$username = $input['username'];
$password = $input['password'];
$fullName = $input['full_name'];
//Check if user already exist
if(!userExists($username)){
//Get a unique Salt
$salt = getSalt();
//Generate a unique password Hash
$passwordHash = password_hash(concatPasswordWithSalt($password,$salt),PASSWORD_DEFAULT);
//Query to register new user
$insertQuery = "INSERT INTO member(username, full_name, password_hash, salt) VALUES (?,?,?,?)";
if($stmt = $con->prepare($insertQuery)){
$stmt->bind_param("ssss",$username,$fullName,$passwordHash,$salt);
$stmt->execute();
$response["status"] = 0;
$response["message"] = "User created";
$stmt->close();
}
}
else{
$response["status"] = 1;
$response["message"] = "User exists";
}
}
else{
$response["status"] = 2;
$response["message"] = "Missing mandatory parameters";
}
echo json_encode($response);
?>
registerActivity
public class RegisterActivity extends AppCompatActivity {
private static final String KEY_STATUS = "status";
private static final String KEY_MESSAGE = "message";
private static final String KEY_FULL_NAME = "full_name";
private static final String KEY_USERNAME = "username";
private static final String KEY_PASSWORD = "password";
private static final String KEY_EMPTY = "";
private EditText etUsername;
private EditText etPassword;
private EditText etConfirmPassword;
private EditText etFullName;
private String username;
private String password;
private String confirmPassword;
private String fullName;
private ProgressDialog pDialog;
private String register_url = "http://10.0.0.1/members/register.php";
private SessionHandler session;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
session = new SessionHandler(getApplicationContext());
setContentView(R.layout.activity_register);
etUsername = findViewById(R.id.etUsername);
etPassword = findViewById(R.id.etPassword);
etConfirmPassword = findViewById(R.id.etConfirmPassword);
etFullName = findViewById(R.id.etFullName);
Button login = findViewById(R.id.btnRegisterLogin);
Button register = findViewById(R.id.btnRegister);
//Launch Login screen when Login Button is clicked
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(i);
finish();
}
});
register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Retrieve the data entered in the edit texts
username = etUsername.getText().toString().toLowerCase().trim();
password = etPassword.getText().toString().trim();
confirmPassword = etConfirmPassword.getText().toString().trim();
fullName = etFullName.getText().toString().trim();
if (validateInputs()) {
registerUser();
}
}
});
}
// Display Progress bar while registering
private void displayLoader() {
pDialog = new ProgressDialog(RegisterActivity.this);
pDialog.setMessage("Signing Up.. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
// Launch Dashboard Activity on Successful Sign Up
private void loadDashboard() {
Intent i = new Intent(getApplicationContext(), DashboardActivity.class);
startActivity(i);
finish();
}
private void registerUser() {
displayLoader();
JSONObject request = new JSONObject();
try {
//Populate the request parameters
request.put(KEY_USERNAME, username);
request.put(KEY_PASSWORD, password);
request.put(KEY_FULL_NAME, fullName);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsArrayRequest = new JsonObjectRequest
(Request.Method.POST, register_url, request, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
pDialog.dismiss();
try {
//Check if user got registered successfully
if (response.getInt(KEY_STATUS) == 0) {
//Set the user session
session.loginUser(username,fullName);
loadDashboard();
}else if(response.getInt(KEY_STATUS) == 1){
//Display error message if username is already existing
etUsername.setError("Username already taken!");
etUsername.requestFocus();
}else{
Toast.makeText(getApplicationContext(),
response.getString(KEY_MESSAGE), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pDialog.dismiss();
//Display error message whenever an error occurs
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
// Access the RequestQueue through your singleton class.
VolleySingleton.getInstance(this).addToRequestQueue(jsArrayRequest);
}
sessionHandler
public class SessionHandler {
private static final String PREF_NAME = "UserSession";
private static final String KEY_USERNAME = "username";
private static final String KEY_EXPIRES = "expires";
private static final String KEY_FULL_NAME = "full_name";
private static final String KEY_EMPTY = "";
private Context mContext;
private SharedPreferences.Editor mEditor;
private SharedPreferences mPreferences;
public SessionHandler(Context mContext) {
this.mContext = mContext;
mPreferences = mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
this.mEditor = mPreferences.edit();
}
public void loginUser(String username, String fullName) {
mEditor.putString(KEY_USERNAME, username);
mEditor.putString(KEY_FULL_NAME, fullName);
Date date = new Date();
//Set user session for next 7 days
long millis = date.getTime() + (7 * 24 * 60 * 60 * 1000);
mEditor.putLong(KEY_EXPIRES, millis);
mEditor.commit();
}
public boolean isLoggedIn() {
Date currentDate = new Date();
long millis = mPreferences.getLong(KEY_EXPIRES, 0);
/* If shared preferences does not have a value
then user is not logged in
*/
if (millis == 0) {
return false;
}
Date expiryDate = new Date(millis);
/* Check if session is expired by comparing
current date and Session expiry date
*/
return currentDate.before(expiryDate);
}
public User getUserDetails() {
//Check if user is logged in first
if (!isLoggedIn()) {
return null;
}
User user = new User();
user.setUsername(mPreferences.getString(KEY_USERNAME, KEY_EMPTY));
user.setFullName(mPreferences.getString(KEY_FULL_NAME, KEY_EMPTY));
user.setSessionExpiryDate(new Date(mPreferences.getLong(KEY_EXPIRES, 0)));
return user;
}
/**
* Logs out user by clearing the session
*/
public void logoutUser(){
mEditor.clear();
mEditor.commit();
}
}
Can you please push me in the right direction as I can't quite figure out where I'm going wrong
If no error message is displayed but nothing is written to the database, it's possible your query is failing to execute.
This piece of code in register.php currently does not have any error checking:
//Query to register new user
$insertQuery = "INSERT INTO member(username, full_name, password_hash, salt) VALUES (?,?,?,?)";
if($stmt = $con->prepare($insertQuery)){
$stmt->bind_param("ssss",$username,$fullName,$passwordHash,$salt);
$stmt->execute();
$response["status"] = 0;
$response["message"] = "User created";
$stmt->close();
}
This can fail in two places:
$con->prepare() can fail if the database already knows the query won't be executed, e.g. due to a syntax error or because a table or column name doesn't exist or your user doesn't have the right permissions to perform an INSERT query into that table
$stmt->execute() can fail if the query fails at runtime, e.g. if you're trying to insert a string into a column that only accepts integer values.
You should add some extra checks on that. At some point you will want to provide a useful error message to your app so users aren't confronted with technical mumbo-jumbo that they can't fix, but for now while debugging I'd recommend to dump the error message in there (it looks like a status of > 1 indicates an error, correct me if I'm wrong):
//Query to register new user
$insertQuery = "INSERT INTO member(username, full_name, password_hash, salt) VALUES (?,?,?,?)";
if($stmt = $con->prepare($insertQuery)){
$stmt->bind_param("ssss",$username,$fullName,$passwordHash,$salt);
if ($stmt->execute()) {
$response["status"] = 0;
$response["message"] = "User created";
} else {
$response["status"] = 2;
$response["message"] = $stmt->error;
}
$stmt->close();
} else {
$response["status"] = 2;
$response["message"] = $con->error;
}
Related
edit text value wont change even the value in the database is already change, its show the previous content and I need to debug again the application to show the new data. I already use this but the value still not change until I debug it again.
i can insert in database using this code but when i display the value of it the old value is the one showing not the updated one. thats why the i say the edittext and textview value not changing.
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_userdetails);
super.onCreate(savedInstanceState);
//if the user is not logged in
//starting the login activity
if (!SharedPrefManager.getInstance(this).isLoggedIn()) {
finish();
startActivity(new Intent(this, LoginActivity.class));
}
User user = SharedPrefManager.getInstance(this).getUser();
Circleimage = findViewById(R.id.Circleimage);
bt_update = findViewById(R.id.bt_update);
Btn_Editprofile = findViewById(R.id.Btn_Editprofile);
textViewFullname = findViewById(R.id.textViewFullname);
textViewId = findViewById(R.id.textViewId);
textViewLastname = findViewById(R.id.textViewLastname);
textViewFirstname = findViewById(R.id.textViewFirstname);
textViewMiname = findViewById(R.id.textViewMiname);
textViewSuname = findViewById(R.id.textViewSuname);
textViewUsername = findViewById(R.id.textViewUsername);
textViewAddress = findViewById(R.id.textViewAddress);
textViewAddress1 = findViewById(R.id.textViewAddress1);
textViewBirthday = findViewById(R.id.textViewBirthday);
textViewBirthday1 = findViewById(R.id.textViewBirthday1);
textViewEmail = findViewById(R.id.textViewEmail);
textViewGender = findViewById(R.id.textViewGender);
textViewHeight = findViewById(R.id.textViewHeight);
textViewWeight = findViewById(R.id.textViewWeight);
Btn_Editprofilepic= findViewById(R.id.Btn_Editprofilepic);
spinner1 = findViewById(R.id.spinner1);
//getting the current user
//setting the values to the textviews
textViewFullname.setText(user.getFirstname() + " " + user.getLastname());
textViewId.setText(String.valueOf(user.getId()));
textViewLastname.setText(user.getLastname());
textViewFirstname.setText(user.getFirstname());
textViewMiname.setText(user.getMiddlename());
textViewSuname.setText(user.getSuffix());
textViewUsername.setText(user.getUsername());
textViewAddress.setText(user.getAddress());
textViewAddress1.setText(user.getAddress1());
textViewBirthday.setText(user.getBirthday());
textViewBirthday1.setText(user.getBirthday1());
textViewEmail.setText(user.getEmail());
textViewGender.setText(user.getGender());
textViewHeight.setText(user.getHeight());
textViewWeight.setText(user.getWeight());
textViewdatashow = findViewById(R.id.textViewId);
}
public void btn_update(View view) {
final String Clastname = textViewLastname.getText().toString().trim();
final String Cfirstname = textViewFirstname.getText().toString().trim();
final String Cmiddlename = textViewMiname.getText().toString().trim();
//first we will do the validations
if (TextUtils.isEmpty(Clastname)) {
textViewLastname.setError("Please enter Lastname");
textViewLastname.requestFocus();
return;
}
if (TextUtils.isEmpty(Cfirstname)) {
textViewFirstname.setError("Please enter Firstname");
textViewFirstname.requestFocus();
return;
}
if (TextUtils.isEmpty(Cmiddlename)) {
textViewMiname.setError("Please enter Middlename");
textViewMiname.requestFocus();
return;
}
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Updating....");
progressDialog.show();
StringRequest request = new StringRequest(Request.Method.POST, "http://192.168.3.106/loginregister/update.php",
response -> {
Toast.makeText(ProfileActivity.this, response, Toast.LENGTH_SHORT).show();
//startActivity(new Intent(getApplicationContext(),MainActivity.class));
progressDialog.dismiss();
}, error -> {
Toast.makeText(ProfileActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
finish();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
progressDialog.dismiss();
}) {
final String id = textViewId.getText().toString().trim();
final String lastname = textViewLastname.getText().toString().trim();
final String firstname = textViewFirstname.getText().toString().trim();
final String middlename = textViewMiname.getText().toString().trim();
final String suffix = textViewSuname.getText().toString().trim();
final String username = textViewUsername.getText().toString().trim();
final String address = textViewAddress.getText().toString().trim();
final String address1 = textViewAddress1.getText().toString().trim();
final String birthday = textViewBirthday.getText().toString().trim();
final String birthday1 = textViewBirthday1.getText().toString().trim();
final String email = textViewEmail.getText().toString().trim();
final String password = textViewGender.getText().toString().trim();
final String height = textViewHeight.getText().toString().trim();
final String weight = textViewWeight.getText().toString().trim();
final String vaccine = spinner1.getText().toString().trim();
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("id", id);
params.put("lastname", lastname);
params.put("firstname", firstname);
params.put("middlename", middlename);
params.put("suffix", suffix);
params.put("username", username);
params.put("address", address);
params.put("address1", address1);
params.put("birthday", birthday);
params.put("birthplace", birthday1);
params.put("email", email);
params.put("password", password);
params.put("height", height);
params.put("weight", weight);
params.put("vaccine", vaccine);
return params;
}
};
bt_update.setEnabled(false);
Btn_Editprofile.setEnabled(true);
textViewAddress.setEnabled(false);
textViewAddress1.setEnabled(false);
textViewBirthday.setEnabled(false);
textViewBirthday1.setEnabled(false);
textViewGender.setEnabled(false);
textViewHeight.setEnabled(false);
textViewWeight.setEnabled(false);
spinner1.setEnabled(false);
Circleimage.setEnabled(false);
RequestQueue requestQueue = Volley.newRequestQueue(ProfileActivity.this);
requestQueue.add(request);
}
public class UserprofileActivity extends AppCompatActivity {
// VARIABLES
TextView fullName, userName, location, motorcycle;
TextInputLayout fullNameInput, emailInput, motorcycleInput, passwordInput;
// GLOBAL VARIABLES TO HOLD USER DATA INSIDE THIS ACTIVITY
String _NAME, _USERNAME, _EMAIL, _LOCATION, _MOTORCYCLE, _PASSWORD;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_userprofile);
reference = FirebaseDatabase.getInstance().getReference("users");
// HOOKS
fullName = findViewById(R.id.profileFullName);
userName = findViewById(R.id.profileUsername);
location = findViewById(R.id.profileLocalization);
motorcycle = findViewById(R.id.profileMotorcycle);
fullNameInput = findViewById(R.id.profile_FullName);
emailInput = findViewById(R.id.profile_Email);
motorcycleInput = findViewById(R.id.profile_Motorcycle);
passwordInput = findViewById(R.id.profile_Password);
// SHOW ALL DATA
showAllUserData();
}
private void showAllUserData() {
Intent intent = getIntent();
_NAME = intent.getStringExtra("name");
_USERNAME = intent.getStringExtra("username");
_EMAIL = intent.getStringExtra("email");
_LOCATION = intent.getStringExtra("location");
_MOTORCYCLE = intent.getStringExtra("motorcycle");
_PASSWORD = intent.getStringExtra("password");
// this variable goes to (TextInputLayout "fullNameInput) and (TextView fullName) this goes to update the full name of the user and also is motorcycle brand. It should update both TextViews(Full Name and Motorcycle) with the data retrieved from the database at the same time and as soon as i would click the update button below the form. But it only updates after a new login. (The table name of the Database is users and the first child is the Username). enter image description here
fullName.setText(_NAME);
userName.setText(_USERNAME);
location.setText(_LOCATION);
motorcycle.setText(_MOTORCYCLE);
Objects.requireNonNull(fullNameInput.getEditText()).setText(_NAME);
Objects.requireNonNull(emailInput.getEditText()).setText(_EMAIL);
Objects.requireNonNull(motorcycleInput.getEditText()).setText(_MOTORCYCLE);
Objects.requireNonNull(passwordInput.getEditText()).setText(_PASSWORD);
}
private boolean isNameChanged() {
if (!_NAME.equals(Objects.requireNonNull(fullNameInput.getEditText()).getText().toString())) {
reference.child(_USERNAME).child("name").setValue(fullNameInput.getEditText().getText().toString());
fullName.getText().equals(_NAME);
return true;
} else {
return false;
}
}
private boolean isMotorcycleChanged() {
if (!_MOTORCYCLE.equals(Objects.requireNonNull(motorcycleInput.getEditText()).getText().toString())) {
reference.child(_USERNAME).child("motorcycle").setValue(motorcycleInput.getEditText().getText().toString());
return true;
} else {
return false;
}
}
public void update(View view) {
if (isNameChanged() || isEmailChanged() || isMotorcycleChanged() || isPasswordChanged()) {
Toast.makeText(this, "Data has been Updated Successfully", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Data is the Same and therefore Cannot be Updated", Toast.LENGTH_LONG).show();
}
}
}
I am creating an app for staff (users) in a factory. The app needs be logged into by the user. After login, on the next page, the spinner value is based on the user's department. If the user is from the IT department, then the spinner will populate the list of all the 'managers' names' from the IT department. Likewise, when the user is from the Engineering department, then the spinner will populate the list of all managers' names from the Engineering department. The problem is, currently, the spinner will list all managers from all departments. How can I adjust my code to show only the manager names from the user's department?
php code for user login and list 'mysuggestion':
<?php
require_once 'dbConnect.php';
$response = array();
if(isset($_GET['apicall'])){
if(isTheseParametersAvailable(array('username', 'password', 'approver'))){
$username = $_POST['username'];
$password = $_POST['password'];
$approver = $_POST['approver'];
$stmt = $conn->prepare("SELECT users.id, users.name, users.badgeid, users.position, users.department, users.factory,
mysuggestion.reviewer, mysuggestion.title, mysuggestion.year, mysuggestion.month, mysuggestion.suggestionwill, mysuggestion.present,
mysuggestion.details, mysuggestion.benefit, mysuggestion.photo, mysuggestion.status, mysuggestion.comment
FROM users left JOIN mysuggestion on users.badgeid = mysuggestion.badgeid
WHERE users.username = ? AND users.password = ? AND users.approver = ? ORDER BY mysuggestion.id DESC;");
$stmt->bind_param("sss",$username, $password, $approver);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows > 0){
$stmt->bind_result($id, $name, $badgeid, $position, $department, $factory, $reviewer, $title, $year, $month, $suggestionwill, $present, $details, $benefit, $photo, $status ,$comment);
$stmt->fetch();
$user = array(
'id'=>$id,
'name'=>$name,
'badgeid'=>$badgeid,
'position'=>$position,
'department'=>$department,
'factory'=>$factory,
'reviewer'=>$reviewer,
'title'=>$title,
'year'=>$year,
'month'=>$month,
'suggestionwill'=>$suggestionwill,
'present'=>$present,
'details'=>$details,
'benefit'=>$benefit,
'photo'=>$photo,
'status'=>$status,
'comment'=>$comment
);
$response['error'] = false;
$response['message'] = 'Login successfull';
$response['user'] = $user;
}else{
$response['error'] = false;
$response['message'] = 'The data that you insert is not match !!';
}
}
}else{
$response['error'] = true;
$response['message'] = 'Invalid API Call';
}
echo json_encode($response);
function isTheseParametersAvailable($params){
foreach($params as $param){
if(!isset($_POST[$param])){
return false;
}
}
return true;
}
php to populate data from mysql to spinner:
<?php
$sql = "SELECT * FROM users WHERE approver = 'Reviewer';";
require_once('dbConnect.php');
$r = mysqli_query($conn,$sql);
$reviewer= array();
while($row = mysqli_fetch_array($r)){
array_push($reviewer,array(
'id'=>$row['id'],
'name'=>$row['name'],
'badgeid'=>$row['badgeid']
));
}
echo json_encode(array('result'=>$reviewer));
mysqli_close($conn);
java code where the spinner located
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_suggestion);
final ActionBar abar = getSupportActionBar();
View viewActionBar = getLayoutInflater().inflate(R.layout.activity_new_suggestion, null);
ActionBar.LayoutParams params = new ActionBar.LayoutParams(//Center the textview in the ActionBar !
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.MATCH_PARENT,
Gravity.CENTER);
TextView tvTitle = viewActionBar.findViewById(R.id.title);
tvTitle.setText("NEW SUGGESTION");
abar.setCustomView(viewActionBar, params);
abar.setDisplayShowCustomEnabled(true);
abar.setDisplayShowTitleEnabled(false);
//abar.setDisplayHomeAsUpEnabled(true);
abar.setHomeButtonEnabled(true);
final SharedPreferences sharedPref = getSharedPreferences("MyData", MODE_PRIVATE);
etTitle = findViewById(R.id.etTitle);
etTitle.setText(sharedPref.getString("title", ""));
etTitle.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
#Override
public void afterTextChanged(Editable s)
{
sharedPref.edit().putString("benefit", s.toString()).apply();
}
});
etYear = findViewById(R.id.etYear);
etMonth = findViewById(R.id.etMonth);
rgSuggestWill =findViewById(R.id.rgSuggestWill);
reviewer = new ArrayList<>();
final Calendar c = Calendar.getInstance();
String mm = c.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.US);
int yy = c.get(Calendar.YEAR);
etYear.setText(new StringBuilder().append(yy));
etMonth.setText(new StringBuilder().append(mm));
spReviewer = findViewById(R.id.spReviewer);
getData();
btnNext = findViewById(R.id.btnNext);
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences sharedPref = getSharedPreferences("MyData",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("title",etTitle.getText().toString());
editor.putString("year",etYear.getText().toString());
editor.putString("month",etMonth.getText().toString());
int selectedId = rgSuggestWill.getCheckedRadioButtonId();
radioButton = findViewById(selectedId);
editor.putString("suggestionwill",radioButton.getText().toString());
editor.putString("reviewer",spReviewer.getSelectedItem().toString());
editor.putString("status", "Pending");
editor.apply();
Intent intent = new Intent(NewSuggestion.this, NewSuggestion2.class);
startActivity(intent);
}
});
}
private void getData(){
//Creating a string request
StringRequest stringRequest = new StringRequest(URLs.URL_SPINNER,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
result = j.getJSONArray(JSON_ARRAY);
//Calling method getStudents to get the students from the JSON Array
getReviewers(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating a request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(stringRequest);
}
private void getReviewers(JSONArray j){
//Traversing through all the items in the json array
for(int i=0;i<j.length();i++){
try {
//Getting json object
JSONObject json = j.getJSONObject(i);
//Adding the name of the student to array list
reviewer.add(json.getString(TAG_NAME));
} catch (JSONException e) {
e.printStackTrace();
}
}
//Setting adapter to show the items in the spinner
spReviewer.setAdapter(new ArrayAdapter<String>(NewSuggestion.this, android.R.layout.simple_spinner_dropdown_item, reviewer));
}
//Method to get student name of a particular position
private String getName(int position){
String name="";
try {
//Getting object of given index
JSONObject json = result.getJSONObject(position);
//Fetching name from that object
name = json.getString(TAG_NAME);
} catch (JSONException e) {
e.printStackTrace();
}
//Returning the name
return name;
}
//Doing the same with this method as we did with getName()
private String getCourse(int position){
String course="";
try {
JSONObject json = result.getJSONObject(position);
course = json.getString(TAG_BADGEID);
} catch (JSONException e) {
e.printStackTrace();
}
return course;
}
#Override
public void onBackPressed() {
SharedPreferences sharedPref = getSharedPreferences("MyData", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("title", etTitle.getText().toString());
editor.apply();
super.onBackPressed();
Intent intent = new Intent(NewSuggestion.this, DashboardApp.class);
startActivity(intent);
}
How about assign a department per user login?
Then add a department_id in the manager's table
So
Table 1 Users
Id | Name | Department Id | Username | Password (encrypted) | etc...
Table 2 Department
Department Id | Department Name
Table 3 Manager
Id | Manager's Name | Department Id
Then on the Query a new where statement should be added:
$stmt = $conn->prepare("SELECT users.id, users.name, users.badgeid, users.position, users.department, users.factory,
mysuggestion.reviewer, mysuggestion.title, mysuggestion.year, mysuggestion.month, mysuggestion.suggestionwill, mysuggestion.present,
mysuggestion.details, mysuggestion.benefit, mysuggestion.photo, mysuggestion.status, mysuggestion.comment
FROM users left JOIN mysuggestion on users.badgeid = mysuggestion.badgeid
WHERE users.username = ? AND users.password = ? AND users.approver = ?
AND users.department_id = '{department_id}'
ORDER BY mysuggestion.id DESC;");
A suggestion from me (it will also depends on what's the specifications of the task though)
Store all users and login credentials in a single table and differentiate them by department (IT/Engineering/etc...) and roles (Users/Manager/etc...)
I'm currently having trouble of updating a user profile after they have login. The table i have is different but is linked together, which mean i get the Username from another table and update the profile details on another table. Here is my php and java file. Additionally, i'm not really good at android and php coding, any guidance will be much appreciated!
UpdateProfile.php
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if( !empty( $_POST ) )
{
$connect = mysqli_connect("localhost", "root", "", "users");
$Username = $_POST['Username'];
$Dri_IC = $_POST["Dri_IC"];
$Dri_Name = $_POST["Dri_Name"];
$Date_of_Birth = $_POST["Date_of_Birth"];
$Carplate = $_POST["Carplate"];
$Dri_Street_Add = $_POST["Dri_Street_Add"];
$Dri_Postal_Code = $_POST["Dri_Postal_Code"];
$Dri_City = $_POST["Dri_City"];
$Dri_State = $_POST["Dri_State"];
$Dri_Country = $_POST["Dri_Country"];
$statement = mysqli_prepare($connect, "UPDATE dri_details SET Dri_IC='$Dri_IC', Dri_Name='$Dri_Name', Date_of_Birth='$Date_of_Birth',
Carplate='$Carplate', Dri_Street_Add='$Dri_Street_Add', Dri_Postal_Code='$Dri_Postal_Code', Dri_City='$Dri_City', Dri_State='$Dri_State', Dri_Country='$Dri_Country'
INNER JOIN account_details ON account_details.Acc_ID = dri_details.Dri_ID WHERE account_details.Username='$Username'");
mysqli_stmt_bind_param($statement, "sissssssss", $Username, $Dri_IC, $Dri_Name, $Date_of_Birth, $Carplate, $Dri_Street_Add, $Dri_Postal_Code, $Dri_City, $Dri_State, $Dri_Country);
mysqli_stmt_execute($statement);
$response = array();
$response["success"] = true;
echo json_encode($response);
}
?>
ProfileUpdate.java
public class ProfileUpdate extends AppCompatActivity {
private EditText editTextDriIC, editTextDriName;
private Button buttonUpPro;
private TextView tvDisplay;
SessionManager session;
public static String global_Usernames;
public static String global_AccPass;
private ProgressDialog loading;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_profile);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// Session class instance
session = new SessionManager(getApplicationContext());
// get user data from session
HashMap<String, String> user = session.getUserDetails();
// get name
String Username = user.get(SessionManager.KEY_USERNAME);
global_Usernames = Username;
// get password
String Acc_Pass = user.get(SessionManager.KEY_PASSWORD);
global_AccPass = Acc_Pass;
final EditText etIdentitycard = (EditText) findViewById(R.id.etIdentitycard);
final EditText etName = (EditText) findViewById(R.id.etName);
final EditText etDOB = (EditText) findViewById(R.id.etDOB);
final EditText etCarplate = (EditText) findViewById(R.id.etCarplate);
final EditText etAddress = (EditText) findViewById(R.id.etAddress);
final EditText etPostal = (EditText) findViewById(R.id.etPostal);
// Get a reference to the AutoCompleteTextView in the layout
final AutoCompleteTextView etCity = (AutoCompleteTextView) findViewById(R.id.etCity);
// Get the string array
String[] cities = getResources().getStringArray(R.array.city_array);
// Create the adapter and set it to the AutoCompleteTextView
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, cities);
etCity.setAdapter(adapter);
// Get a reference to the AutoCompleteTextView in the layout
final AutoCompleteTextView etState = (AutoCompleteTextView) findViewById(R.id.etState);
// Get the string array
String[] states = getResources().getStringArray(R.array.state_array);
// Create the adapter and set it to the AutoCompleteTextView
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, states);
etState.setAdapter(adapter);
// Get a reference to the AutoCompleteTextView in the layout
final AutoCompleteTextView etCountry = (AutoCompleteTextView) findViewById(R.id.etCountry);
// Get the string array
String[] country = getResources().getStringArray(R.array.countries_array);
// Create the adapter and set it to the AutoCompleteTextView
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, country);
etCountry.setAdapter(adapter);
final Button buttonUpPro = (Button) findViewById(R.id.bUpdate);
final Calendar myCalendar = Calendar.getInstance();
final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
// TODO Auto-generated method stub
myCalendar.set(Calendar.YEAR, year);
myCalendar.set(Calendar.MONTH, monthOfYear);
myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateLabel();
}
private void updateLabel() {
//String myFormat = "YYYY/MM/DD"; //In which you need put here
//DateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
String myFormat = "yyyy/MM/dd"; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
//DateFormat sdf = DateFormat.getDateInstance(DateFormat.LONG, Locale.UK);
etDOB.setText(sdf.format(myCalendar.getTime()));
}
};
etDOB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new DatePickerDialog(ProfileUpdate.this, date, myCalendar
.get(Calendar.YEAR), myCalendar.get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH)).show();
}
});
buttonUpPro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String Dri_IC = etIdentitycard.getText().toString().trim();
final String Dri_Name = etName.getText().toString().trim();
final String Date_of_Birth = etDOB.getText().toString();
final String Carplate = etCarplate.getText().toString().trim();
final String Dri_Street_Add = etAddress.getText().toString().trim();
final String Dri_Postal_Code = etPostal.getText().toString().trim();
final String Dri_City = etCity.getText().toString().trim();
final String Dri_State = etState.getText().toString().trim();
final String Dri_Country = etCountry.getText().toString().trim();
if (etIdentitycard.getText().toString().matches("") || etName.getText().toString().matches("") || etDOB.getText().toString().matches("") || etAddress.getText().toString().matches("")
|| etPostal.getText().toString().matches("") || etCity.getText().toString().matches("") || etState.getText().toString().matches("") || etCountry.getText().toString().matches("")) {
if (TextUtils.isEmpty(Dri_IC)) {
etIdentitycard.setError("You are required to enter your Identification Card Number");
}
if (TextUtils.isEmpty(Dri_Name)) {
etName.setError("You are required to enter your Full Name");
}
if (TextUtils.isEmpty(Date_of_Birth)) {
etDOB.setError("You are required to enter your Date of Birth");
}
if (TextUtils.isEmpty(Dri_Street_Add)) {
etAddress.setError("You are required to enter your House Address");
}
if (TextUtils.isEmpty(Dri_Postal_Code)) {
etPostal.setError("You are required to enter your Postal Code");
}
if (TextUtils.isEmpty(Dri_City)) {
etCity.setError("You are required to enter City name");
}
if (TextUtils.isEmpty(Dri_State)) {
etState.setError("You are required to enter State name");
}
if (TextUtils.isEmpty(Dri_Country)) {
etCountry.setError("You are required to enter Country name");
}
} else {
Response.Listener<String> responeListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonRespone = new JSONObject(response);
boolean success = jsonRespone.getBoolean("success");
/*if (success){
Intent intent = new Intent(RegisterActivity2.this, LoginActivity.class);
RegisterActivity2.this.startActivity(intent);
}*/
if (!success){
AlertDialog.Builder builder = new AlertDialog.Builder(ProfileUpdate.this);
builder.setMessage("Retry")
.setNegativeButton("Retry", null)
.create()
.show();
} else {
Toast.makeText(ProfileUpdate.this, getString(R.string.profile_update_success), Toast.LENGTH_LONG).show();
//Intent intent = new Intent(RegisterActivity2.this, LoginActivity.class);
//RegisterActivity2.this.startActivity(intent);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
ProfileUpdateRequest profileUpdateRequest = new ProfileUpdateRequest(Dri_IC, Dri_Name, Date_of_Birth, Carplate, Dri_Street_Add, Dri_Postal_Code, Dri_City, Dri_State, Dri_Country, responeListener);
RequestQueue queue = Volley.newRequestQueue(ProfileUpdate.this);
queue.add(profileUpdateRequest);
}
}
});
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
ProfileUpdateRequest.java
public class ProfileUpdateRequest extends StringRequest {
private static final String PROFILEUPDATE_REQUEST = "http://192.168.1.5/UpdateProfile.php";
private Map<String, String> params;
public ProfileUpdateRequest(String Dri_IC, String Dri_Name, String Date_of_Birth, String Carplate, String Dri_Street_Add, String Dri_Postal_Code, String Dri_City, String Dri_State, String Dri_Country, Response.Listener<String> listener){
super (Method.POST, PROFILEUPDATE_REQUEST, listener, null);
Log.i("Getting url info",""+PROFILEUPDATE_REQUEST + " " + Dri_IC + " " + Dri_Name + " " + Date_of_Birth);
params = new HashMap<>();
params.put("Dri_IC", Dri_IC + "");
params.put("Dri_Name", Dri_Name);
params.put("Date_of_Birth", Date_of_Birth);
params.put("Carplate", Carplate);
params.put("Dri_Street_Add", Dri_Street_Add);
params.put("Dri_Postal_Code", Dri_Postal_Code);
params.put("Dri_City", Dri_City);
params.put("Dri_State", Dri_State);
params.put("Dri_Country", Dri_Country);
params.put("Username", MainActivity.global_Username);
}
#Override
public Map<String, String> getParams() {
return params;
}
}
I'm not sure what went wrong, after i click update on my android, it did not show success or error, and the database did not update as well. Any help will be much appreciated!
I want to sync the local database file in the Android app with the users' DropBox or SkyDrive account. Anything would do.
I am not able to get a running code.
Please help.
Here is the code I got from the official DropBox site, but it says error at
"final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER;" as NoClassDefFoundError
public class DBRoulette extends Activity {
private static final String TAG = "DBRoulette";
///////////////////////////////////////////////////////////////////////////
// Your app-specific settings. //
///////////////////////////////////////////////////////////////////////////
// Replace this with your app key and secret assigned by Dropbox.
// Note that this is a really insecure way to do this, and you shouldn't
// ship code which contains your key & secret in such an obvious way.
// Obfuscation is good.
final static private String APP_KEY = "5gqlcpeirbe9kju";
final static private String APP_SECRET = "zs9bi3nwqf4arn2";
// If you'd like to change the access type to the full Dropbox instead of
// an app folder, change this value.
final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER;
///////////////////////////////////////////////////////////////////////////
// End app-specific settings. //
///////////////////////////////////////////////////////////////////////////
// You don't need to change these, leave them alone.
final static private String ACCOUNT_PREFS_NAME = "prefs";
final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";
DropboxAPI<AndroidAuthSession> mApi;
private boolean mLoggedIn;
// Android widgets
private Button mSubmit;
private LinearLayout mDisplay;
private Button mPhoto;
private Button mRoulette;
private ImageView mImage;
private final String PHOTO_DIR = "/Photos/";
final static private int NEW_PICTURE = 1;
private String mCameraFileName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mCameraFileName = savedInstanceState.getString("mCameraFileName");
}
// We create a new AuthSession so that we can use the Dropbox API.
AndroidAuthSession session = buildSession();
mApi = new DropboxAPI<AndroidAuthSession>(session);
// Basic Android widgets
setContentView(R.layout.main);
checkAppKeySetup();
mSubmit = (Button)findViewById(R.id.auth_button);
mSubmit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// This logs you out if you're logged in, or vice versa
if (mLoggedIn) {
logOut();
} else {
// Start the remote authentication
mApi.getSession().startAuthentication(DBRoulette.this);
}
}
});
mDisplay = (LinearLayout)findViewById(R.id.logged_in_display);
// This is where a photo is displayed
mImage = (ImageView)findViewById(R.id.image_view);
// This is the button to take a photo
mPhoto = (Button)findViewById(R.id.photo_button);
mPhoto.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
// Picture from camera
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
// This is not the right way to do this, but for some reason, having
// it store it in
// MediaStore.Images.Media.EXTERNAL_CONTENT_URI isn't working right.
Date date = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd-kk-mm-ss");
String newPicFile = df.format(date) + ".jpg";
String outPath = "/sdcard/" + newPicFile;
File outFile = new File(outPath);
mCameraFileName = outFile.toString();
Uri outuri = Uri.fromFile(outFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outuri);
Log.i(TAG, "Importing New Picture: " + mCameraFileName);
try {
startActivityForResult(intent, NEW_PICTURE);
} catch (ActivityNotFoundException e) {
showToast("There doesn't seem to be a camera.");
}
}
});
// This is the button to take a photo
mRoulette = (Button)findViewById(R.id.roulette_button);
mRoulette.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
DownloadRandomPicture download = new DownloadRandomPicture(DBRoulette.this, mApi, PHOTO_DIR, mImage);
download.execute();
}
});
// Display the proper UI state if logged in or not
setLoggedIn(mApi.getSession().isLinked());
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("mCameraFileName", mCameraFileName);
super.onSaveInstanceState(outState);
}
#Override
protected void onResume() {
super.onResume();
AndroidAuthSession session = mApi.getSession();
// The next part must be inserted in the onResume() method of the
// activity from which session.startAuthentication() was called, so
// that Dropbox authentication completes properly.
if (session.authenticationSuccessful()) {
try {
// Mandatory call to complete the auth
session.finishAuthentication();
// Store it locally in our app for later use
TokenPair tokens = session.getAccessTokenPair();
storeKeys(tokens.key, tokens.secret);
setLoggedIn(true);
} catch (IllegalStateException e) {
showToast("Couldn't authenticate with Dropbox:" + e.getLocalizedMessage());
Log.i(TAG, "Error authenticating", e);
}
}
}
// This is what gets called on finishing a media piece to import
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == NEW_PICTURE) {
// return from file upload
if (resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (data != null) {
uri = data.getData();
}
if (uri == null && mCameraFileName != null) {
uri = Uri.fromFile(new File(mCameraFileName));
}
File file = new File(mCameraFileName);
if (uri != null) {
UploadPicture upload = new UploadPicture(this, mApi, PHOTO_DIR, file);
upload.execute();
}
} else {
Log.w(TAG, "Unknown Activity Result from mediaImport: "
+ resultCode);
}
}
}
private void logOut() {
// Remove credentials from the session
mApi.getSession().unlink();
// Clear our stored keys
clearKeys();
// Change UI state to display logged out version
setLoggedIn(false);
}
/**
* Convenience function to change UI state based on being logged in
*/
private void setLoggedIn(boolean loggedIn) {
mLoggedIn = loggedIn;
if (loggedIn) {
mSubmit.setText("Unlink from Dropbox");
mDisplay.setVisibility(View.VISIBLE);
} else {
mSubmit.setText("Link with Dropbox");
mDisplay.setVisibility(View.GONE);
mImage.setImageDrawable(null);
}
}
private void checkAppKeySetup() {
// Check to make sure that we have a valid app key
if (APP_KEY.startsWith("CHANGE") ||
APP_SECRET.startsWith("CHANGE")) {
showToast("You must apply for an app key and secret from developers.dropbox.com, and add them to the DBRoulette ap before trying it.");
finish();
return;
}
// Check if the app has set up its manifest properly.
Intent testIntent = new Intent(Intent.ACTION_VIEW);
String scheme = "db-" + APP_KEY;
String uri = scheme + "://" + AuthActivity.AUTH_VERSION + "/test";
testIntent.setData(Uri.parse(uri));
PackageManager pm = getPackageManager();
if (0 == pm.queryIntentActivities(testIntent, 0).size()) {
showToast("URL scheme in your app's " +
"manifest is not set up correctly. You should have a " +
"com.dropbox.client2.android.AuthActivity with the " +
"scheme: " + scheme);
finish();
}
}
private void showToast(String msg) {
Toast error = Toast.makeText(this, msg, Toast.LENGTH_LONG);
error.show();
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a local
* store, rather than storing user name & password, and re-authenticating each
* time (which is not to be done, ever).
*
* #return Array of [access_key, access_secret], or null if none stored
*/
private String[] getKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(ACCESS_KEY_NAME, null);
String secret = prefs.getString(ACCESS_SECRET_NAME, null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a local
* store, rather than storing user name & password, and re-authenticating each
* time (which is not to be done, ever).
*/
private void storeKeys(String key, String secret) {
// Save the access key for later
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, key);
edit.putString(ACCESS_SECRET_NAME, secret);
edit.commit();
}
private void clearKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.clear();
edit.commit();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE);
}
return session;
}
}
Do you add the dropbox-android-sdk.jar in your buildPath and in a correct way ?
The DropboxAPI JAR file should be in the libs/ folder, not lib/.
Try this and tell me if it works now ...
PS: I'm working with DropboxAPI for android, and their code works very well for me and their documentation is really good to do your own application.