I'm trying to set wallpaper by downloading an image from internet but it's showing that "get()method" is not found.
My Code:
In this code wall_set is a button's name
wall_set.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap result=Glide.with(getApplicationContext())
.load("http://www.sport-stickers.com/images/2013/CARTOON%20IRON%20ONS/Doraemon/Doraemon%20Iron%20ons%20(Wall%20Stickers)%20N3715.jpg").get();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(result);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
);
change this part of your code:
Bitmap result=Glide.with(getApplicationContext())
.load("http://www.sport-stickers.com/images/2013/CARTOON%20IRON%20ONS/Doraemon/Doraemon%20Iron%20ons%20(Wall%20Stickers)%20N3715.jpg").asBitmap().get();
add "asBitmap"
you might need to add
asBitmap().into(20, 20). // Width and height
in the following
If you follow Glide sample usage it comes up with that get() method belongs to java.util.concurrent.Future object. And Future class definition is given by the official doc as below.
public interface Future<V> A Future represents the result of an
asynchronous computation. Methods are provided to check if the
computation is complete, to wait for its completion, and to retrieve
the result of the computation. The result can only be retrieved using
method get when the computation has completed, blocking if necessary
until it is ready. Cancellation is performed by the cancel method.
Additional methods are provided to determine if the task completed
normally or was cancelled. Once a computation has completed, the
computation cannot be cancelled. If you would like to use a Future for
the sake of cancellability but not provide a usable result, you can
declare types of the form Future and return null as a result of the
underlying task.
Sample Usage (Note that the following classes are all made-up.)
interface ArchiveSearcher { String search(String target); }
class App {
ExecutorService executor = ...
ArchiveSearcher searcher = ...
void showSearch(final String target)
throws InterruptedException {
Future<String> future
= executor.submit(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
displayOtherThings(); // do other things while searching
try {
displayText(future.get()); // use future
} catch (ExecutionException ex) { cleanup(); return; }
}
}
Lets see what happens step by step:
Bitmap theBitmap = Glide.
with(this). //in Glide class and returns RequestManager
load(image_url). // in RequestManager and returns RequestBuilder<Drawable>
asBitmap(). //in RequestBuilder and returns RequestBuilder<Bitmap>
submit(). // in RequestBuilder and returns FutureTarget<TranscodeType> which extends Future<>
get(); // this belongs to Future object which is the result of async computation
public static RequestManager with(Context context) {
return getRetriever(context).get(context);
}
public RequestBuilder<Drawable> load(#Nullable Object model) {
return asDrawable().load(model);
}
public RequestBuilder<Bitmap> asBitmap() {
return as(Bitmap.class).transition(new GenericTransitionOptions<Bitmap>())
.apply(DECODE_TYPE_BITMAP);
}
public FutureTarget<TranscodeType> submit() {
return submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
}
public interface FutureTarget<R> extends Future<R>, Target<R> {
}
But more proper and secure solution is by using callback
Glide
.with(this)
.load(image_url)
.asBitmap()
.into(new SimpleTarget<Bitmap>(100,100) {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
//resource is the resulting bitmap
}
});
Related
I'm developing an Android App using Fernando Ceja's clean architecture. One of my Interactors or Use Cases is in charge of getting the User's feed data. In order to get the data, first I have to retrieve the User's Teams from a database table and then I have to get the Feed list from the server-side.
This is how I get the Teams from the database layer:
mTeamCache.getAllTeams().subscribe(new DefaultSubscriber<List<SimpleTeam>>() {
#Override
public void onNext(List<SimpleTeam> simpleTeams) {
super.onNext(simpleTeams);
mTeams = simpleTeams;
}
});
TeamCache is basically just another Interactor that takes care of getting all the teams that I have in the database.
Here's how I get the Feed data from the server-side:
mFeedRepository.getFeed(0, 50).subscribe(new ServerSubscriber<List<ApiFeedResponse>>() {
#Override
protected void onServerSideError(Throwable errorResponse) {
callback.onFeedFetchFailed(...);
}
#Override
protected void onSuccess(List<ApiFeedResponse> responseBody) {
//Do stuff with mTeams
callback.onFeedFetched(...);
}
});
My GetFeedInteractor class has a method called execute, where I pass through the Callback that I'm later using in the UI to handle the response. The issue with all this is that currently I'm chaining the responses like this:
#Override
public void execute(final Callback callback, String userSipId) {
mTeamCache.getAllTeams().subscribe(new DefaultSubscriber<List<SimpleTeam>>() {
#Override
public void onNext(List<SimpleTeam> simpleTeams) {
super.onNext(simpleTeams);
mTeams = simpleTeams;
getFeedFromRepository(callback);
}
});
}
public void getFeedFromRepository(final Callback callback) {
mFeedRepository.getFeedRx(0, 50).subscribe(new ServerSubscriber<List<ApiFeedResponse>>() {
#Override
protected void onServerSideError(Throwable errorResponse) {
callback.onFeedFetchFailed("failed");
}
#Override
protected void onSuccess(List<ApiFeedResponse> responseBody) {
//Do stuff with mTeams
List<BaseFeedItem> responseList = new ArrayList();
for (ApiFeedResponse apiFeedResponse : responseBody) {
responseList.add(FeedDataMapper.transform(apiFeedResponse));
}
callback.onFeedFetched(responseList);
}
});
}
As you can see, once that I get the Team collection from the Cache Interactor I call the method that gets the feed from the very same Subscriber. I don't like this. I want to be able to do something nicer, like using Observable.concat(getTeamsFromCache(), getFeedFromRepository()); chain a call to another rx.Observable inside a Subscriber is not something nice to do. I guess that my question is, how can I chain two rx.Observables that are using different Subscribers?
Update:
ServerSubscriber is a subscriber that I implemted to subscribe to Retrofit services. It simply checks the error codes and some stuff. Here is:
https://gist.github.com/4gus71n/65dc94de4ca01fb221a079b68c0570b5
Default subscriber is an empty default subscriber. Here is:
https://gist.github.com/4gus71n/df501928fc5d24c2c6ed7740a6520330
TeamCache#getAllTeams() returns rx.Observable>
FeedRepository#getFeed(int page, int offset) returns rx.Observable>
Update 2:
This is how the Interactor to get the User's feed looks like now:
#Override
public void execute(final Callback callback, int offset, int pageSize) {
User user = mGetLoggedUser.get();
String userSipid = mUserSipid.get();
mFeedRepository.getFeed(offset, pageSize) //Get items from the server-side
.onErrorResumeNext(mFeedCache.getFeed(userSipid)) //If something goes wrong take it from cache
.mergeWith(mPendingPostCache.getAllPendingPostsAsFeedItems(user)) //Merge the response with the pending posts
.subscribe(new DefaultSubscriber<List<BaseFeedItem>>() {
#Override
public void onNext(List<BaseFeedItem> baseFeedItems) {
callback.onFeedFetched(baseFeedItems);
}
#Override
public void onError(Throwable e) {
if (e instanceof ServerSideException) {
//Handle the http error
} else if (e instanceof DBException) {
//Handle the database cache error
} else {
//Handle generic error
}
}
});
}
I think you're missing the point of RxJava and reactive approach, you should not have different subscribers with OO hierarchy, and callbacks.
You should construct separated Observables that should emit the specific data it's handle, without the Subscriber, then you can chain you're Observable as needed, and at the end, you have the subscriber that react to the final result expected from the chained Observable stream.
something like this (using lambdas to have more thin code):
TeamCache mTeamCache = new TeamCache();
FeedRepository mFeedRepository = new FeedRepository();
Observable.zip(teamsObservable, feedObservable, Pair::new)
.subscribe(resultPair -> {
//Do stuff with mTeams
List<BaseFeedItem> responseList = new ArrayList();
for (ApiFeedResponse apiFeedResponse : resultPair.second) {
responseList.add(FeedDataMapper.transform(apiFeedResponse));
}
}, throwable -> {
//handle errors
}
);
I've use zip and not concat as it's seems you have 2 independent calls here that you want to wait for both to finish ('zip' them together) and then act upon, but ofcourse, as you have separated Observables stream, you can chain them together differently according to your needs.
as for your ServerSubscriber with all the response validation logic, it should be rxify too, so you can compose it along your server Observable stream.
something like this (some logic emitted to simplify, and as I'm not familiar with it...)
Observable<List<SimpleTeam>> teamsObservable = mTeamCache.getAllTeams();
Observable<List<ApiFeedResponse>> feedObservable = mFeedRepository.getFeed(0, 50)
.flatMap(apiFeedsResponse -> {
if (apiFeedsResponse.code() != 200) {
if (apiFeedsResponse.code() == 304) {
List<ApiFeedResponse> body = apiFeedsResponse.body();
return Observable.just(body);
//onNotModified(o.body());
} else {
return Observable.error(new ServerSideErrorException(apiFeedsResponse));
}
} else {
//onServerSideResponse(o.body());
return Observable.just(apiFeedsResponse.body());
}
});
I want to be able to have Espresso monitor Picasso as an IdlingResource so that I can run ViewMatchers once the image has been successfully loaded.
From navigating through the Picasso source code, I don't see why this isn't working. Here's what I tried:
Picasso picasso = new Picasso.Builder(context).build();
Field dispatcherField = Picasso.class.getDeclaredField("dispatcher");
dispatcherField.setAccessible(true);
try {
Dispatcher dispatcher = (Dispatcher) dispatcherField.get(picasso);
Espresso.registerLooperAsIdlingResource(dispatcher.dispatcherThread.getLooper());
} catch (NoSuchFieldException e) {
throw new PicassoHasBeenRefactoredException();
} catch (Exception e) {
e.printStackTrace();
}
onView(withId(R.id.image_view)).check(matches(withImage(R.drawable.drawable)));
(yes, I know, reflecting is icky, but I couldn't find another way of getting a handle on the Looper)
But it results in this error when trying to get the Bitmap from the ImageView:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Bitmap android.graphics.drawable.BitmapDrawable.getBitmap()' on a null object reference
To check that the test is running as expected once an image has been loaded, I tried introducing a Thread.sleep(1000) in lieu of the IdlingResource check and it passed.
Is it safe to assume that the IdlingResource hasn't been set up correctly, and, more importantly, what would be the correct way of waiting for Picasso to finish loading before checking views with Espresso?
I'm using an IdlingResource that checks if there are actions left.
Note that the IdlingResource must live in the same package as Picasso to gain access to a package-protected variable
package com.squareup.picasso;
public class PicassoIdlingResource implements IdlingResource, ActivityLifecycleCallback {
protected ResourceCallback callback;
WeakReference<Picasso> picassoWeakReference;
#Override
public String getName() {
return "PicassoIdlingResource";
}
#Override
public boolean isIdleNow() {
if (isIdle()) {
notifyDone();
return true;
} else {
return false;
}
}
public boolean isIdle() {
return picassoWeakReference == null
|| picassoWeakReference.get() == null
|| picassoWeakReference.get().targetToAction.isEmpty();
}
#Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.callback = resourceCallback;
}
void notifyDone() {
if (callback != null) {
callback.onTransitionToIdle();
}
}
#Override
public void onActivityLifecycleChanged(Activity activity, Stage stage) {
switch (stage) {
case CREATED:
picassoWeakReference = new WeakReference<>(Picasso.with(activity));
break;
case STOPPED:
// Clean up reference
picassoWeakReference = null;
break;
default: // NOP
}
}
}
I don't think using WeakReference is needed, but it doesn't hurt either.
Also, I've identified one case where it doesn't wait until Picasso finishes (when using .load(null)). So, use at your own risk and please come back if you improve it.
See gist for full details and usage (https://gist.github.com/Maragues/0c0db81a137c8d067396)
I'm using 'Retrofit' for making asynchronous network requests, how might i right a function for handling logins? For instance i've currently attempted:
public UserAuthResponse Login(String username, String password) {
try {
Callback<UserAuthResponse> getAuthCallback = new Callback<UserAuthResponse>() {
#Override
public void failure(RetrofitError arg0) {
if (arg0 != null) {
if (arg0.getMessage() != null
&& arg0.getMessage().length() > 0) {
Log.e("KFF-Retrofit", arg0.getMessage());
}
}
}
#Override
public void success(UserAuthResponse listItem,
retrofit.client.Response arg1) {
Log.e("dg", listItem.getUser().getFirstname());
}
};
service.authUser(username, MD5(password), getAuthCallback);
return response;
} catch (RetrofitError e) {
e.printStackTrace();
return null;
}
}
But this is flawed: there is no way of returning the 'UserAuthResponse' from the function? How can i pass back the result?
It seems like i need a synchronous call to the web service but then i'm hit with a 'NetworkOnMainThreadException'
What is the best practice for things like this? Sorry about the poor explanation, struggling to form the right words.
Well the things is that when you're using the Callback as your means of getting the results from Retrofit you automatically giving away the possibility of having the response returned inline. There's a few ways this can be solved. I suppose it's up to you to choose which one fits best with your design.
You could decide to not use the Callback approach and use the inline result from Retrofit but then you'd need to handle the scheduling yourself otherwise you'll hit the Exception of NetworkOnMainThreadException like you mentioned.
You could also pass in a listener to your login method. This listener could then be called by the result Callback. This could be useful if you're trying to hide Retrofit behind some sort of service layer and expose a simple login interface.
interface OnLoginListener {
onLoginSuccessful(UserAuthResponse response);
onLoginFailed(Throwable t);
}
public void Login(String username, String password, final OnLoginListener listener) {
Callback<UserAuthResponse> getAuthCallback = new Callback<UserAuthResponse>() {
#Override
public void failure(RetrofitError e) {
// You can handle Retrofit exception or simply pass them down to the listener as is
listener.onLoginFailed(e);
}
#Override
public void success(UserAuthResponse listItem,
retrofit.client.Response arg1) {
// handle successful case here and pass down the data to the listener
listener.onLoginSucessful(listItem);
}
};
service.authUser(username, MD5(password), getAuthCallback);
}
use this line i Manifest
<uses-permission android:name="android.permission.INTERNET"/>
or use this before network operation (not suggestible)
if (Build.VERSION.SDK_INT>= 10) {
ThreadPolicy tp = ThreadPolicy.LAX;
StrictMode.setThreadPolicy(tp);
}
I have an app where I use the library Ion (https://github.com/koush/ion). The problem is I realized that I need to get the http-status when the loading fails.
I have a rest-service returning different status depending on what went wrong, and need to have different logic in the app as well.
This is the code for the rest-service:
#GET
#Path("/damages/image/get")
#Produces("image/jpeg")
#Override
public Response getImage() {
byte[] byteImage;
try {
//Getting the image here
...
} catch (ExceptionTypeA e) {
return Response.status(204).entity(null).build();
} catch (ExceptionTypeB e) {
return Response.status(503).entity(null).build();
}
return Response.ok(image).build();
}
This is the code I use to get an image:
...
Ion.with(imageView)
.error(R.drawable.ic_menu_camera)
.load(imageUrl).setCallback(new FutureCallback<ImageView>() {
#Override
public void onCompleted(Exception ex, ImageView iv) {
//I need to get the HTTP-status here.
}
});
...
I also tried this:
Ion
.with(getApplicationContext())
.load(imageUrl)
.as(new TypeToken<byte[]>(){})
.withResponse()
.setCallback(new FutureCallback<Response<byte[]>>() {
#Override
public void onCompleted(Exception e,
Response<Byte[]> result) {
//I never get here
}
});
With the code above I get the error following exception:
java.lang.NoSuchMethodError: com.koushikdutta.ion.gson.GsonSerializer
Do you have any tips on how I can solve this problem? Another lib or am I just doing it wrong?
SOLUTION:
My solution was to rewrite it with the AndroidAsync library. Here is the code:
AsyncHttpClient.getDefaultInstance().getByteBufferList(imageUrl, new
AsyncHttpClient.DownloadCallback() {
#Override
public void onCompleted(Exception e, AsyncHttpResponse source,
ByteBufferList result) {
int httpStatus = source.getHeaders().getHeaders().getResponseCode();
byte[] byteImage = result.getAllByteArray();
Bitmap bitmapImage = BitmapFactory.decodeByteArray(byteImage, 0,
byteImage.length);
theImageViewIWantToSet.setImageBitmap(bitmapImage);
if(httpStatus == 200) {
//Do something
} else {
//Do something else
}
}
}
});
After you call setCallback(), use .withResponse() to get the result wrapped in a Response future. That response future will let you access headers, response code, etc.
Sample that shows you how to do it with a String result... same concept applies to byte arrays.
https://github.com/koush/ion#viewing-received-headers
Ion.with(getContext())
.load("http://example.com/test.txt")
.asString()
.withResponse()
.setCallback(new FutureCallback<Response<String>>() {
#Override
public void onCompleted(Exception e, Response<String> result) {
// print the response code, ie, 200
System.out.println(result.getHeaders().getResponseCode());
// print the String that was downloaded
System.out.println(result.getResult());
}
});
Note that this is not possible with ImageView loading, as ImageView loading may not hit the network at all, due to cache hits, etc.
As a matter of fact there is an other library for this. I have used THIS for image loading. Its simpler, has a lot of implemented methods. There is a method .showImageOnFail(R.drawable.ic_error) in DisplayImageOptions configuration class. I didn't go trough all of the library, but I guess you can see how the configuration class affects this and how the showImageOnFail function gets called and re-use the same logic to add your own or override some method to get your status. This was initially how I got the idea that this library can help you.
There's no way to do this using that library, or probably any other asynchronous image loading library for that matter. It's not a common use case. You'll have to look into the base library and modify the code to read the status code and return it.
I'm playing around with the Picasso library for image loading, but I'm running into an issue. When an image fails to load, I want to hide the view rather than load in a default image. I noticed from the source that it looks like the only way to add a listener is from the builder, but the error method is never called when an image does fail to load. Anyone have any experience with this?
iv = (ImageView) findViewById(R.id.imageView);
Picasso.Builder builder = new Picasso.Builder(getApplicationContext());
builder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso arg0, String arg1) {
Log.e("Picasso Error", "Errored out, hiding view");
iv.setVisibility(View.GONE);
}
});
Picasso pic = builder.build();
pic.load("thisshouldbreak.jpg").into(iv);
Picasso 2.0 allows you to attach a callback into a request.
https://github.com/square/picasso
The callback you are using is for "global" listener and it helps you debug errors that potentially happen due to a network load.
Use load(url).into(view, new Callback() {...}); in Picasso 2.0.
Remember to invoke cancelRequest(target) if you are using a Callback.
My example:
Picasso picasso = new Picasso.Builder(parent.getContext())
.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
//Here your log
}
})
.build();
picasso.load(shopModel.getShopImg())
.fit()
.into(viewHolder.shopImg);
You can try to add a 'global' listener.
// create Picasso.Builder object
Picasso.Builder picassoBuilder = new Picasso.Builder(this);
picassoBuilder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
Log.e("PICASSO", uri.toString(), exception);
}
});
// Picasso.Builder creates the Picasso object to do the actual requests
Picasso picasso = picassoBuilder.build();
try {
Picasso.setSingletonInstance(picasso);
} catch (IllegalStateException ignored) {
// Picasso instance was already set
// cannot set it after Picasso.with(Context) was already in use
}
Any subsequent calls to Picasso.with(Context context) will return the instance which connected to listener, so all fails will be logged.
Please note that you need to call setSingletonInstance as soon as possible, e.g. in Application onCreate.
P.S. Code adopted from here - Customizing Picasso with Picasso.Builder
My answer:
File file = new File(filePath);
Picasso.with(context).load(file).placeholder(R.drawable.draw_detailed_view_display).error(R.drawable.draw_detailed_view_display)
.resize(400, 400).into(mImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
mImageView.setVisibility(View.GONE);
}
});
When we got error, error goes to onError method then we handle it!
private void getAvatar(){
Picasso.with(this)
.load(Links.GET_AVATAR + ".jpg")
.into(imgUserAvatar, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
imgUserAvatar.setImageResource(R.drawable.icon_profile_default);
}
});
}
Just a suggestion, but you might avoid issues in programming if you make an "empty" png file and set it as the default image file in your res folder... kinda silly i know... but likely to work without fighting...