Logical error in getting a text from URL with okHttp - android

Im trying to write an app to read a text file from an url like this "http://chemvaaj.xzn.ir/test/words.txt"
it seems right but it doesn't return what it should :\
here's my code :
public String DL (){
OkHttpHandler handler = new OkHttpHandler();
String text ="";
try {
text = handler.execute().get();
if (text!= null && text.length()> 0){
System.out.println("not empty");
return text;
}
} catch (Exception e) {
text= "empty !!";
}
return text;
}
and here is OkHttpHandler class :
public class OkHttpHandler extends AsyncTask<Void, Void, String> {
private final String DB_URL = "http://chemvaaj.xzn.ir/test/words.txt";
OkHttpClient httpClient = new OkHttpClient();
#Override
protected String doInBackground(Void... params) {
Request.Builder builder = new Request.Builder();
builder.url(DB_URL);
Request request = builder.build();
try {
Response response = httpClient.newCall(request).execute();
return response.body().toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.e("ANSWER", "" + s);
}
}
and here's my logcat after call DL() function :
10-28 00:23:25.167 17288-17288/erfan.bagheri.chemvaaj E/ANSWER﹕ com.squareup.okhttp.internal.http.RealResponseBody#423bc6b8

You should replace return response.body().toString(); by return response.body().string();
Please refer to my following working sample code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView);
new GetFileRequest().execute();
}
...
private class GetFileRequest extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... voids) {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://chemvaaj.xzn.ir/test/words.txt")
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
return e.toString();
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (mTextView != null && result != null) {
mTextView.setText(result);
}
}
}
Here is the screenshot
Hope this helps!

First of all, please check how an AsyncTask works. Here's the official, easy to understand how-to-use.
Then you'll find that the method execute() returns the task itself, not the resulting String object.
It seems that OkHttpClient's returned Response object can be transformed to string in the following way:
response.body().toString();
Just one more hint: please avoid returning null in any method, it's considered very bad practice.

OkHttpClient is used in the wrong way(Suppose you want to use async). OkHttp is a full featured Http client library and has Asynchronous requests implemented in itself.
So there is no need to Android AsyncTask.
Here is the right way:
private final OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://chemvaaj.xzn.ir/test/words.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}
#Override public void onFailure(Request request, Throwable throwable) {
throwable.printStackTrace();
}
});

I am not familiar with OkHttpClient but from the log I am guessing that the body response is a complex object that does not have a toString() that will show you a human readable response. You will probably have to print a specific member of that object to get your readable response.

try this
OkHttpClient and callback:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
// Headers responseHeaders = response.headers();
// for (int i = 0; i < responseHeaders.size(); i++) {
// System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
// }
// System.out.println(response.body().string());
InputStream in = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String result, line = reader.readLine();
result = line;
while((line = reader.readLine()) != null) {
result += line;
}
System.out.println(result);
}
});

Related

Android - Skipping frames when trying to login to server from application. (async)

public class AppApi extends AsyncTask<String, Void, String> {
private OkHttpClient client;
private Request request;
private MediaType JSON;
private String URL;
private RequestBody body;
public AppApi(JSONObject obj) {
client = new OkHttpClient();
JSON = MediaType.parse("application/json; charset=utf-8");
URL = "http://serverapi.domain.com/user/login";
Log.d("Information",obj.toString());
body = RequestBody.create(JSON, obj.toString());
request = new Request.Builder()
.url(URL)
.post(body)
.build();
}
#Override
protected String doInBackground(String... strings) {
// execute fonksiyonu cagrilarak calistirilir
try {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception ex) {
Log.e("doInBackground()", ex.getMessage());
return null;
}
}
protected void onProgressUpdate(Integer... progress) {
// setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
// showDialog("Downloaded " + result + " bytes");
}
}
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
login();
}
}
LoginActivity.Java below.
private void login() {
JSONObject data = new JSONObject();
try {
data.put("email", "email");
data.put("password", "pass");
} catch (JSONException e) {
}
AppApi api = new AppApi(data);
try {
String result = api.execute().get();
Log.d("login()", result);
} catch (Exception e) {
e.printStackTrace();
}
}
So the problem with the application is that we can't properly login to our https server. Android Studio says it is skipping frames.
I/Choreographer: Skipped 77 frames! The application may be doing too
much work on its main thread.
When we try to enter the wrong password intentionally, it skips even more frames.(200ish)
I think we did most of the coding correctly on the Async task side. How can we check the return value? How can we solve the problem?
Try to put the build request into the background thread as well .i.e
private JSONObject obj;
public AppApi(JSONObject obj) {
this.obj = obj;
}
#Override
protected String doInBackground(String... strings) {
// execute fonksiyonu cagrilarak calistirilir
try {
client = new OkHttpClient();
JSON = MediaType.parse("application/json; charset=utf-8");
URL = "http://serverapi.domain.com/user/login";
Log.d("Information",obj.toString());
body = RequestBody.create(JSON, obj.toString());
request = new Request.Builder()
.url(URL)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception ex) {
Log.e("doInBackground()", ex.getMessage());
return null;
}
}

OkHttp on Android

This is my code to get the JSON string from my PHP server.
When I run this the app crashes and says that there is an error with Response response = client.newCall(request).execute();
What am I doing wrong?
public class MainActivity extends Activity {
//private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new AsyncTask<Void, Void, String>(){
#Override
protected String doInBackground(Void... params) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
try {
Response response = client.newCall(request).execute();
Log.d("OkHttp", "doInBackground() called with: " + "params = [" + response.body().string() + "]");
return response.body().string();
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
}
You don't need to put this into an async task as you can use the call back of the OKHttp library which itself is async.
Second thing is you are using the wrong method. Instead of execute() you should use enqueue() which has a callback as a parameter as I mentioned above.
Try this code:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// Observe reason of failure using
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
// Use response here
}
else{
// Observe error
}
}
});

Android: OkHttp request within AsyncTask is called twice

I have a OkHttp request within an async taks doInBackgroun(), The resquest is a bit heavy and takes some time on my backend. Unfortunatly it looks like when OKHttp doesn't get an answer straight away it tries again, this makes my server blow up !
I have tried to disable this function but it seems to ignore it... What could i do ?
public class AsyncUpdateNewPatients extends AsyncTask<Object, Void, Boolean> {
private static OkHttpClient okHttpClient;
private static DatabaseHandler db;
ActivityMain activityMain;
public AsyncUpdateNewPatients (ActivityMain atv)
{
this.activityMain = atv;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Stormpath.logger().d(message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(httpLoggingInterceptor)
.retryOnConnectionFailure(false)
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15L, TimeUnit.SECONDS)
.writeTimeout(15L, TimeUnit.SECONDS)
.build();
db = new DatabaseHandler(activityMain);
}
#Override
protected Boolean doInBackground(Object... objects) {
List<PatientData> allNewPatients = db.getAllNewPatients();
JSONArray allNewPatientJSONArray = new JSONArray();
for (PatientData tempPatientObject : allNewPatients) {
JSONObject tempPatientJSON = new JSONObject();
try {
tempPatientJSON.put("firstName", tempPatientObject.getFirstName());
tempPatientJSON.put("lastName", tempPatientObject.getLastName());
tempPatientJSON.put("height", tempPatientObject.getHeight());
tempPatientJSON.put("weight", tempPatientObject.getWeight());
tempPatientJSON.put("vaccines", tempPatientObject.getVaccinHistory());
tempPatientJSON.put("address", tempPatientObject.getAddress());
tempPatientJSON.put("zone", tempPatientObject.getZone());
tempPatientJSON.put("id", tempPatientObject.getId());
String dateOfBirth = tempPatientObject.getDateOfBirth().get(Calendar.DAY_OF_MONTH) + "/" + tempPatientObject.getDateOfBirth().get(Calendar.MONTH) + "/" + tempPatientObject.getDateOfBirth().get(Calendar.YEAR);
tempPatientJSON.put("dob",dateOfBirth);
} catch (JSONException e) {
e.printStackTrace();
}
allNewPatientJSONArray.put(tempPatientJSON);
}
if(allNewPatients.size() > 0){
JSONObject bodyJSON = new JSONObject();
try {
bodyJSON.put("allNewPatients", allNewPatientJSONArray);
} catch (JSONException e) {
e.printStackTrace();
}
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
final RequestBody body = RequestBody.create(JSON, String.valueOf(bodyJSON));
Request request = new Request.Builder()
.url(activityMain.getString(R.string.main_url) + "/api/syncFromOffLine")
.headers(buildStandardHeaders(Stormpath.accessToken()))
.post(body)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d("DEBEUG", "error: " + e.getMessage());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.code() == 200){
Log.d("DEBEUG", "response: " + response.body().string());
} else {
Log.d("DEBEUG", "there was an error: " + response.message().toString());
}
}
});
}
return true;
}

Android: file extension is undefined in the response body after uploading a file to server

I am using the following code for sending files (pdf,docx,pptx etc) from user to user in a chatting application.
public class UploadFile extends AsyncTask<String, Void, String> {
protected MessageModel mMessage;
File file ;
String mimeType = "";
public UploadFile(MessageModel msg, File file) {
super();
this.mMessage = msg;
this.file = file;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String responseBodyText = null;
mimeType = mMessage.getMsgFileType();
MediaType MEDIA_TYPE = okhttp3.MediaType.parse(mimeType);
OkHttpClient client = new OkHttpClient();
try {
RequestBody req = new okhttp3.MultipartBody.Builder()
.setType(okhttp3.MultipartBody.FORM)
.addFormDataPart("chatFileUpload", file.getName(), RequestBody.create(MEDIA_TYPE, file)).build();
Request request = new Request.Builder()
.header("Authorization", "Bearer "+Constants.AUTH_TOKEN)
.addHeader("User-Agent", Constants.USER_AGENT)
.url(urlforFileUpload)
.post(req)
.build();
Response response = null;
response = client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException("Okhttp Error: " + response);
} else {
responseBodyText = response.body().string();
Log.d("PrintResponseBody", responseBodyText); // Print the response body here
}
} catch (IOException e) {
e.printStackTrace();
}
return responseBodyText;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
JSONObject msgFiles = new JSONObject();
if (result != null) {
try {
JSONObject responseObject = new JSONObject(result);
msgFiles.put("filename", responseObject.get("fileName"));
msgFiles.put("mimetype", responseObject.get("mimetype"));
msgFiles.put("filepath", responseObject.get("fileUploadPath"));
Log.d("PrintFileUploadPath", String.valueOf(responseObject.get("fileUploadPath")));
// Print the response upload file path with file name and extension;
//.... do other stuffs....
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
In the logcat, I'm getting extension as 'undefined' instead of proper extension name (.docx, .pptx etc). Can someone tell me which might cause this kind of behavior? Is it appropriate? If yes, how am I supposed to check which type of file user is receiving from server response?
An example of response I'm getting using debugger:
{
"status":"true",
"fileName":"1490691261587.undefined",
"fileUploadPath":"/uploads/chat_upload/1490691261587.undefined",
"mimetype":"file/file",
"msg":"File is uploaded successfully",
"downloadLink":"<a target=\"_blank\" href=\"/uploads/chat_upload/1490691261587.undefined\">New-Text-Document.txt909.txt</a>"
}
Thanks in advance.

Error "Unhandled exception: java.io.IOException" while using OkHttp in MainActivity

Error has appeared on //Response response = client.newCall(request).execute();
return response.body().string();// lines.
The whole code:
`
OkHttpClient client = new OkHttpClient();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
}`
Where should I write url-adress which I enter? In OkHttp documentation it's shown only for public class. Where should I write this code if I wnat it in MainActivity:
public static void main(String[] args) throws IOException{
OkHttpexample okHttpexample = new OkHttpexample();
String response =
okHttpexample.run("https://raw.github.com/square/okhttp/master/README.md");
System.out.println(response);}
If you know more detailed tutorials on OkHttp, it would be useful
For your reference:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new APIRequest().execute();
}
private class APIRequest extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... voids) {
String response;
try {
// HTTP GET
GetExample example = new GetExample();
response = example.run("http://192.168.1.100/api/getsomething");
} catch (IOException e) {
response = e.toString();
}
return response;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// do something...
}
}
public class GetExample {
final OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
try {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
return e.toString();
}
}
}
}
You may need to catch the IOException, try involving your HTTP call with a Try/Catch.
Try {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException exception) {
}
and as you do this, remove the throws IOException from your method declaration.

Categories

Resources