How to use user input to open api JSON [duplicate] - java

This question already has answers here:
What arguments are passed into AsyncTask<arg1, arg2, arg3>?
(5 answers)
Closed 3 years ago.
I am working on an Android app in which I am making a weather app. The application opens api data from a JSON and displays this information. More specifically it takes the user input of a city or zip code and adds this info to the URL for the API and then executes the URL.
MainActivity.java
package com.shanehampcsci3660.weather;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
//import static com.shanehampcsci3660.weather.GetJsonData.*;
public class MainActivity extends AppCompatActivity
{
public static TextView tempTV, jsonTV;
public EditText cityORZipET;
private Button getWeather;
public String zip, cityOrZip;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tempTV = (TextView) findViewById(R.id.tempTV);
jsonTV = (TextView) findViewById(R.id.jsonFeedTV);
cityORZipET = (EditText) findViewById(R.id.cityORZipET);
getWeather = (Button) findViewById(R.id.getWeatherButton);
//cityOrZip = cityORZipET.getText().toString();
getWeather.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
GetJsonData getJsonData = new GetJsonData();
//getJsonData.execute();
cityOrZip = cityORZipET.getText().toString();
getJsonData.execute("https://api.openweathermap.org/data/2.5/weather?q=" + cityOrZip +"&appid=x");
jsonTV.setText(cityOrZip);
/*if(cityOrZip.equals(""))
{
getJsonData.execute("https://api.openweathermap.org/data/2.5/weather?q=" + cityOrZip +"&appid=x");
}
else
{
zip = "30528";
getJsonData.execute("https://api.openweathermap.org/data/2.5/weather?q=" + zip + "&appid=x");
}*/
}
});
}
}
GetJsonData.java
package com.shanehampcsci3660.weather;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class GetJsonData extends AsyncTask<Void, Void, Void>
{
public String data= "", line = "", name = "";
double temp, minTemp, maxTemp;
#Override
protected Void doInBackground(Void... voids)
{
try
{
URL url = new URL("https://api.openweathermap.org/data/2.5/weather?q=30528&appid=id");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while(line != null)
{
line = bufferedReader.readLine();
data = data + line;
}
JSONObject jsonObject = new JSONObject(data);
JSONObject main = jsonObject.getJSONObject("main");
name = jsonObject.getString("name");
temp = main.getDouble("temp");
minTemp = main.getDouble("min_temp");
maxTemp = main.getDouble("max_temp");
/*JSONObject jsonObject = new JSONObject(result);
JSONObject jsonData = new JSONObject(jsonObject.getString("main"));
String weatherInfo = jsonObject.getString("weather");
JSONArray jsonArray = new JSONArray(weatherInfo);
String description, icon, iconURI;
for(int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonData1 = jsonArray.getJSONObject(i);
description = jsonData1.getString("description");
MainActivityController.description.setText(description);
icon = jsonData1.getString("icon");
iconURI = "http://openweathermap.org/img/w/" + icon + ".png";
Picasso.get().load(iconURI).into(MainActivityController.conditionImageView);
}*/
}
catch(MalformedURLException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid)
{
super.onPostExecute(aVoid);
//MainActivity.jsonTV.setText(data);
MainActivity.tempTV.setText("City:\t" + name + "\tTemp:\t" + temp);
Log.d("Json Feed", name + "Temp: " + temp);
}
public static void execute(String s) {
}
}
My issue is that no matter where I put...
if(cityOrZip.equals(""))
{
getJsonData.execute("https://api.openweathermap.org/data/2.5/weather?q=" + cityOrZip +"&appid=id");
}
else
{
zip = "30528";
getJsonData.execute("https://api.openweathermap.org/data/2.5/weather?q=" + zip + "&appid=id");
}
...It will only show the data of the default Url opened in GetJsonData.java. My question is what am I doing wrong and what should I correct in order to make my app work with the user input like it should.

you are calling an GetJsonData.execute with the url that contains the client data, but it has no code in it. Looking at your current code the zip that the client inputs does not get stored into the worker class.

This is because you always use the same URL in GetJsonData class. According to question What arguments are passed into AsyncTask? your class declaration should look like:
public class GetJsonData extends AsyncTask<String, Void, YourPojo> {
#Override
protected YourPojo doInBackground(String... urls)
{
try
{
URL url = new URL(urls[0]);
...
} catch (Exception e) {
handle(e);
}
}
}
where YourPojo is a class you need to create to store all properties you need to read from JSON payload:
class YourPojo {
private String data;
private String line;
private String name;
private double temp;
private double minTemp
private double maxTemp;
// getters, setters
}

Related

caused by: Can't toast on a thread that has not called Looper.prepare()

So whenever I Enter a city name in the EditText and press the button my app just crashes and does not show a toast
shows this error in logcat : used by: java.lang.NullPointerException: Can't toast on a thread that has not called Looper.prepare()
Does anyone know who to fix this error?
im using android studio
package com.example.whatstheweather;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
public class MainActivity extends AppCompatActivity {
EditText editText;
TextView resultTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editTextTextPersonName);
resultTextView = findViewById(R.id.resultTextView);
}
public void getWeather(View view){
try {
DownloadTask task = new DownloadTask();
String encodedCityName = URLEncoder.encode(editText.getText().toString(), "UTF-8");
task.execute("http://openweathermap.org/data/2.5/weather?q=" + encodedCityName + "&APPID=9eebb30a9664baf113136d98e764ffb5");
InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}catch (Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Could not find weather :(",Toast.LENGTH_SHORT).show();
}
}
public class DownloadTask extends AsyncTask<String, Void, String >{
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data != -1){
char current = (char) data;
result += current;
data = reader.read();
}
return result;
}catch(Exception e){
e.printStackTrace();;
Toast.makeText(getApplicationContext(),"Could not find weather :(",Toast.LENGTH_SHORT).show();
return null;
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
JSONObject jsonObject = new JSONObject(s);
String weatherInfo = jsonObject.getString("weather");
JSONArray arr = new JSONArray(weatherInfo);
String message = "";
for (int i = 0; i< arr.length(); i++){
JSONObject jsonPart =arr.getJSONObject(i);
String main = jsonPart.getString("main");
String description = jsonPart.getString("description");
if (!main.equals("") && !description.equals("")) {
message += main + ": " + description + "\r\n";
}
}
if (!message.equals("")){
resultTextView.setText(message);
}else{
Toast.makeText(getApplicationContext(),"Could not find weather :(",Toast.LENGTH_SHORT).show();
}
}catch (Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Could not find weather :(",Toast.LENGTH_SHORT).show();
}
}
}
}
try {
//add her code
} catch (java.text.ParseException e) {
runOnUiThread(new Runnable(){
public void run() {
Toast.makeText(getApplicationContext(),"Please key in
the correct input",
Toast.LENGTH_LONG).show();
}
});
e.printStackTrace();
return true; // attention here
}
Method in onCreate :
private void toastPublic(final String message){
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(getBaseContext(),""+message,
4 /*Toast.LENGTH_SHORT*/).show();
}});
}
Next : use in inside asyncTask or Thread

I am trying to get data from different URLs and load then on background

I have built my app with one URL and it worked correctly. But there's a problem from the unmatched return of "onCreateLoader" method in the MainActivity.java.
I use a background thread to load all data without problems. The onCreateLoader method in MainActivity.java should return Loader> and there's a class NewsLoader.java that extends AsyncTaskLoader>.
I want to return new NewsLoader in the onCreateLoader method but there's an error of unmatched return for this method, even tough I have done this before in another similar app.
MainActivity.java
package com.example.newsapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.app.LoaderManager.LoaderCallbacks;
import android.app.LoaderManager;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<Event>> {
private EventAdapter mAdapter;
private static final int LOADER_ID = 1;
private static final String REQUEST_URL_1 = "http://content.guardianapis.com/search?q=debates&api-key=test\n";
private static final String REQUEST_URL_2 = "https://content.guardianapis.com/search?q=debate&tag=politics/politics&from-date=2014-01-01&api-key=test\n";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView earthquakeListView = findViewById(R.id.list_of_news);
mAdapter = new EventAdapter(this, new ArrayList<Event>());
earthquakeListView.setAdapter(mAdapter);
earthquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Event currentEvent = mAdapter.getItem(position);
assert currentEvent != null;
Uri eventUri = Uri.parse(currentEvent.getURL());
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, eventUri);
startActivity(websiteIntent);
}
});
getLoaderManager().initLoader(LOADER_ID, null, this);
}
#NonNull
#Override
public Loader<List<Event>> onCreateLoader(int id, Bundle args) {
return new NewsLoader(MainActivity.this, REQUEST_URL_1, REQUEST_URL_2);
}
#Override
public void onLoadFinished(Loader<List<Event>> loader, List<Event> news) {
mAdapter.clear();
if (news != null && !news.isEmpty()) {
mAdapter.addAll(news);
}
}
#Override
public void onLoaderReset(Loader<List<Event>> loader) {
mAdapter.clear();
}
}
NewsLoader.java
package com.example.newsapp;
import android.content.Context;
import androidx.loader.content.AsyncTaskLoader;
import java.util.List;
public class NewsLoader extends AsyncTaskLoader<List<Event>> {
private static final String LOG_TAG = NewsLoader.class.getName();
private String mUrl1;
private String mUrl2;
public NewsLoader(Context context, String url1, String url2) {
super(context);
mUrl1 = url1;
mUrl2 = url2;
}
#Override
protected void onStartLoading() {
forceLoad();
}
#Override
public List<Event> loadInBackground() {
if (mUrl1 == null && mUrl2 == null) { return null; }
// Perform the network request, parse the response, and extract a list of earthquakes.
List<Event> news = QueryUtils.fetchNewsData(mUrl1, mUrl2);
return news;
}
}
QueryUtils.java
package com.example.newsapp;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class QueryUtils {
private static final String LOCATION_SEPARATOR = "T";
public static final String LOG_TAG = QueryUtils.class.getSimpleName();
private QueryUtils() {
}
public static List<Event> fetchNewsData(String requestUrl1, String requestUrl2) {
URL url1 = createUrl(requestUrl1);
URL url2 = createUrl(requestUrl2);
String jsonResponse1 = null;
String jsonResponse2 = null;
try {
jsonResponse1 = makeHttpRequest(url1);
jsonResponse2 = makeHttpRequest(url2);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
List<Event> news = extractEvents(jsonResponse1, jsonResponse2);
return news;
}
public static List<Event> extractEvents(String eventJSON1, String eventJSON2) {
// verify that there's data in one link at list
if (TextUtils.isEmpty(eventJSON1) && TextUtils.isEmpty(eventJSON2)) {
return null;
}
List<Event> news = new ArrayList<>();
try {
//getting results array from first link
JSONObject baseJsonResponse1 = new JSONObject(eventJSON1);
JSONObject mainObject1 = baseJsonResponse1.getJSONObject("response");
JSONArray eventArray1 = mainObject1.getJSONArray("results");
//getting results array from second link
JSONObject baseJsonResponse2 = new JSONObject(eventJSON2);
JSONObject mainObject2 = baseJsonResponse2.getJSONObject("response");
JSONArray eventArray2 = mainObject2.getJSONArray("results");
// reading required data from array of first link
for (int i = 0; i<eventArray1.length(); i++){
JSONObject currentEvent = eventArray1.getJSONObject(i);
//getting url
String webUrl = currentEvent.getString("webUrl");
//getting title
String webTitle = currentEvent.getString("webTitle");
//getting sectionName
String sectionName = currentEvent.getString("sectionName");
//getting webPublicationDate
String webPublicationDate = currentEvent.getString("webPublicationDate");
String date = "0000 - 00 - 00";
String time = "00:00:00";
if (webPublicationDate.contains(LOCATION_SEPARATOR)) {
String[] parts = webPublicationDate.split(LOCATION_SEPARATOR);
date = parts[0];
time = parts[1].substring(0, parts[1].length() - 1);
}
// Make Quake Of the Strings And Assigning it to earthquakes ArrayList<Quake>
Event quake = new Event(sectionName, webTitle, date, time, webUrl);
news.add(quake);
}
// reading required data from array of first link
for (int i = 0; i<eventArray2.length(); i++){
JSONObject currentEvent = eventArray2.getJSONObject(i);
//getting url
String webUrl = currentEvent.getString("webUrl");
//getting title
String webTitle = currentEvent.getString("webTitle");
//getting sectionName
String sectionName = currentEvent.getString("sectionName");
//getting webPublicationDate
String webPublicationDate = currentEvent.getString("webPublicationDate");
String date = "0000 - 00 - 00";
String time = "00:00:00";
if (webPublicationDate.contains(LOCATION_SEPARATOR)) {
String[] parts = webPublicationDate.split(LOCATION_SEPARATOR);
date = parts[0];
time = parts[1].substring(0, parts[1].length() - 1);
}
// Make Quake Of the Strings And Assigning it to earthquakes ArrayList<Quake>
Event quake = new Event(sectionName, webTitle, date, time, webUrl);
news.add(quake);
}
} catch (JSONException e) {
Log.e("QueryUtils", "Problem parsing the news JSON results", e);
}
// Return the list of earthquakes
return news;
}
private static URL createUrl(String requestUrl) {
URL url = null;
try {
url = new URL(requestUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.connect();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
}
I have found a solution.
the problem here is that Loader has been deprecated in 28-API. So, one cannot use androidx with it.
The solution here is in NewsLoader.java:
Replace: import androidx.loader.content.AsyncTaskLoader;
with: import android.content.AsyncTaskLoader;
If one needs to use a newer way: use ViewrModels

Not able to print JSON object String in android TextView

So I am trying to fetch JSON string from a website which looks like this
[{"name":"Painting"},{"name":"Painting or varnishing doors"},{"name":"Painting or varnishing frames"},{"name":"Varnishing floors"},{"name":"Picking old wallpaper"},{"name":"Painting the facade"},{"name":"professional athlete"}]
I just want to fetch the first JSONObject with the string "Painting".
Here's my MainActivity.java code
package mobiletest.pixelapp.com.mobiletest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import model.Cup;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private String myString;
private String anotherString;
private String myVar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.textView);
Cup myCup = new Cup();
String newString = myCup.myMethod();
try {
JSONArray jsonArray = new JSONArray(newString);
JSONObject jsonObject = jsonArray.getJSONObject(0);
Log.v("Key",jsonObject.getString("name"));
textView.setText(jsonObject.getString("name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Here's my java class file cup.java
package model;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
/**
* Created by pruthvi on 12/2/2015.
*/
public class Cup {
public String myMethod()
{
String output = getUrlContents("http://xyz.co/tests/android-query.php");
return output;
}
private static String getUrlContents(String theUrl)
{
StringBuilder content = new StringBuilder();
// many of these calls can throw exceptions, so i've just
// wrapped them all in one try/catch statement.
try
{
// create a url object
URL url = new URL(theUrl);
// create a urlconnection object
URLConnection urlConnection = url.openConnection();
// wrap the urlconnection in a bufferedreader
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
// read from the urlconnection via the bufferedreader
while ((line = bufferedReader.readLine()) != null)
{
content.append(line + "\n");
}
bufferedReader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
return content.toString();
}
}
Now the problem, when I run this code as java I am easily able to print painting from the JSONObject, but when I try to run it as an android view by setting the text for my TextView, I am getting some strange system.err
12-02 14:06:26.809 19250-19250/mobiletest.pixelapp.com.mobiletest D/libc: [NET] getaddrinfo hn 10, servname NULL, ai_family 0+
12-02 14:06:26.809 19250-19250/mobiletest.pixelapp.com.mobiletest W/System.err: at java.net.InetAddress.lookupHostByName(InetAddress.java:393)
12-02 14:06:26.809 19250-19250/mobiletest.pixelapp.com.mobiletest W/System.err: at java.net.InetAddress.getAllByNameImpl(InetAddress.java:244)
12-02 14:06:26.809 19250-19250/mobiletest.pixelapp.com.mobiletest W/System.err: at java.net.InetAddress.getAllByName(InetAddress.java:219)
I am new to java and android, and as of now I just want to get data from my remote server files and database.
Thanks in advance
look at this example it will give you an idea
AsyncTask<Void, Void, Void> asyncLoad = new AsyncTask<Void, Void, Void>()
{
#Override
protected Void doInBackground(Void... params)
{
URL url = new URL("http://www.omdbapi.com/?i=&t="
+ TITLE);
String URL2="http://www.omdbapi.com/?i=&t=saw";
Log.d("URL content", url.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
Log.d("URL content", "register URL");
urlConnection.connect();
Log.d("URL connection", "establish connection");
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
}
};
asyncLoad.execute();
Do like that in onCrate Method
try {
JSONArray jsonArray = new JSONArray(newString);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String name = jsonObject.getString("name")
textView.setText(name));}
} catch (JSONException e) {
e.printStackTrace();
}
It will set name to textView.
Happy to Help and Happy Coding
You can't do network task in UI Thread.
So
String newString = myCup.myMethod();
not properly working.
Main Reason of those errors are related with thread context.
If you want to do network task with android, use async task or other network library (personally I recommend retrofit).
try
{
JSONArray jsonArray = new JSONArray(newString);
if(jarray.length()>0){
String name = jarray.getJSONObject(0).getString("name");
displayName(name); //new method
}catch(Exception e){
}
Define the method displayName(String) like this outside onCreate()
public void displayName(final String name){
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(jsonObject.getString("name"));
}
});
}

Android File Download from File system web server not working

The list is working fine but the problem is i can't download the file from the web server file system. When i tried clicking one of the list item, the dialog will show up but after a few seconds the app will crash. I am using GenyMotion emulator
The filename is correct and also the url, i guess it's in the saving part
Memo.java
package com.example.androidtablayout;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class Memo extends ListActivity {
// Declare Variables
JSONObject jsonobject;
JSONArray jsonarray;
ListView listview;
ArrayList<HashMap<String, String>> arraylist;
ProgressDialog mProgressDialog, dialog;
JSONParser jsonParser = new JSONParser();
String email;
SessionManager session;
String[] services;
private String url = "http://10.0.3.2/sunshine-ems/memo.php";
// single product url
// ALL JSON node names
private static final String MEMO_ID = "memo_id";
private static final String MEMO_SENDER = "sender";
private static final String MEMO_FILENAME = "file_name";
Button btnLogout;
String username;
String download_path = "";
String dest_file_path = "";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.announc);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
session = new SessionManager(getApplicationContext());
username = session.getUsername();
btnLogout = (Button) findViewById(R.id.btnLogout);
btnLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Launching All products Activity
session.logoutUser();
Intent i = new Intent(getApplicationContext(), Login.class);
startActivity(i);
}
});
new DownloadJSON().execute();
ListView lv = getListView();
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
String memo_filename = ((TextView) view.findViewById(R.id.txt_service)).getText().toString();
download_path = "http://www.sunshine-ems.balay-indang.com/attachments/memo/"+memo_filename+".docx";
String sd_path = Environment.getExternalStorageDirectory().getPath();
dest_file_path = sd_path+"/"+memo_filename+".docx";
dialog = ProgressDialog.show(Memo.this, "", "Downloading file...", true);
new Thread(new Runnable() {
public void run() {
//Log.d("Download Path", dest_file_path+" "+download_path);
downloadFile(download_path, dest_file_path);
}
}).start();
}
});
}
//download
public void downloadFile(String download_path, String dest_file_path) {
try {
File dest_file = new File(dest_file_path);
URL u = new URL(download_path);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(dest_file));
fos.write(buffer);
fos.flush();
fos.close();
hideProgressIndicator();
} catch(FileNotFoundException e) {
hideProgressIndicator();
return;
} catch (IOException e) {
hideProgressIndicator();
return;
}
}
void hideProgressIndicator(){
runOnUiThread(new Runnable() {
public void run() {
dialog.dismiss();
}
});
}
// DownloadJSON AsyncTask
private class DownloadJSON extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(Memo.this);
mProgressDialog.setTitle("Loading Services");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected String doInBackground(String... params) {
username = session.getUsername();
List<NameValuePair> params1 = new ArrayList<NameValuePair>();
params1.add(new BasicNameValuePair("username", username));
JSONObject json = jsonParser.makeHttpRequest(url, "POST", params1);
// Check your log cat for JSON reponse
Log.d("Check JSON ", json.toString());
// Create the array
arraylist = new ArrayList<HashMap<String, String>>();
try {
int success = json.getInt("success");
if (success == 1) {
// Locate the array name
jsonarray = json.getJSONArray("memos");
for (int i = 0; i < jsonarray.length(); i++) {
json = jsonarray.getJSONObject(i);
String m_id = json.optString(MEMO_ID);
String m_subject = json.getString(MEMO_FILENAME);
String m_sender = json.getString(MEMO_SENDER);
// Retrive JSON Objects
HashMap<String, String> map = new HashMap<String, String>();
map.put(MEMO_ID, m_id);
map.put(MEMO_FILENAME, m_subject);
map.put(MEMO_SENDER, m_sender);
// Set the JSON Objects into the array
arraylist.add(map);
}
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String file_url) {
mProgressDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
Memo.this,
arraylist,
R.layout.listview_services,
new String[] { MEMO_ID, MEMO_FILENAME, MEMO_SENDER },
new int[] { R.id.transac_id, R.id.txt_service,
R.id.txt_date });
// updating listview
setListAdapter(adapter);
}
});
}
}
}
I think the downloading was fine, maybe the problem is in the saving/writing part. Maybe the destination path or something close to that
And also where can i see the downloaded file after the download?
I'm using GenyMotion emulator
I'm sorry for the noob questions
Thank you so much
The problem seems to be this line (because it is the only array):
byte[] buffer = new byte[contentLength];
Looking at the declaration of contentLenght it seems conn.getContentLength() is returning a negative number.
Returns the content length in bytes specified by the response header field
content-length or -1 if this field is not set or cannot be represented as an int.
I copied your code and checked with a debugger: contentLenght is always -1.
I just rewrote your downloadFile function to use HttpURLConnection instead of URLConnection. Additionally, it uses a small buffer multiple times instead of creating one large buffer.
//download
public void downloadFile(String download_path, String dest_file_path) {
try {
URL u = new URL(download_path);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
InputStream stream = conn.getInputStream();
File f = new File(dest_file_path);
FileOutputStream fos = new FileOutputStream(f);
int bytesRead = 0;
byte[] buffer = new byte[4096];
while ((bytesRead = stream.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fos.close();
stream.close();
hideProgressIndicator();
} catch(FileNotFoundException e) {
hideProgressIndicator();
return;
} catch (IOException e) {
hideProgressIndicator();
return;
}
}
You can view the file afterwards by using ADB. Android device monitor contains a file explorer and is located at "path-to\AndroidSDK\tools\monitor.bat" (using Windows)

Consuming Restful WCF Service in Android

I am not sure what causing the request not to execute. I was trying to call a WCF Restful service in android, and I receive the error message "Request Error". Looking at the example, I don't see any reason why this example should not work. See below:
Here is the .Net Service:
[ServiceContract]
public interface ISampleService
{
[OperationContract]
[WebInvoke(
Method="POST", UriTemplate="/Login", BodyStyle= WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string Login(string value);
}
public class SampleService : ISampleService
{
public string Login(string value)
{
string t = "";
try
{
//foreach (string s in value)
//{
// t = s;
//}
return t;
}
catch (Exception e)
{
return e.ToString();
}
}
}
Java:
package com.mitch.wcfwebserviceexample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONStringer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity implements OnClickListener {
private String values ="";
Button btn;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)this.findViewById(R.id.btnAccess);
tv = (TextView)this.findViewById(R.id.tvAccess);
btn.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
try
{
AsyncTaskExample task = new AsyncTaskExample(this);
task.execute("");
String test = values;
tv.setText(values);
} catch(Exception e)
{
Log.e("Click Exception ", e.getMessage());
}
}
public class AsyncTaskExample extends AsyncTask<String, Void,String>
{
private String Result="";
//private final static String SERVICE_URI = "http://10.0.2.2:8889";
private final static String SERVICE_URI = "http://10.0.2.2:65031/SampleService.svc";
private MainActivity host;
public AsyncTaskExample(MainActivity host)
{
this.host = host;
}
public String GetSEssion(String URL)
{
boolean isValid = true;
if(isValid)
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://10.0.2.2:65031/SampleService.svc/Login");
try
{
List<NameValuePair> value = new ArrayList<NameValuePair>(1);
value.add(new BasicNameValuePair("value", "123456"));
post.setEntity(new UrlEncodedFormEntity(value));
HttpResponse response = client.execute(post) ;
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line ="";
while((line = rd.readLine()) != null)
{
System.out.println(line);
}
}catch(Exception e)
{
Log.e("Error", e.getMessage());
}
}
return Result;
}
#Override
protected String doInBackground(String... arg0) {
android.os.Debug.waitForDebugger();
String t = GetSEssion(SERVICE_URI);
return t;
}
#Override
protected void onPostExecute(String result) {
// host.values = Result;
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
}
}
}
I finally got it to work they way that I want it to. The issue was that I was building the Array this way (see below section 1) and pass it to the JSONObject or JSONArray. I switched and build the Array using JSONArray and pass it to the JSONObject (see section 2). It works like a charm.
Section1: Wrong way to do it - (It may work this way if you were to look through the array and put them in a JSONArray. It's will be too much work when it can be done directly.)
String[][] Array = {
new String[]{"Example", "Test"},
new String[]{"Example", "Test"},
};
JSONArray jar1 = new JSONArray();
jar1.put(0, Array);
// Did not work
Section 2: The way I did it after long hours of trying and some very helpful tips and hints from #vorrtex.
**JSONArray jar1 = new JSONArray();
jar1.put(0, "ABC");
jar1.put(1, "Son");
jar1.put(2, "Niece");**
**JSONArray jarr = new JSONArray();
jarr.put(0, jar1);**
JSONArray j = new JSONArray();
j.put(0,"session");
JSONObject obj = new JSONObject();
obj.put("value", jarr);
obj.put("test", j);
obj.put("name","myName");
Log.d("Obj.ToString message: ",obj.toString());
StringEntity entity = new StringEntity(obj.toString());
Looking at the web service, and it has exactly what I was looking for.
Thanks for you help!!!!

Categories