Asking the user for a URL to receive a JSON - java

Just as a practicing exercise i'm trying to make an app that fetches a JSON from a URL.
I found the following code in other thread here in stackoverflow and it works just fine. My problem is that the URL is hardcoded, and i need it to be an input by the user. What should i change/add?
public class MainActivity extends AppCompatActivity {
Button btnHit;
TextView txtJson;
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnHit = (Button) findViewById(R.id.btnHit);
txtJson = (TextView) findViewById(R.id.tvJsonItem);
btnHit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new JsonTask().execute("Url address here");
}
});
}
private class JsonTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
Log.d("Response: ", "> " + line); //here u ll get whole response..... :-)
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (pd.isShowing()){
pd.dismiss();
}
txtJson.setText(result);
}
}
}
This is the thread where i got that code from:
Get JSON Data from URL Using Android?

Create a constructor in your async Task
private class JSONTask extends AsyncTask<String, String, String> {
String url;
public JSONTask(String url){
this.url=url;
}
use the url string in place of params[0]
And wherever you call your async task do it like this
new JSONTask(textView.getText()).execute()
This should solve it.
Else you can directly use the do in background variable params.

So the problem is that you are using a TextView. TextView does not recieve inputs.
EditText does.
Make these Changes:
TextView txtJson;
In your OnCreate change this:
txtJson = (EditText) findViewById(R.id.tvJsonItem);
btnHit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new JsonTask().execute(txtJson.getText());
}
});
Now in your xml file change the Button to EditText.
Hope this helps.

Related

Returning result from Asynctask

If I have this background worker file in my android application and it gets data from my database how can I pass the string 'result' to another class?
The background worker connects to my server and then using php it connects to a database.
public class BackgroundWorker extends AsyncTask<String,Void,String> {
Context context;
AlertDialog alertDialog;
BackgroundWorker (Context ctx) {
context = ctx;
}
#Override
public String doInBackground(String... params) {
String type = params[0];
String specials_url = "";
if(type.equals("venue click")) {
try {
//String user_name = params[1];
URL url = new URL(specials_url);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
// String post_data = URLEncoder.encode("user_name","UTF-8")+"="+URLEncoder.encode(user_name,"UTF-8");
// bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"iso-8859-1"));
String result="";
String line="";
while((line = bufferedReader.readLine())!= null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle("Info");
}
#Override
protected void onPostExecute(String result) {
alertDialog.setMessage(result);
alertDialog.show();
// String temp = "login success";
// if (result.equals(temp)) {
// Intent intent = new Intent(context, Register.class);
// context.startActivity(intent);
// }
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
You need a listener. This will allow you to notify back when the AsyncTask is done.
Define the listener by creating an interface, like this:
public interface IListener
{
void onCompletedTask(String result);
}
On the task store a reference to the listener.
private IListener mListener;
// Pass the reference to the constructor.
public BackgroundWorker(IListener listener)
{
mListener = listener;
}
Then you notify the listener like this.
#Override
protected void onPostExecute(String result)
{
mListener.onCompletedTask(result);
}
Best way to get a callback from background thread is to use interfaces as a callback from AsyncTask for example:
create an interface that can be called in onPostExecute()
public interface ResponseCallback {
void onRespond(String result);
}
and before calling asynckTask define it like this:
ResponseCallback cpk = new ResponseCallback() {
#Override
public void onRespond(String result) {
//code to be done after calling it from onPostExecute
}
};
and pass cpk to the constructor of of the asynckTask and call it in onPostExecute like that:
if(cpk!=null){
cpk.onRespond(result);
}
of course you can modify the signature of the interface to what ever you want.

Unable to access string from class

I want to show string from another string in my MainActivity, but the string is getting printed in console. Here is my code:
public class MainActivity extends AppCompatActivity {
Button start;
public TextView showText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showText= (TextView)findViewById(R.id.textView);
start = (Button)findViewById(R.id.button);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RetrieveFeedTask click1 = new RetrieveFeedTask();
click1.execute();
showText.setText(click1.getString());
}
});
}
}
And the class:
class RetrieveFeedTask extends AsyncTask<Void, Void, String> {
static final String API_URL = "http://numbersapi.com/random/trivia?json";
private Exception exception;
public String finalString;
protected void onPreExecute() { }
protected String doInBackground(Void... urls) {
try {
URL url = new URL(API_URL );
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
while ((finalString = bufferedReader.readLine()) != null) {
stringBuilder.append(finalString).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
}
finally{
urlConnection.disconnect();
}
}
catch(Exception e) {
Log.e("ERROR", e.getMessage(), e);
return null;
}
}
protected void onPostExecute(String response) {
if(response == null) {
response = "THERE WAS AN ERROR";
}
try {
JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
finalString = object.getString("text");
Log.i("Here",finalString);
} catch (JSONException e) {
}
}
public String getString() {
return this.finalString;
}
}
You require the finalString before it's populated with your data. the onPostExecute is executed after the doInBackground so you should pass your text view to your task and set it's value in the onPostExecute
public TextView showText;
public RetrieveFeedTask(TextView showText) { this.showText = showText; }
protected void onPostExecute(String response) {
if(response == null) {
response = "THERE WAS AN ERROR";
}
try {
JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
finalString = object.getString("text");
showText.setText(finalString ); // add this
Log.i("Here",finalString);
} catch (JSONException e) {
}
}
The problem is that showText.setText(click1.getString()); of your activity is called earlier than finalString = object.getString("text"); of your task.
Solution:
Create an interface:
public interface DataCallback {
void onNewData(String data);
}
and implement it in your activity:
public class MainActivity extends ... implements DataCallback
public void onNewData(String data) {
showText.setText(data);
}
Pass the interface to your asynctask when you create it:
RetrieveFeedTask click1 = new RetrieveFeedTask(this);
Call the interface inside the task in onPostExecute() to notify the activity that there is new data:
JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
finalString = object.getString("text");
callback.onNewData(finalString);

How do i set an ImageView to show an image from an image url?

When i try to set the ImageView variable "profilePicture" to the bitmap from the image url, it doesn't show anything. Please help!! I am getting the image url link from my database. This is what that async task result is.
System.out: Resulted Value: {"image":"http://www.myegotest.com/PhotoUpload/uploads/5.png"}
Here is my Java code
public class HomeActivity extends AppCompatActivity {
//View item variables
private TextView loggedUsersName;
private TextView successMessage;
private Button logoutButton;
private ImageView profilePicture;
//Other variables
private String getProfileImageURL = "http://www.myegotest.com/PhotoUpload/getAllImages.php";
private String firstName;
private String lastName;
private String email;
private Bitmap profilePicBitmap;
LocalDataBase mLocalDataBase;
Boolean imageSet;
Drawable d;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//Get logged in user from LocalDataBase and
//Destroy Activity if user is logged out
mLocalDataBase = new LocalDataBase(this);
User user = mLocalDataBase.getLoggedInUserInfo();
if(!mLocalDataBase.userIsLoggedIn()){
HomeActivity.this.finish();
}
//Initialize view item variables.
loggedUsersName = (TextView)findViewById(R.id.login_user);
successMessage = (TextView)findViewById(R.id.message);
logoutButton = (Button)findViewById(R.id.logoutButton);
profilePicture = (ImageView)findViewById(R.id.profile_Picture);
//Get intent and values from the intent started this activity and
//Get loggedIn user values from the LocalDataBase .
Intent intent = getIntent();
String message = intent.getStringExtra("MESSAGE");
firstName = user.mFirstName;
lastName = user.mLastName;
email = user.mEmail;
//Set view values to equal values sent from intent.
loggedUsersName.setText(firstName + " " + lastName);
successMessage.setText(message);
netAsync();
}
//Call this method to execute the Async Task
private void netAsync() {
new NetCheck().execute();
}
//Async Task to check whether internet connection is working.
private class NetCheck extends AsyncTask {
private ProgressDialog mDialog;
//Create and show progress dialog box so user knows the app is trying to login.
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog = new ProgressDialog(HomeActivity.this);
mDialog.setTitle("Logging In...");
mDialog.setMessage("connecting to server");
mDialog.setIndeterminate(false);
mDialog.setCancelable(true);
mDialog.show();
}
//Gets current device state and checks for working internet connection by trying Google.
#Override
protected Boolean doInBackground(Object[] objects) {
ConnectivityManager mCM = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo myNetInfo = mCM.getActiveNetworkInfo();
if ( (myNetInfo != null) && (myNetInfo.isConnected())){
try {
URL url = new URL("http://google.com");
HttpURLConnection myConnection = (HttpURLConnection) url.openConnection();
myConnection.setConnectTimeout(3000);
myConnection.connect();
if (myConnection.getResponseCode() == 200){
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
//If successful internet connection start AsyncTask to register user info on server
if(o.equals(true)){
mDialog.dismiss();
new RegisterUser().execute(getProfileImageURL, email);
} else {
mDialog.dismiss();
Toast.makeText(getApplicationContext(), "Error in Network Connection", Toast.LENGTH_SHORT).show();
}
}
}
//AsyncTask to get profile pic url string from server
private class RegisterUser extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection LucasHttpURLConnection = (HttpURLConnection)url.openConnection();
LucasHttpURLConnection.setRequestMethod("POST");
LucasHttpURLConnection.setDoOutput(true);
LucasHttpURLConnection.setDoInput(true);
LucasHttpURLConnection.setConnectTimeout(1000 * 6);
LucasHttpURLConnection.setReadTimeout(1000 * 6);
//OutputStream to get response
OutputStream outputStream = LucasHttpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,"UTF-8"));
String data =
URLEncoder.encode("email", "UTF-8")+"="+URLEncoder.encode(params[1], "UTF-8");
bufferedWriter.write(data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
//InputStream to get response
InputStream IS = LucasHttpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IS, "iso-8859-1"));
StringBuilder response = new StringBuilder();
String json;
while( (json = bufferedReader.readLine()) != null){
response.append(json + "\n");
break;
}
bufferedReader.close();
IS.close();
LucasHttpURLConnection.disconnect();
return response.toString().trim();
} catch (MalformedInputException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Print server AsyncTask response
System.out.println("Resulted Value: " + result);
//If null Response
if (result != null && !result.equals("")) {
String profilepic = returnParsedJsonObject(result);
new GetBitmapImageFromUrl().execute(profilepic);
profilePicture = (ImageView)findViewById(R.id.profile_Picture);
profilePicture.setImageBitmap(profilePicBitmap);
} else {
Toast.makeText(HomeActivity.this, "Sorry, there was an error. Please try again", Toast.LENGTH_LONG).show();
}
}
//Method to parse json result and get the value of the key "image"
private String returnParsedJsonObject(String result){
JSONObject resultObject = null;
String returnedResult = "";
try {
resultObject = new JSONObject(result);
returnedResult = resultObject.getString("image");
} catch (JSONException e) {
e.printStackTrace();
}
return returnedResult;
}
}
class GetBitmapImageFromUrl extends AsyncTask<String,Void,Bitmap>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Bitmap doInBackground(String... params) {
try {
profilePicBitmap = BitmapFactory.decodeStream((InputStream)new URL(params[0]).getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
}
}
}
If you are seeing background white instead image. Out of memory exception by using bitmap.
You could use
Option 1
URL newurl = new URL(photo_url_str);
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
profile_photo.setImageBitmap(mIcon_val);
Picasso
Picasso.with(context).load("http://www.myegotest.com/PhotoUpload/uploads/5.png").into(profilePicture);
I would suggest to go with Piccasso. Since it will handle everything.

AsyncTask dont show me message from server (HttpUrlConnection)

So I'm trying to read a message from the server by HttpURLConnection in a AsyncTask class. The problem is, when i send the request to read the data from the server, it just keeps displaying the ProgresssDialog, like it doesn't read the data from the server:
public class MainActivity extends Activity{
EditText name, password;
Button login;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = (EditText) findViewById(R.id.name);
password = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String serverURL = "http://192.168.1.1/my/text.php";
LongOperation longOperation = new LongOperation();
longOperation.execute(serverURL);
}
});
}
private class LongOperation extends AsyncTask<String, Void, Void> {
private String content;
private String error = null;
private ProgressDialog dialog = new ProgressDialog(MainActivity.this);
TextView uiUpdate = (TextView) findViewById(R.id.output);
#Override
protected void onPreExecute() {
uiUpdate.setText("Output : ");
dialog.setMessage("Downloading source..");
dialog.show();
}
#Override
protected Void doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection client = (HttpURLConnection)url.openConnection();
client.connect();
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
content = bufferedReader.readLine();
bufferedReader.close();
inputStream.close();
client.disconnect();
} catch (IOException e) {
error = e.getMessage();
}
return null;
}
#Override
protected void onPostExecute(Void unused) {
dialog.dismiss();
if (error != null) {
uiUpdate.setText("Output : "+error);
} else {
uiUpdate.setText("Output : "+content);
}
}
I already tryed before the connectivity to server via HttpClient, so thats not the problem.Thanks!
Try debugging it and see if OnPostExecute() method is getting called or not.!
This seems to get stuck in your stream reader code. Also, add a connection timeout of, say, 5-10 seconds for better user experience.!
Moreover, there seems to be an issue with your return type of doInBackground() method and input parameter type of OnPostExecute() method. As per your AsyncTask definition, they both should be string, isnt it?
See this
Try remove client.connect();
try {
URL url = new URL(urls[0]);
HttpURLConnection client = (HttpURLConnection)url.openConnection();
//remove client.connect();
int response = client.getResponse();
if(response == HttpURLConnection.HTTP_OK){
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
content = bufferedReader.readLine();
bufferedReader.close();
inputStream.close();
}
finally{
client.disconnect();
}
} catch (IOException e) {
error = e.getMessage();
}
return null;
Make sure your server is running. Also set request time out.
You are not always required to explicitly call the connect method to initiate the connection. Operations that depend on being connected, like getInputStream, getOutputStream will implicitly perform the connection, when necessary.
This link
Try this:
private class LongOperation extends AsyncTask<String, Void, String>
{
private String content;
private String error = null;
private ProgressDialog dialog = new ProgressDialog(MainActivity.this);
TextView uiUpdate = (TextView) findViewById(R.id.output);
#Override
protected void onPreExecute() {
uiUpdate.setText("Output : ");
dialog.setMessage("Downloading source..");
dialog.show();
}
#Override
protected Strinh doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection client = (HttpURLConnection)url.openConnection(); client.connect();
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
content = bufferedReader.readLine();
bufferedReader.close();
inputStream.close();
//client.discon dialog.dismiss();
}
catch (IOException e)
{
content = e.getMessage();
}
return content ;
}
#Override
protected void onPostExecute(String returnValue) {
if (return value != null) {
uiUpdate.setText("Output : "+error);
}
else {
uiUpdate.setText("Output No Value Returned");
}
dialog.dismiss();
}

android network connection faliure

I'm having a hard time to connect the application to the internet and retrieve the html source.
Been looking all over for a solution and didn't find. Hope someone could help.
Here is my code:
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText et = (EditText) findViewById(R.id.editText1);
final Button b = (Button) findViewById(R.id.button1);
final TextView tv = (TextView) findViewById(R.id.textView1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
URL url=null;
url = new URL(et.getText().toString());
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
tv.append(line);
}
} catch (Exception e) {
}
}
});
}
I've also added INTERNET permission..
You need to move the code which connects to the internet and fetches data to an AsyncTask. This is because of the NetworkOnMainThreadException. This exception is thrown when an application attempts to perform a networking operation on its main thread.
Though there is a workaround available by using the StrictMode.ThreadPolicy, it highly advisable not to do that.
Here is a excerpt from the docs.
NetworkOnMainThreadException:-
This is only thrown for applications
targeting the Honeycomb SDK or higher. Applications targeting earlier
SDK versions are allowed to do networking on their main event loop
threads, but it's heavily discouraged.
See this question for more info.
Because you are doing this on UI therad.
Try this:
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText et = (EditText) findViewById(R.id.editText1);
final Button b = (Button) findViewById(R.id.button1);
final TextView tv = (TextView) findViewById(R.id.textView1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Thread th = new Thread() {
#Override
public void run() {
try {
URL url=null;
url = new URL(et.getText().toString());
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
tv.append(line);
}
} catch (Exception e) {
}
}
};
th.start();
}
});
}
i will suggest you to use AsyncTask
Do this
On ButtonClick
RequestClient reqClient = new RequestClient(ActivityName.this);
String AppResponse = null;
AppResponse = reqClient.execute().get();
RequestClient
public class RequestClient extends AsyncTask<String, Void, String> {
Context context;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
HttpClient httpclient = new DefaultHttpClient(); // Create HTTP Client
HttpGet httpget = new HttpGet("http://yoururl.com"); // Set the action you want to do
HttpResponse response = httpclient.execute(httpget); // Executeit
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent(); // Create an InputStream with the response
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) // Read line by line
sb.append(line + "\n");
String resString = sb.toString(); // Result is here
is.close(); // Close the stream
} catch (Exception e) {
Log.d("ANDRO_ASYNC_ERROR", "Error is " + e.toString());
}
Log.d("ANDRO_ASYNC_RESPONSE", responseString.trim());
client.getConnectionManager().shutdown();
return responseString.trim();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}

Categories

Resources