Async Task to Save data in SQL server in Android - java

I am trying to save edit box data in SQL server by using android app. I am trying to use async task to save data.I already developed web service and host in the IIS which is running fine. So i Need now code in android to save data.
This is my Aysnc Task
class SaveScan extends AsyncTask<String,Void, String>{
String status = null;
protected void onPreExecute(){
}
protected String doInBackground(String... connUrl){
HttpURLConnection conn = null;
BufferedReader reader;
try{
final URL url = new URL(connUrl[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setChunkedStreamingMode(0);
conn.addRequestProperty("Content-Type","application/json: charset=utf-8");
conn.setRequestMethod("POST");;
JSONObject jsonObject = new JSONObject();
jsonObject.put("scans",Scan1);
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
out.write(jsonObject.toString().getBytes());
out.close();
int result = conn.getResponseCode();
if (result == 200) {
InputStream in = new BufferedInputStream(conn.getInputStream());
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while((line =reader.readLine()) != null){
status = line;
}
}
}catch(Exception ex){
}
return status;
}
protected void onPostExecute(String result){
super.onPostExecute(result);
if(result != null){
Toast.makeText(MainActivity.this,"Scan Saved ",Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this,"Not Saved",Toast.LENGTH_LONG).show();
}
}
}
This is Mine Button Call
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{
Manifest.permission.CAMERA},
100);
Intent intent = new Intent(MainActivity.this, Scan.class);
startActivity(intent);
}
});

private void onSaveClicked() {
new SaveScan(url).execute();
}
private class SaveScan extends AsyncTask<String,Void, String>{
String status = null;
protected String doInBackground(String... connUrl){
try {
// This is getting the url from the string we passed in
URL url = new URL(connUrl[0]);
// Create the urlConnection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestMethod("POST");
// OPTIONAL - Sets an authorization header
urlConnection.setRequestProperty("Authorization", "someAuthString");
JSONObject jsonObject = new JSONObject();
jsonObject.put("scans","someString");
// Send the post body
OutputStreamWriter writer = new OutputStreamWriter(urlConnection.getOutputStream());
writer.write(jsonObject.toString());
writer.flush();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
String response = convertInputStreamToString(inputStream);
status=response ;
// From here you can convert the string to JSON with whatever JSON parser you like to use
} else {
// Status code is not 200
// Do something to handle the error
status=null;
}
} catch (Exception e) {
Log.d("SaveScan", e.getMessage());
}
return status;
}
private String convertInputStreamToString(InputStream inputStream) {
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line;
try {
while((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
protected void onPostExecute(String result){
super.onPostExecute(result);
if(result != null){
Toast.makeText(MainActivity.this,"Scan Saved ",Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this,"Not Saved",Toast.LENGTH_LONG).show();
}
}
}

You can choose between different storage frameworks such as Room, SQLite or Preferences depending on your data. Room and SQLite are relational databases, where SQLite requires developers to create tables and map relationships, Room takes care of those with the help of annotation processing. Preferences are android's storage framework where you can store minimal amount of data for example settings for your app, map app's flow and vital data such as user information. In the end, it all depends on the time you can spend and the data that you are trying to save. I suggest you go through all these frameworks and identify what's best for you.

Related

How can I solve this IOException?

I am trying to get a user token from a url but I keep getting an IOException:
(W/System.err: java.io.FileNotFoundException: url)
I have tried to run the API from postman, and that seems to work. The request method is GET:
private class userlogin extends AsyncTask<String, String, String> {
#Override
public void onPreExecute() {
progressDialog = new ProgressDialog(userLogin.this);
progressDialog.setMessage("please wait.........");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.setTitle("Logging in");
progressDialog.show();
}
#Override
public String doInBackground(String... para) {
try {
URL url = new URL(webconfigs.LOGIN_URL);
Map<String, String> params = new LinkedHashMap<>();
params.put("grant_type", "password");
params.put("username", para[0]);
params.put("password", para[1]);
utility.updateSharedPreference(userLogin.this, "Username", para[0]);
utility.updateSharedPreference(getApplicationContext(), "Password", para[1]);
//just to check if it is sored in the shared prefrence
utility.fetchFromSharedPreference(getApplicationContext(), "Username");
utility.fetchFromSharedPreference(getApplicationContext(), "Password");
Log.e(">>Username>>", para[0]);
Log.e(">>Password>>", para[1]);
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, String> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
String urlparameters = postData.toString();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(3000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", webconfigs.CONTENT_TYPE);
conn.setDoOutput(true);
//connect the url
conn.connect();
//conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlparameters);
writer.flush();
//create our buffered reader to read from the input stream reader
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder st = new StringBuilder();
//checking the status of the response code
Integer resposeCode = conn.getResponseCode();
String responsecode1 = resposeCode.toString();
Log.e("the respose code is :", responsecode1);
String line;
String result= "";
// consume the response and read it line by line as
while ((line = reader.readLine()) != null) {
st.append(line);
}
reader.close();
writer.close();
result = st.toString();
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.e(">>>>LOGINSERVERRESPONSE", ">>>>>" + result);
progressDialog.dismiss();
try {
JSONObject results = new JSONObject(result);
String token = results.getString("access_token");
if (token != null) {
String accessToken = results.getString("access_token");
String tokenType = results.getString("token_type");
String dateIssued = results.getString(".issued");
String expiryDate = results.getString(".expires_in");
}
} catch (Exception e) {
}
startActivity(new Intent(getApplicationContext(), drawerLayout.class));
}
}
the problem with using the asynchtask is that when the credentials that are used are wrong the problem will exist ,incase that happens,use a different user from the database

Is there an Alternative for AsyncTask using HttpUrlConnection

Using AsyncTask freezes my whole app. i have an icon that rotates while the Http action is happening in the background. but the app just freezes till it finishes that action. Is there an alternative?
The below class sends the JSON to the server, the server has multiple endpoints and stuff like that. now when calling class calls the execute() method, the app freezes until the task is complete.
public class Connector extends AsyncTask<String, Void, Void> {
private String ip = "http://192.168.1.127";
private String port = "5000";
private URL Url;
private JSONObject jsonObject;
private String method = "";
private StringBuilder output = new StringBuilder();
Connector(String url, JSONObject jsonObject, String method)
{
try {
this.method = method;
this.Url = new URL(ip+":"+port+url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
this.jsonObject = jsonObject;
//Connect to URL
}
#Override
protected Void doInBackground(String... strings) {
try {
HttpURLConnection httpURLConnection = (HttpURLConnection) Url.openConnection();
Log.i("Data", "Data sent => " + jsonObject.toString());
try {
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod(method);
httpURLConnection.setRequestProperty("content-type", "application/json");
httpURLConnection.connect();
DataOutputStream outputStream = new DataOutputStream(httpURLConnection.getOutputStream());
if(jsonObject != null)
{
outputStream.writeBytes(jsonObject.toString());
outputStream.flush();
outputStream.close();
}
InputStreamReader inputStreamReader = new InputStreamReader((InputStream) httpURLConnection.getContent(), Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while(line != null)
{
output.append(line);
line = reader.readLine();
}
}finally {
httpURLConnection.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
String getMessge() {
Log.i("Data", "Data received <= " + output.toString());
return output.toString();
}
}
Please use Retrofit library.
You can find samples to use Retrofit easily.
https://www.journaldev.com/13639/retrofit-android-example-tutorial
This is one of them.
Hope it to help you. Thanks.

Getting Response code as 400 from geo location api

I am trying to use geo location api to get lattitude and longitude of the location. So for this I created a project on developer console and created an api key. I used this api key with this api https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY
So this when I executed the request in postman it works well.
But when I tried to execute same request in an app its giving response as response code 400.
Response code 400 as per developer guide
https://developers.google.com/maps/documentation/geolocation/intro#errors
shows it comes when the api key is wrong. But how the key works in postman and not in the app?
Here is the code for server request:
public JSONObject sendPostRequest1(String data) {
try {
URL url = new URL(api);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
// con.setRequestProperty("content-type", "application/x-www-form-urlencoded");
con.setDoOutput(true);
con.setDoInput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
try {
writer.write(data);
} catch (Exception e) {
Log.e("Exception111", e.toString());
}
writer.close();
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
Log.d("ServerResponse", new String(sb));
String output = new String(sb);
return new JSONObject(output);
} else {
Log.e("Exception", "" + responseCode);
}
}
catch (JSONException je)
{
je.printStackTrace();
return Excpetion2JSON.getJSON(je);
}
catch(IOException e)
{
}
return null;
}
Async Task :
public class GetLocationAsyncTask extends AsyncTask<String, Void, JSONObject> {
String api;
JSONObject jsonParams;
Context mContext;
private ProgressDialog loadingDialog;
private String number,code;
public GetLocationsCallBack getLocationsCallBack;
public GetLocationAsyncTask(Context context,GetLocationsCallBack getLocationsCallBack) {
this.mContext = context;
this.getLocationsCallBack = getLocationsCallBack;
}
public interface GetLocationsCallBack {
void doPostExecute(ArrayList<Location> list);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected JSONObject doInBackground(String... params) {
try {
api = "https://www.googleapis.com/geolocation/v1/geolocate?key=AIzaSyCArRAX4oHdfFWrTWhXrOVBQtbs";
jsonParams = new JSONObject();
jsonParams.put("cellId", params[0]);
jsonParams.put("locationAreaCode",params[1]);
ServerRequest request = new ServerRequest(api, jsonParams);
return request.sendPostRequest1(jsonParams.toString());
} catch (Exception ue) {
return Excpetion2JSON.getJSON(ue);
}
} //end of doInBackground
#Override
protected void onPostExecute(JSONObject response) {
super.onPostExecute(response);
if(response.has("location"))
{
try {
Location location = new Location();
location.setLattitude(response.getString("lat"));
location.setLongitude(response.getString("lng"));
ArrayList<Location> locations = location.getLocationArrayList();
locations.add(location);
}
catch (JSONException je)
{
Log.d("JsonException",je.toString());
}
}
if (loadingDialog.isShowing())
loadingDialog.dismiss();
}
}
Executing async task:
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation cellLocation = (GsmCellLocation)telephonyManager.getCellLocation();
int cellid= cellLocation.getCid();
int celllac = cellLocation.getLac();
Log.d("CellLocation", cellLocation.toString());
Log.d("GSM CELL ID", String.valueOf(cellid));
Log.d("GSM Location Code", String.valueOf(celllac));
GetLocationAsyncTask getLocationAsyncTask = new GetLocationAsyncTask(MainActivity.this,MainActivity.this);
getLocationAsyncTask.execute(String.valueOf(cellid),String.valueOf(celllac));
Whats going wrong with this? Please help. Thank you..
You have to tell the receiving side that it is json that you send
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

POST data not sent via HttpURLConnection

I'm trying to send POST request via HttpURLConnection, here is the code
public class BackgroundTask extends AsyncTask<String, Void, Void> {
Context context;
Activity activity;
StringBuffer str = null;
int responseCode;
String responseMessage;
public BackgroundTask(Context context) {
this.context = context;
this.activity = (Activity) context;
}
#Override
protected Void doInBackground(String... params) {
HttpURLConnection connection = null;
OutputStream outputStream = null;
InputStream inputStream = null;
BufferedReader reader = null;
BufferedWriter writer = null;
String method = params[1];
if(method.equals("post")) {
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
outputStream = connection.getOutputStream();
writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String data = URLEncoder.encode(params[2] + "=" + params[3], "UTF-8");
writer.write(data);
responseCode = connection.getResponseCode();
responseMessage = connection.getResponseMessage();
inputStream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
str = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
str.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer != null) {
try {
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else if(method.equals("get")) {
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void aVoid) {
TextView txt = (TextView) activity.findViewById(R.id.txt);
if(str != null)
txt.setText(str.toString());
Toast.makeText(activity, responseMessage, Toast.LENGTH_LONG).show();
}
}
responseCode is 200 which means everything went OK, however it says Undefined index: id
id is well defined inside php file
$user = User::find_by_id($_POST['id']);
echo json_encode($user);
and it works fine when I send post request from an html file yet when i send it from application it says id undefined which means that POST data is not sent.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BackgroundTask myTask = new BackgroundTask(MainActivity.this);
myTask.execute(link, "post", "id", "5");
}
});
this is how i instantiate asynctask object inside main activity
UPDATE: when i send not encoded string it works fine!
writer.write("id=5"); // works perfectly!
what is wrong with URLEncoder i use in the code?
I believe you have a problem in this line:
String data = URLEncoder.encode(params[2] + "=" + params[3], "UTF-8");
You are url-encoding the = as well as the params, that's why the server cannot recognise the form fields. Try to encode the params only:
String data = URLEncoder.encode(params[2], "UTF-8") + "=" + URLEncoder.encode(params[3], "UTF-8");
The reason is that URL encoding is for passing special characters like = in the value(or key). Basically, the server will split and parse the key-value pairs with & and = before doing the decoding. And when you url-encode the = character, the server simply couldn't recognise it during the split and parse phase.
When i need to communicate with the server i use this
Server Class
public static String sendPostRequest(String requestURL,
HashMap<String, String> postDataParams) {
URL url;
String response = "";
try {
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
response = br.readLine();
} else {
response = "Error Registering";
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
private static String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
OtherClass
//Run this inside an Asynctask
HashMap<String,String> data = new HashMap<>();
data.put("id", id);
String serverResponce = Server.sendPostRequest(URL,data);

Random org.json.JSONException: Unterminated array at character 24367

Android 4.2.2
I'm parsing a JSON string sent from PHP server. Parsing the same string gives this exception on random character number each time. Sometimes it's loaded successfully. The size of the input is 202858 bytes. I can't post it here as it's private data but I guess it's correctly formatted. If I run my app in debug/step-by-step mode it loads all the time! Also if the size of the response is smaller (fewer lines but not sure how many exactly) it also loads all the time.
Here is how I load the stream:
String JSONResp = "";
try {
URL u = new URL(params[1]);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(params[0]);
conn.connect();
/* Here is the new code. This works! */
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"), 4096);
StringBuilder sb = new StringBuilder();
String line = null;
while( (line = br.readLine()) != null ) {
sb.append(line + "\n");
}
JSONResp = sb.toString();
/* Old code starts here. This is not working!
// Read the stream
InputStream is = conn.getInputStream();
byte[] b = new byte[4096];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ( is.read(b) != -1) {
baos.write(b);
}
JSONResp = new String(baos.toByteArray());
*/
JSONArray arr = new JSONArray(JSONResp);
//TODO read result form the input stream
_HTTP_code = 200;
return arr;
}
catch(Throwable t) {
_HTTP_code = ERROR_Throwable;
_HTTP_text = "Error";
_HTTP_body = "Could not parse response!";
Log.e("JSON", "JSONResp.length() = " + JSONResp.length() + ".");
t.printStackTrace();
}
The code is executed from a separate thread and this is what I found in the Android documentation:
Instances of this class are not thread safe. Although this class is nonfinal, it was not designed for inheritance and should not be subclassed. In particular, self-use by overridable methods is not specified. See Effective Java Item 17, "Design and Document or inheritance or else prohibit it" for further information.
I'm not sure if I understand that text correctly but I don't have more than one thread querying the server at the same time.
Any help would be appreciated.
public class GetResultTask extends AsyncTask<String, Void, String> {
Activity act;
private ProgressDialog pd;
private boolean isInternetConnected = true;
public GetResultTask(Activity _act){
this.act = _act;
pd = ProgressDialog.show(act, null, "Loading...", true );
}
#Override
protected void onPreExecute() {
}
protected void onPostExecute(String result) {
pd.dismiss();
if(!isInternetConnected){
//Toast.makeText(getApplicationContext(), "Check your Network Connection", Toast.LENGTH_LONG).show();
}
}
#Override
protected String doInBackground(String... params) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("option", "getPeople"));
nameValuePairs.add(new BasicNameValuePair("val", params[0]));
String downloadedString = null;
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://example.com/filename.php");
try {
// Execute HTTP Post Request
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8);
httppost.setEntity(ent);
//new
//HttpResponse response = httpClient.execute(httppost);
//System.out.println("Response");
HttpResponse response = httpclient.execute(httppost);
//System.out.println("Response is :-\n"+response);
InputStream in = response.getEntity().getContent();
StringBuilder stringbuilder = new StringBuilder();
BufferedReader bfrd = new BufferedReader(new InputStreamReader(in));
String line;
while((line = bfrd.readLine()) != null)
stringbuilder.append(line);
//string returned as JSON
downloadedString = stringbuilder.toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch(UnknownHostException e){
isInternetConnected = false;
}
catch (IOException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
//System.out.println(downloadedString);
return downloadedString;
}
}

Categories

Resources