Downloading the image using OkHttp gives null - android

I tried to download image from URL using OkHttp . It returns null.
I have permissions
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Here is my Rest Client
public class RestClient {
private static volatile RestClient instance;
private final OkHttpClient client;
private RestClient(Context context) throws Exception {
client = new OkHttpClient();
}
public static RestClient getInstance(Context context) throws Exception {
if (instance == null)
synchronized (RestClient.class) {
if (instance == null)
instance = new RestClient(context);
}
return instance;
}
public Call uploadPicture(Callback callback){
String link = "http://www.101apps.co.za/images/headers/101_logo_very_small.jpg";
Request request = new Request.Builder()
.url(String.format(link))
.get()
.build();
Call call = client.newCall(request);
call.enqueue(callback);
return call;
}
}
Here is my getPicture method in the main activity
public void getPicByURL() {
try {
RestClient.getInstance(getActivity()).uploadPicture(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Response response) throws IOException {
final String json = response.body().string();
if (response.code() == Constants.SUCCESSFUL_DOWNLOAD) {
ResponseBody in = response.body();
InputStream inputStream = in.byteStream();
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
updateImage(BitmapFactory.decodeStream(bufferedInputStream));
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void updateImage(final Bitmap bitmap) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
if (bitmap != null) {
mSelectedPic.setImageBitmap(bitmap);
} else {
Toast.makeText(getActivity(), R.string.show_error, Toast.LENGTH_SHORT).show();
}
}
});
}
updateImage() method takes bitmap = null. I don`t know what I doing wrong. Please help.

Hi its work for me try this
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("https://www.101apps.co.za/images/headers/101_logo_very_small.jpg").get().build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.i("Tag","error"+e.getMessage());
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
runOnUiThread(new Runnable() {
#Override
public void run() {
ImageView imageView (ImageView)findViewById(R.id.down_imageView);
ResponseBody in = response.body();
InputStream inputStream = in.byteStream();
Log.i("inputStream","inputstream value = "+inputStream);
// convert inputstram to bufferinoutstream
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
Bitmap bitmap=BitmapFactory.decodeStream(bufferedInputStream);
Log.i("bitmap","bitmap value = "+bitmap);
imageView.setImageBitmap(bitmap);
}
});
}
});
}
});

With your current Url (http://www.101apps.co.za/images/headers/101_logo_very_small.jpg) and your purpose (loading the image into ImageView only), I suggest you use Picasso or Glide instead.
Sample code if using Picasso:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Picasso.with(this)
.load("http://www.101apps.co.za/images/headers/101_logo_very_small.jpg")
.into(imageView);
Hope it helps!

Related

Android Studio how to use Request in Fragments

I want to make this request in a fragment but the errors, as could I do?, thanks! I have many errors as .Builder() or OkHttpClient() when I want to implement it in a Fragment so I do not say any error in particular
String url = "https://freegeoip.net/json/"
Request mRequest = new Request.Builder()
.url(url)
.build();
Context mContext // A UI context
new OkHttpClient().newCall(mRequest).enqueue(new Callback() {
Handler mainHandler = new Handler(mContext.getApplicationContext().getMainLooper());
#Override
public void onResponse(Call call, Response response) {
String responseBody = null;
try {
responseBody = response.body().string();
} catch (final IOException e) {
mainHandler.post(new Runnable() {
#Override
public void run() {
// handle error
}
});
}
final String finalResponseBody = responseBody;
mainHandler.post(new Runnable() {
#Override
public void run() {
// handle response body
try {
JSONObject locationObject = new JSONObject(finalResponseBody);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
#Override
public void onFailure(Call call, final IOException e) {
mainHandler.post(new Runnable() {
#Override
public void run() {
mNetworkListener.onNetworkError(e.getMessage());
}
});
}
});

okhttp3 how to return value from async GET call

I am implementing Helper class in Android studio to service Activity
public void getLastId()
{
//init OkHttpClient
OkHttpClient client = new OkHttpClient();
//backend url
Request request = new Request.Builder()
.url("http://192.168.1.102:8080/aquabackend/public/customers/lastid")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String jsonData = response.body().string();
try {
JSONObject jobject = new JSONObject(jsonData);
String id = jobject.getString("id");
//increment current id +1
String last_id = String.valueOf(Integer.parseInt(id)+1);
Log.i("new id", last_id);
} catch (Exception e) {
e.printStackTrace();
}
//Log.i("ok", response.body().string());
}
});
My function call in activity class
Helper helper = new Helper();
helper.getLastId();
//I want to get method to return lastId and then manipulate with the data
How can I make method return value of the id?
As it is an asynchronous process you won't be able to return a value from the method itself. However, you can use a callback to provide you the value when the asynchronous process has been completed. Below is an example of how you might want to do this.
public interface GetLastIdCallback {
void lastId(String id);
}
You would modify getLastId as follows:
public void getLastId(GetLastIdCallback idCallback) {
...
String last_id = String.valueOf(Integer.parseInt(id)+1);
idCallback.lastId(last_id);
...
}
Your Helper class usage would now look like this:
Helper helper = new Helper();
helper.getLastId(new GetLastIdCallback() {
#Override
public void lastId(String id) {
// Do something with your id
}
});
I'd suggest making your callback a bit more generic than I have suggested above. It could look like this:
public interface GenericCallback<T> {
void onValue(T value);
}
...
Helper helper = new Helper();
helper.getLastId(new GenericCallback<String>() {
#Override
public void onValue(String value) {
// Do something
}
});
If you used an interface like above you would be able to work with any return type.
Create a interface.
public interface Result{
void getResult(String id);
}
Now, pass interface to method as parameter.
Helper helper = new Helper();
helper.getLastId(new Result(){
#Override
void getResult(String id){
}
});
And In your method :
public void getLastId(final Result result)
{
//init OkHttpClient
OkHttpClient client = new OkHttpClient();
//backend url
Request request = new Request.Builder()
.url("http://192.168.1.102:8080/aquabackend/public/customers/lastid")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String jsonData = response.body().string();
try {
JSONObject jobject = new JSONObject(jsonData);
String id = jobject.getString("id");
//increment current id +1
String last_id = String.valueOf(Integer.parseInt(id)+1);
Log.i("new id", last_id);
result.getResult(last_id);
} catch (Exception e) {
e.printStackTrace();
}
//Log.i("ok", response.body().string());
}
});
You have to create interface for it.
public interface getResponse {
void getJsonResponse(final String id);
}
In Your code :
public void getLastId(fianl getResponse response)
{
//init OkHttpClient
OkHttpClient client = new OkHttpClient();
//backend url
Request request = new Request.Builder()
.url("http://192.168.1.102:8080/aquabackend/public/customers/lastid")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String jsonData = response.body().string();
try {
JSONObject jobject = new JSONObject(jsonData);
String id = jobject.getString("id");
//increment current id +1
String last_id = String.valueOf(Integer.parseInt(id)+1);
Log.i("new id", last_id);
if(response!=null){
response.getJsonResponse(last_id)
}
} catch (Exception e) {
e.printStackTrace();
}
//Log.i("ok", response.body().string());
}
});
In Activity :
public class HomeActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Helper helper = new Helper();
helper.getLastId(new getResponse(){
#Override
void getJsonResponse(String id){
}
});
}}
}

android.os.NetworkOnMainThreadException with OkHttpClient [duplicate]

I want to use OkHttp library for networking in Android.
I started with the simple post example as written in their website:
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
With this call:
String response = post("http://www.roundsapp.com/post", json);
This call ends with NetworkOnMainThreadException.
I could wrap the call with an AsyncTask, but as far as I understand from the examples, the OkHttp library should have already taken care of that..
Am I doing something wrong?
You should use OkHttp's async method.
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
Call post(String url, String json, Callback callback) {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(callback);
return call;
}
And then your response would be handled in the callback (OkHttp 2.x):
post("http://www.roundsapp.com/post", json, new Callback() {
#Override
public void onFailure(Request request, Throwable throwable) {
// Something went wrong
}
#Override public void onResponse(Response response) throws IOException {
if (response.isSuccessful()) {
String responseStr = response.body().string();
// Do what you want to do with the response.
} else {
// Request not successful
}
}
});
Or OkHttp 3.x/4.x:
post("http://www.roundsapp.com/post", "", new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// Something went wrong
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseStr = response.body().string();
// Do what you want to do with the response.
} else {
// Request not successful
}
}
});
Take a look at their recipes for more examples: http://square.github.io/okhttp/recipes/
According to the OkHttp docs:
It supports both synchronous blocking calls and async calls with callbacks.
Your example is on main thread and Android since version 3.0 throws that exception if you try to do network calls on main thread
Better option is to use it together with retrofit and Gson:
http://square.github.io/retrofit/
https://code.google.com/p/google-gson/
Here are the examples:
http://engineering.meetme.com/2014/03/best-practices-for-consuming-apis-on-android/
http://heriman.net/?p=5
If you follows these steps to implement OKHTTP, then definitely you'll call multiple API on multiple screen by applying only two lines of code
UpdateListener updateListener = new UpdateListener(HitAPIActivity.this, baseHTTPRequest);
updateListener.getJsonData();
Step 1:
baseHTTPRequest = new BaseHTTPRequest();
// baseHTTPRequest.setURL("https://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demohttps://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo");
baseHTTPRequest.setURL("http://jsonparsing.parseapp.com/jsonData/moviesDemoItem.txt");
baseHTTPRequest.setRequestCode(reqType);
baseHTTPRequest.setCachedRequired(true);
UpdateListener updateListener = new UpdateListener(HitAPIActivity.this, baseHTTPRequest);
updateListener.executeRequest();
Step 2 : Create a request class
/**
* Created by Deepak Sharma on 4/7/16.
* This is a HTTP request class which has the basic parameters.
* If you wants to add some more parameters, please make a subclass of that class
* and add with your subclass. Don't modify this class.
*/
public class BaseHTTPRequest<T> {
private Context context;
private String URL;
private int requestCode;
private List<T> listParameters;
private String header;
private boolean isCachedRequired;
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public void setURL(String URL) {
this.URL = URL;
}
public String getURL() {
return URL;
}
public int getRequestCode() {
return requestCode;
}
public void setRequestCode(int requestCode) {
this.requestCode = requestCode;
}
public List<T> getListParameters() {
return listParameters;
}
public void setListParameters(List<T> listParameters) {
this.listParameters = listParameters;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public boolean isCachedRequired() {
return isCachedRequired;
}
public void setCachedRequired(boolean cachedRequired) {
isCachedRequired = cachedRequired;
}
}
step 4 : Create a listener class
import android.util.Log;
import com.google.gson.Gson;
import java.io.IOException;
import dxswifi_direct.com.wifidirectcommunication.base.model.request.BaseHTTPRequest;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Callback;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by Deepak Sharma on 4/7/16.
* #email : dpsharma.sharma1#gmail.com
* This is a Simple java class which will help you for HTTP request/response and it will
* throw the response to your correspondance activity.
*/
public class UpdateListener {
private OnUpdateViewListener onUpdateViewListener;
OkHttpClient okHttpClient = new OkHttpClient();
BaseHTTPRequest mRequestModel;
private String mURL = null;
private Request mRequest = null;
public interface OnUpdateViewListener {
void updateView(String responseString, boolean isSuccess,int reqType);
}
public UpdateListener(OnUpdateViewListener onUpdateView, final BaseHTTPRequest requestModel) {
this.mRequestModel = requestModel;
this.onUpdateViewListener = onUpdateView;
if (requestModel.isCachedRequired())
{
/*File httpCacheDirectory = new File(requestModel.getContext().getCacheDir(), "responses");
Cache cache = null;
cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
if (cache != null) {
okHttpClient.setCache(cache);
}*/
}
/*mURL = null;
if (requestModel.getListParameters()!=null && requestModel.getListParameters().size()>0)
{
HttpUrl.Builder urlBuilder = HttpUrl.parse(requestModel.getURL()).newBuilder();
List<RequestParameter> requestParameters = requestModel.getListParameters();
for (int i=0; i<requestParameters.size();i++)
{
urlBuilder.addQueryParameter(requestParameters.get(i).getKey(),requestParameters.get(i).getValue());
}
mURL = urlBuilder.build().toString();
}
else
{
mURL = requestModel.getURL();
}*/
mURL = requestModel.getURL();
if (mRequestModel.getListParameters()!=null && mRequestModel.getListParameters().size()>1)
{
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
mRequest = new Request.Builder()
.url(mURL)
.post(RequestBody.create(JSON, new Gson().toJson(BaseHTTPRequest.class)))
.build();
}
else
{
mRequest = new Request.Builder()
.url(mURL)
.build();
}
}
public void executeRequest()
{
Call call = okHttpClient.newCall(mRequest);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
onUpdateViewListener.updateView(NetworkException.getErrorMessage(e), false, mRequestModel.getRequestCode());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
// You can also throw your own custom exception
throw new IOException("Unexpected code " + response);
} else {
Log.i("Response:",response.toString());
Log.i("Response body:",response.body().toString());
Log.i("Response message:",response.message());
onUpdateViewListener.updateView(response.body().string(),true, mRequestModel.getRequestCode());
}
// do something wih the result
}
});
}
}
step 5 : From the activity you requesting, implement listener
public class HitAPIActivity extends AppCompatActivity implements View.OnClickListener, UpdateListener.OnUpdateViewListener{
#Override
public void updateView(final String responseString, boolean isSuccess, int reqType) {
if (isSuccess)
{
if (!responseString.contains("failure")
&& !responseString.contains("Error")) {
// Handle request on the basis of Request Type.
switch (reqType) {
case ApiConstants.GET_CONTACTS:
break;
default:
break;
}
}
}
}

OkHttp trigger callback in originated class after finishing network actions

Here is the scenario: I have an Activity, named MainActivity, calling a OkHttp wrapper class, named NetworkManager to perform network post in background:
// In MainActivity
NetworkManager manager = new NetworkManager();
try {
manager.post("http://www.example.com/api/", reqObj); // reqObj is a JSONObject
} catch(IOException ioe) {
Log.e(TAG, ioe.getMessage());
}
Then, in the NetworkManager, I perform the POST action in asynchronous mode:
public class NetworkManager {
static String TAG = "NetworkManager";
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
void post(String url, JSONObject json) throws IOException {
//RequestBody body = RequestBody.create(JSON, json);
try {
JSONArray array = json.getJSONArray("d");
RequestBody body = new FormEncodingBuilder()
.add("m", json.getString("m"))
.add("d", array.toString())
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
// Asynchronous Mode
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
Log.e(TAG, e.toString());
// what should I put here?
}
#Override
public void onResponse(Response response) throws IOException {
Log.w(TAG, response.body().string());
// what should I put here?
}
});
} catch (JSONException jsone) {
Log.e(TAG, jsone.getMessage());
}
}
}
What I'm trying to achieve is to call a function in MainActivity after network POST is successful or failed. How can I achieve this?
You can create an interface with onFailure and onResponse then let YourActivity implement it. And, on NetworkManagertry to notify YourActivity using listener.
// MainActivity implements NetworkListener
NetworkManager manager = new NetworkManager();
manager.setOnNetWorkListener(this);
try {
manager.post("http://www.example.com/api/", reqObj); // reqObj is a JSONObject
} catch(IOException ioe) {
Log.e(TAG, ioe.getMessage());
}
void onFailure(Request request, IOException e) {
// call your activity methods
}
void onResponse(Response response) {
// call your activity methods
}
// ======NetworkManager class============
public class NetworkManager {
static String TAG = "NetworkManager";
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
public NetworkListenerv listener;
public void setOnNetWorkListener(NetworkListener listener) {
this.listener = listener
}
// Asynchronous Mode
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
Log.e(TAG, e.toString());
// what should I put here?
if (listener != null) {
listener.onFailure(request, e);
}
}
#Override
public void onResponse(Response response) throws IOException {
Log.w(TAG, response.body().string());
// what should I put here?
if (listener != null) {
listener.onResponse(response);
}
}
});
// Your interface;
public interface NetworkListener {
void onFailure(Request request, IOException e);
void onResponse(Response response);
}

DOwnload base64 image on a protected site using Picasso

I tried to use this Android Picasso library, How to add authentication headers? to access a protected image that returns the base64 version of the image. My problem is that the picasso always failed. and I don't know why. the authorization code is valid since the profile details are loaded. only the image was not. Here is my implementation how to get the image.
public class PicaAuth {
private static Picasso sPicasso;
private PicaAuth() {
}
public static Picasso getImageLoader(final Context context) {
if (sPicasso == null) {
Picasso.Builder builder = new Picasso.Builder(context);
builder.downloader(new CustomOkHttpDownloader(context));
sPicasso = builder.build();
}
return sPicasso;
}
private static class CustomOkHttpDownloader extends OkHttpDownloader {
public CustomOkHttpDownloader(Context context) {
super(context);
}
#Override
protected HttpURLConnection openConnection(final Uri uri) throws IOException {
HttpURLConnection connection = super.openConnection(uri);
connection.setRequestProperty("Authorization", Auth.getBearerAccessToken());
return connection;
}
}
}
Main Activity
PicaAuth.getImageLoader(MainActivity.this)
.load(uri)
.into(mImage, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
Log.d("Image Success");
}
#Override
public void onError() {
Log.e("Image Failed");
}
});
You need to intercept the answer and change it
OkHttpClient client;
OkHttpClient.Builder builderOkHttpClient;
builderOkHttpClient = new OkHttpClient.Builder();
builderOkHttpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.build();
Response response = chain.proceed(newRequest);
try {
MediaType contentType = response.body().contentType();
String base64String = response.body().string().getBytes("UTF-8");
base64String = base64String .replace("data:image/jpeg;base64,", "");
byte[] decodedString = Base64.decode(base64String , Base64.DEFAULT);
ResponseBody body = ResponseBody.create(contentType, decodedString);
response = response.newBuilder().body(body).build();
} catch (JSONException e) {
e.printStackTrace();
}
return response;
}
});
int cacheSize = 10 * 1024 * 1024;
Cache cache = new Cache(context.getCacheDir(), cacheSize);
builderOkHttpClient.cache(cache);
client = builderOkHttpClient.build();
Application.getAppComponent().inject(this);
picasso = new Picasso.Builder(context)
.downloader(new OkHttp3Downloader(client))
.loggingEnabled(true)
.indicatorsEnabled(true)
.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
Log.e("PICASSO", "loading image " + uri);
Log.e("PICASSO ERROR", exception.getMessage());
}
}
).build();
Above answer works great. Then if the base 64 encoded image is further stored inside a JSON Object.
String jsonData = response.body().string();
JSONObject Jobject = new JSONObject(jsonData);
String base64String = (String) Jobject.get("ImageData");

Categories

Resources