NFC tag and php - java

I am new to NFC tags and am interested on how it work. I have bought a NFC tag and am able to write studentid to the tag. Now my problem is how to pass the student id to a php web service and check if this student has paid his/her meals before thy can proceed to the cafeteria when thy scan their student cards through my application.
Kindly anyone assist me on how i can do this. below is what i have done.
//reading the tag
private String readText(NdefRecord record) throws UnsupportedEncodingException {
byte[] payload = record.getPayload();
// Get the Text Encoding
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
// Get the Language Code
int languageCodeLength = payload[0] & 0063;
// Get the Text
return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
//show the student id in a textedit
mTextView.setText(result);
//pass variable to the server and get contents. I want to pass the student id to the method
getstudentinfo(result);
}
}
void getstudentinfo(String studID) {
//get connection to the server using http request
httpclient=new DefaultHttpClient();
httppost= new HttpPost("http://myip/getStudentBl.php?studID="+ studID);
try{
response = getThreadSafeClient().execute(httppost);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
final String response = httpclient.execute(httppost, responseHandler);
//checking the response and info the user
runOnUiThread(new Runnable() {
public void run() {
dialog.dismiss();
}
});
//if the user is found
if(response.equalsIgnoreCase("Student Found")){
runOnUiThread(new Runnable() {
public void run() {
//Toast.makeText(MainActivity.this,"Saved Successfull", Toast.LENGTH_SHORT).show();
stdBalance.setText("Student Balance " + response);
}
});
//show the dashboard screen
startActivity(new Intent(MainActivity.this, MainActivity.class));
}else if(response.equalsIgnoreCase("No Record")){
//show error results
showAlert();
}
//end try catch
}catch(Exception e){
dialog.dismiss();
System.out.println("Exception : " + e.getMessage());
}
}

From my understanding, with android readers at a minimum, if the tag holds an URL, it will automatically load the browser and go to the URL (no asking if you want to open the app nor if you want to go to the URL). You should be able to just put the student_id as a query string and use it in a page.

Looks here to have an exemple of an NDEF implementation : Github repo
In the main activity you will have to modify the
#Override
public void ndefDataRead(String ndefData) {
demoTextView.setText(ndefData);
}
to call your getstudentinfo(String studID) methods and it might work

Related

Processing can't find a callback function from a save dialog

For whatever reason, Processing does not seem to find the callback function after I select a file using selectOutput(). Here is the part of my code where I am trying to save a file:
void saveProjectDialog() { // Shows a save file dialog
JSONObject header = new JSONObject();
header.setString("name", proj_name);
selectOutput(getLang("SaveDialog"), "saveProject");
}
void saveProject(File selection) { // Save file dialog callback
if (selection == null) {
println("Save dialog was closed, canceled save.");
} else {
println("Saving to " + selection.getAbsolutePath());
saveJSONArray(project, selection.getAbsolutePath());
println("Construction saved!");
}
}
When I select the path, this is printed out to the console:
saveProject() could not be found
What is wrong with my code?
Using this test sketch worked:
JSONArray project = new JSONArray();
String proj_name = "test";
void saveProjectDialog() { // Shows a save file dialog
JSONObject header = new JSONObject();
header.setString("name", proj_name);
selectOutput(getLang("SaveDialog"), "saveProject");
}
void saveProject(File selection) { // Save file dialog callback
if (selection == null) {
println("Save dialog was closed, canceled save.");
} else {
println("Saving to " + selection.getAbsolutePath());
saveJSONArray(project, selection.getAbsolutePath());
println("Construction saved!");
}
}
void setup(){
saveProjectDialog();
}
String getLang(String s){
return s;
}
Double check the values proj_name and getLang() result.

Android: Making application wait before executing task (AsyncTask usage)

Hello I will define my problem more clearly here. I am working on my first Android App that reads simply an NFC Tag and compares it to an SQLite database stored on the device.
In short, if this is successful (Tag is ok, code exists in the database) the screen changes to reflect it. If it fails (tag not ok, tag code does not exist in the database) it again changes to show this. What I am trying to accomplish is to make the screen return to its initial state after say 2 seconds when the either OK or error views are displayed.
I have tried several options but I was unable to do so hence why I am asking. Thread.sleep() does not seem to do it. I tried executing it after verifying if the Asynctask's status is finished but not to much luck either. Code below:
// Internal Class used to define NdefReaderTask
private class NdefReaderTask extends AsyncTask<Tag, Void, String> {
#Override
protected String doInBackground(Tag... params) {
Tag tag = params[0];
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
return null;
}
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
NdefRecord[] records = ndefMessage.getRecords();
for (NdefRecord ndefRecord : records) {
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN
&& Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
try {
return readText(ndefRecord);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported encoding", e);
}
}
}
return null;
}
private String readText(NdefRecord record)
throws UnsupportedEncodingException {
byte[] payload = record.getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
int languageCodeLength = payload[0] & 0063;
return new String(payload, languageCodeLength + 1, payload.length
- languageCodeLength - 1, textEncoding);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
// Do SOMETHING HERE
// find the tag which has the same code as result
EventTag currentTag = dataSource.getEventTag(result);
if (currentTag != null) {
Toast.makeText(
getApplicationContext(),
"Welcome " + currentTag.getFullName()
+ " you are using tag: "
+ currentTag.getNfcCode(), Toast.LENGTH_LONG)
.show();
((TextView) findViewById(R.id.fullscreen_content))
.setBackgroundResource(R.drawable.bggreen);
((TextView) findViewById(R.id.fullscreen_content))
.setText(getResources().getString(R.string.txt_tag_ok)
+ " " + currentTag.getFullName());
} else {
Toast.makeText(getApplicationContext(),
"Tag with code: " + result + " not found in database",
Toast.LENGTH_LONG).show();
((TextView) findViewById(R.id.fullscreen_content))
.setBackgroundResource(R.drawable.bgred);
((TextView) findViewById(R.id.fullscreen_content))
.setText(getResources().getString(
R.string.txt_tag_notok));
}
if (this.getStatus() == Status.FINISHED) {
try {
Thread.sleep(miliseconds);
((TextView) findViewById(R.id.fullscreen_content))
.setBackgroundResource(R.drawable.bgblue);
((TextView) findViewById(R.id.fullscreen_content))
.setText(getResources().getString(
R.string.dummy_content));
} catch (Exception exp) {
Log.d("Thread Error", "Unable to sleep thread for "
+ miliseconds, exp);
}
}
}
}
}
This is my AsyncTask class, i will post more code if needed but this is what i've been doing so far.
I also tried the code below in onPostExecute as well but the screen did not even change anymore to either error or success.
try {
this.get(miliseconds, TimeUnit.MILLISECONDS);
((TextView) findViewById(R.id.fullscreen_content)).setBackgroundResource(
R.drawable.bgblue);
((TextView) findViewById(R.id.fullscreen_content)).setText(
getResources().getString(R.string.dummy_content));
}
catch(Exception exp) {
Log.d("Thread Error", "Unable to sleep thread for " + miliseconds, exp);
}
When you have to do tasks based on time in Android you should use a Handler.
In your case use Handler.postDelayed(Runnable, long). Create and execute the handler in your onPostExecute.
The problem with your approach
By using Thread.sleep you stopped the execution of the current thread, which in onPostExecute is the UI Thread hence you couldn't see it getting updated in either success or failure.

Thread contention in Asynctask

I'm having a thread contention issue when my program gets to executing an asynctask whose current purpose is to connect to an ftp server and based on a successful connection then make a get HTTP parsing request in order to access JSON data I need to write into a local SQLite database.
I'm slightly new in understanding thread contention but having read around particulalry this article I suspect it is a deadlock.
Below is my debug window which is called when I run my app. I'm doing so on a device and not an emulator:
Below is the asynctask code:
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllProducts extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
//pDialog = new ProgressDialog(AllProductsActivity.this);
//pDialog.setMessage("Loading products. Please wait...");
Log.i("LoadAllProducts", "LoadAllProducts - Loading products. Please wait...");
//pDialog.setIndeterminate(false);
//pDialog.setCancelable(false);
//pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
Log.i("LoadAllProducts", "URL: " + url_all_products);
ftpConnectLoginAndUpload = new FTPConnectLoginAndUpload();
if(ftpConnectLoginAndUpload.execute()) {
// Check your log cat for JSON response
Log.d("LoadAllProducts ", "About to execute JSONObject json = jParser.makeHttpRequest(url_all_products, \"GET\", params);");
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);
// Check your log cat for JSON response
Log.d("LoadAllProducts ", json.toString());
/*try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS); // products is a variable holding the value from the 2nd key-value pairing.
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String price = c.getString("price");
String created_at = c.getString("created_at");
String updated_at = c.getString("updated_at");
Log.d("LoadAllProducts ", "JSON item var i.e. id:" + id);
Log.d("LoadAllProducts ", "JSON item var i.e. name:" + name);
Log.d("LoadAllProducts ", "JSON item var i.e. price:" + price);
Log.d("LoadAllProducts ", "JSON item var i.e. created_at:" + created_at);
Log.d("LoadAllProducts ", "JSON item var i.e. updated_at:" + updated_at);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_PID, id);
map.put(TAG_NAME, name);
// adding HashList to ArrayList
productsList.add(map);
}
} else {
// no products found
// Launch Add New product Activity
Intent i = new Intent(getApplicationContext(),
NewProductActivity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}*/
} else {
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
Log.i("LoadAllProducts", "LoadAllProducts - dismiss the dialog after getting all products");
// updating UI from Background Thread
/*runOnUiThread(new Runnable() {
public void run() {
//Updating parsed JSON data into ListView
ListAdapter adapter = new SimpleAdapter(
AllProductsActivity.this, productsList,
R.layout.list_item, new String[] { TAG_PID,
TAG_NAME},
new int[] { R.id.pid, R.id.name });
// updating listview
setListAdapter(adapter);
}
});*/
}
}
Below is the FTP log in code:
//!< FTP Connect, Login And Upload
public class FTPConnectLoginAndUpload {
//!<
private void showServerReply(FTPClient ftpClient) {
String[] replies = ftpClient.getReplyStrings();
if (replies != null && replies.length > 0) {
for (String aReply : replies) {
System.out.println("---> showServerReply(FTPClient ftpClient) - SERVER: " + aReply);
}
}
}
//!<
public boolean execute() {
// Boston's FTP login credentials
String server = "XX.XXX.XXX.XX";
int port = 21;
String user = "XXXXXXXX_XXXXXX";
String pass = "XXXXXXXX";
// Time out period after connection attempt
int timeOut = 5000;
boolean ftpResult;
// FTPClient encapsulates all the functionality necessary to store and retrieve files from an FTP server
// This class takes care of all low level details of interacting with an FTP server and provides a convenient higher level interface
FTPClient ftpClient = new FTPClient();
// Execute FTP process
try {
// Set connection timeout in milliseconds
ftpClient.setConnectTimeout(timeOut);
// Sets the timeout in milliseconds to use when reading from the data connection.
ftpClient.setDataTimeout(timeOut);
// Connect using provided server and port numb
ftpClient.connect(server, port);
System.out.println("\n---> ftpClient.connect(server, port) has been executed.\n---> Server used was "
+ server + " and port number used was: " + port);
System.out.println("\n---> ftpClient.getReplyString() returns: " + ftpClient.getReplyString());
// Returns server reply
System.out.println("\n---> Server reply is as follows:");
showServerReply(ftpClient);
System.out.println("---> End of server reply");
// Get server reply code
int replyCode = ftpClient.getReplyCode();
System.out.println("\n---> ftpClient replyCode is: " + replyCode);
// Determine if a reply code is a positive completion response. All codes beginning with a 2 are positive completion responses.
// The FTP server will send a positive completion response on the final successful completion of a command.
if (!FTPReply.isPositiveCompletion(replyCode)) {
System.out.println("\n---> Operation failed. Server reply code: " + replyCode);
ftpResult = false;
return ftpResult;
} else {
System.out.println("\n---> Operation successful. Server reply code: " + replyCode);
// Attempt login
boolean success = ftpClient.login(user, pass);
System.out.println("\n---> ftpClient.login(user, pass); has been called.");
// Determine log in success
if (!success) {
System.out.println("\n ---> Unable to login to the server");
ftpResult = false;
return ftpResult;
} else {
System.out.println("\n---> Successfully logged into server");
ftpResult = true;
}
//
ftpClient.enterLocalPassiveMode();
// Show server reply after logging in
System.out.println("\n---> Server response after logging in is as follows:");
showServerReply(ftpClient);
System.out.println("---> End of server response after logging");
return ftpResult;
}
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
ftpResult = false;
return ftpResult;
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
ftpResult = false;
return ftpResult;
}
} catch (IOException ex) {
ex.printStackTrace();
ftpResult = false;
return ftpResult;
}
}
}
}

Two identical strings return false while one string received from a PHP response

I got a strange problem, when I receive a response from a PHP page, store it in a string variable in Java and try to compare it with identical string that I typed, it return false from some reason.
I am trying to make a login class that validate simply if the user details are stored on MySQL.
This if("User Found".equals(response)) statement returns false even that the response contain equal contents.
Here is the Java and PHP codes:
void login(){
try{
httpclient=new DefaultHttpClient();
httppost= new HttpPost("http://192.200.10.100:8080/login.php"); // make sure the url is correct.
//add your data
nameValuePairs = new ArrayList<NameValuePair>(2);
// Always use the same variable name for posting i.e the android side variable name and php side variable name should be similar,
nameValuePairs.add(new BasicNameValuePair("Name",loginInputs[0])); // $Edittext_value = $_POST['Edittext_value'];
nameValuePairs.add(new BasicNameValuePair("Password",loginInputs[1]));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
//Execute HTTP Post Request
httpresponse=httpclient.execute(httppost);
// edited by James from coderzheaven.. from here....
ResponseHandler<String> responseHandler = new BasicResponseHandler();
response = httpclient.execute(httppost, responseHandler);
System.out.println("Response : " + response);
runOnUiThread(new Runnable() {
public void run() {
tv.setText("Response from PHP : " + response);
dialog.dismiss();
}
});
if("User Found".equals(response)){
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(login.this,"Login Success", Toast.LENGTH_SHORT).show();
}
});
startActivity(new Intent(login.this, MainActivity.class));
}else{
showAlert();
}
}catch(Exception e){
dialog.dismiss();
System.out.println("Exception : " + e.getMessage());
}
}
public void showAlert(){
login.this.runOnUiThread(new Runnable() {
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(login.this);
builder.setTitle("Login Error.");
builder.setMessage("User not Found.")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
The PHP code:
<?php
if (isset($_POST['Name']) && isset($_POST['Password'])) {
$name = $_POST['Name'];
$Password = $_POST['Password'];
// include db connect class
require_once __DIR__ . '/connect.php';
// connecting to db
$db = new DB_CONNECT();
$result = mysql_query("SELECT * FROM `userinfo` WHERE Name='$name' AND Password='$Password'");
if (mysql_num_rows($result)>0)
{
echo "User Found";
}
else {
echo "Not Found";
}
}
?>
I read a lot of suggestions and tried to change many things but couldn't succeed. Anyway I think the problem caused by unmatched string encoded type, but have no idea how to fix it.
Have you tried with compareTo()?
Edit:
It would be a better solution if the php code returned an int. Ex: if user is found, return 1 else return 0.
Then in login() function for each digit retured display the message. It is easier comparing integers than strings.
This code snippet worked for me:
String TempString = new String(response.substring(2,12).toString());
if("User Found".equals(TempString)) {
// other actions here
}

make multiple http post in android

hello i want to ask some question
i want to make application that connected with a web services that i made
my app has 2 uniqueID called app_id and token, app_id generate only once when the app first start and token generated by web service
every request, i must check whenever the token already expired or not, if the token already expired it will call separate web service and generate new token
the problem is the app must access 2 different web service: to request new token and to get another desired data
i use asynctask, but the response from web service for request token always same every request and i have no idea why
protected Boolean doInBackground(Void... params) {
int status = 0;
int token_expired=0;
String token_val = token.getToken(getBaseContext());
for(int i=0;i<5 && status==0;i++) {
try {
Thread.sleep(1000);
//function to check if token already expired or not and request new token using http post
token_expired = token.checkToken(getBaseContext());
System.out.println("token expired: " +token_expired);
if (token_expired==1 || token_expired==2) {
//function to call another web service and get a data from it
status = rclient.Execute("POST");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (status==0) {
return false;
}else{
return true;
}
}
thanks before!
oh yeah this is a function of check token from class token handler
public Integer checkToken(Context context) {
int status = 0; //0 = failed to request token , 1 = successfully request new token, 2 = token has not expired yet
String token_id = getToken(context);
System.out.println("token_id: " +token_id);
//if (token_id!=null) {
Long time = getTime(context);
Long curr_time = System.currentTimeMillis()/1000;
System.out.println("time before: " +time);
System.out.println("time current: " +curr_time);
Long interval = curr_time - time;
System.out.println("interval: " +interval);
if (interval>10) {
status = TokenGenerator(context);
}else {
status = 2;
}
//}
return status;
}
}
and this is a function to request new token from the same class
public synchronized Integer TokenGenerator(Context context) {
int status = 0;
SharedPreferences sharedPrefs = context.getSharedPreferences(TOKEN_STORAGE, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
try {
rclient.AddJSON("app_id", uniqueID);
rclient.CompileJSON();
} catch (JSONException e1) {
e1.printStackTrace();
}
try {
status = rclient.Execute("POST");
} catch (Exception e) {
e.printStackTrace();
}
if (status==1) {
String response = rclient.getResponse();
String token = null;
System.out.println("uuid_response: " +response);
try {
JSONObject json = new JSONObject(response);
token = json.getString("result");
} catch (JSONException e) {
e.printStackTrace();
}
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
System.out.println("time: " +ts);
Editor editor = sharedPrefs.edit();
editor.putString(TIMESTAMP, ts);
editor.putString(TOKEN_ID, token);
editor.commit();
}
return status;
}
so basically the rest client class called two times, first at class token handler to request a new token, and second from the activity itself
As per the code posted by you, I think rclient.Execute("POST") is used to get the data. But the below piece of code
if (token_expired==1 || token_expired==2) {
//function to call another web service and get a data from it
status = rclient.Execute("POST");
}
says that if the token is still alive you are trying to get the new token again.
I think the line status = rclient.Execute("POST"); should be replaced with the code to fetch the data from the server.
problem solved after i put constructor of rest client class in function

Categories