Fresco Image Viewer doesn't show photo - android

I'm using fresco image viewer on my app for showing post photos when clicked make it full screen. It was working last week, i didn't changed anything in my code but now it doesn't work.
Here is my showFullScreen function
public void showFullScreenImage(final Context activity, final String imageURL) {
Handler handler = new Handler(activity.getMainLooper());
handler.post(new Runnable() {
public void run() {
try {
List<String> pictures = new ArrayList<>();
pictures.add(imageURL);
GenericDraweeHierarchyBuilder hierarchyBuilder = GenericDraweeHierarchyBuilder.newInstance(mContext.getResources())
.setFailureImage(R.drawable.error)
.setProgressBarImage(new ProgressBarDrawable());
new ImageViewer.Builder<>(activity, pictures).setCustomDraweeHierarchyBuilder(hierarchyBuilder).setStartPosition(0).show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
It shows black screen, but it's not freezing, i can swipe to dismiss the view.

Okay I found the solution, upgrade all repos the final update from build.gradle fresco and frescoImageViwer than it'll be work.

Related

Image not found /Documents/Image:XXXX

I'm selecting an image from the gallery selector after pressing a button, and then filling a RecyclerView with these images. However, it seems the pictures I'm selecting cannot be found...
To open the gallery selector I do:
ActivityResultLauncher<String> GetImageFromGallery = registerForActivityResult(new ActivityResultContracts.GetContent(),
new ActivityResultCallback<Uri>() {
#Override
public void onActivityResult(#Nullable Uri uri) {
if (uri != null) {
ArrayList<String> temp = new ArrayList<>(0);
temp.add(uri.getPath());
img_data.add(temp);
mAdapter.notifyDataSetChanged();
}
}
});
// Button
Button btn_add = root.findViewById(R.id.btn_add_image);
btn_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GetImageFromGallery.launch("image/*");
}
});
where img_data is an `ArrayList<ArrayList> and mAdapter is the adapter of a RecyclerView. Inside the RecyclerView I'm reading the images to show in an ImageViewer as follows:
try {
viewHolder.getphoto().setImageBitmap(BitmapFactory.decodeStream(viewHolder.getphoto().getContext().getApplicationContext().getContentResolver().openInputStream(Uri.parse(localDataSet.get(position).get(0)))));
//Or viewHolder.getphoto().setImageBitmap(BitmapFactory.decodeFile(localDataSet.get(position).get(0)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
However, none of above works. I'm getting stuck with a not found file error. Path are always of style /Documents/Image:XXXX where X are numbers. What am I doing wrong?
Following the code in my question, use this to add the uri as a String:
temp.add(uri.toString());
and this to load the image:
viewHolder.getphoto().setImageURI(Uri.parse(localDataSet.get(position).get(0)));
Although if possible use Glide to load the image. Without Glide was extremely slow, but with it it wasn't. To add glide add the following dependencies intro build.gradle module:
implementation 'com.github.bumptech.glide:glide:4.12.0'
// Glide v4 uses this new annotation processor -- see https://bumptech.github.io/glide/doc/generatedapi.html
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
and then to load the picture:
Glide.with(viewHolder.getphoto().getContext())
.load(Uri.parse(localDataSet.get(position).get(0)))
.into(viewHolder.getphoto());

Why Textview is not updating data everytime?

I'm trying to get text from db then update text in my textView of recyclerView adapter class . Although I'm getting text from db without any problem but my textview is not updating text everytime . Sometimes it's updating and sometimes it's not I wonder what's the problem . I tried to refer a lot of SO questions but none of them could solve my issue . I even tried to use textView.invalidate() but it was of no use . Could anyone please help me to solve this issue.
Code:
#Override
public void onBindViewHolder( CustomRecyclerViewHolder holder, int position) {
JSONObject ov=new JSONObject();
try {
ov.put("prof_email",timelineData.getEmail());
socket.disconnect();
socket.connect();
socket.emit("data",ov);
socket.on("name_full", new Emitter.Listener() {
#Override
public void call(Object... args) {
final JSONObject ob = (JSONObject)args[0];
try {
final String st = ob.getString("fullname");
Needle.onMainThread().execute(new Runnable() {
#Override
public void run() {
if (st.length() > 0) {
//I'm toasting just to test that text is alright or not but it's alright
Toast.makeText(context,st,Toast.LENGTH_SHORT).show();
holder.userName.invalidate();//here not useful
holder.userName.setText(st);
holder.userName.invalidate();//even here also not useful
socket.disconnect();
}
}
});
}catch (Exception e){
e.printStackTrace();
}
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
OnBindViewHolder will be called every time when user scroll the recyclerview.
So corresponding to your source code, socket connection and disconnection is done many times when user scroll the list. (This seems not a good way)
So I recommend to remove socket related code from onBindViewHolder.
After that just listening to the socket. When data changed, replace old data with new one from your collection and call Adapter#notifyDatasetChanged().

FirebaseUI RecyclerView random items added to listitems

When a button is pressed, a dialog appears asking user for message, with the option of attaching an image (from url). The problem I'm having is once the recyclerview is filled with enough items to scroll, when the user scrolls quickly for some reason random images start popping up in seemingly random list items.
I know the problem has to come from when the image is actually placed into the imageview, since I can tell the link is added to the firebase db just fine.
When the image link is submitted, it's sent to /posts/$uid/$post-id in a HashMap. Kind of like this:
final Map<String, String> postMap = new HashMap<String, String>();
imagebutton.setOnClickListener((view) -> {
AlertDialog.Builder = new...
LayoutInflater in = ...
View dialogLayout = ...inflate(r.layout...., null);
build.setView(dialogLayout);
EditText imgText = ...
Button submit = ...
AlertDialog a = build.create();
submit.setOnClickListener((View) -> {
...
postMap.put("imgLink", imgText.getText().toString());
a.dismiss();
...
urlDialog.show();
Then a few more items are added to the map and pushed to firebase.
Firebase postRef = ref.child("posts").child(auth.getUid());
postMap.put("author", ...);
postMap.put("content", ...);
postRef.push().setValue(postMap);
But like I said, I'm almost 100% sure the problem is not in posting the information, just populating the recview
Here's my code for the list itself:
RecyclerView feed = (RecyclerView)findViewById(R.id.recycler);
if (ref.getAuth() != null) {
FirebaseRecyclerAdapter<TextPost, PostViewHolder> adapter = new FirebaseRecyclerAdapter<TextPost, PostViewHolder>(TextPost.class, R.layout.list_item, PostViewHolder.class, ref.child("posts").child(uid)) {
#Override
protected void populateViewHolder(final PostViewHolder postViewHolder, final TextPost textPost, int i) {
postViewHolder.content.setText(textPost.getContent());
postViewHolder.author.setText(textPost.getAuthor());
postViewHolder.score.setText(textPost.getScore());
postViewHolder.time.setText(textPost.getTime());
if (textPost.getImgLink() != null && !textPost.getImgLink().equals("")) {
Log.i(TAG, "Setting image");
new Thread(new Runnable() {
#Override
public void run() {
try {
final Bitmap pic = bitmapFromUrl(textPost.getImgLink());
postViewHolder.img.post(new Runnable() {
#Override
public void run() {
postViewHolder.img.setImageBitmap(pic);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
...
feed.setAdapter(adapter);
I just started learning how to work with worker threads for network activities off the main UI thread so I assume I messed that up? I've gone through the logic over and over in my head and i can't seem to figure out what's going wrong here.
EDIT: I tried using AsyncTask instead of Threads and the problem persists. sos
All I had to do was set the ImageView drawable to null before populating the ImageView.
Like this:
#Override
protected void populateViewHolder(final ViewHolder v, final Object o, int i) {
//populate views
v.content.setText("...");
//Set imageview to null
v.imageview.setImageDrawable(null);*
if (o.getImageLink() != null && !o.getImageLink.equals("")) {
// Start AsyncTask to get image from link and populate imageview
new DownloadImageTask().execute(o.getImgLink(), v.imageview);
}
}

How to present a ProgressDialog while onPictureTaken() is saving image data?

In the setup part of my app, I want to take a picture then display it. I want to display a Progress Dialog while saving the image to disk. My ProgressDialog code works except on a Droid Mini running KitKat.
I have tried a number of approaches, including this blog https://www.workreloaded.com/2011/06/how-to-use-the-android-camera/. I liked the approach but the ProgressDialog did not appear for me.
I think the root of the problem is some timing issue using the UI thread. But I can't precisely diagnose it and definitely can't solve it. My questions:
1. Does camera.takePicture() run on the UI thread?
2. What would prevent a ProgressDialog from appearing?
3. Does someone have a working example (besides the above post) that I could use?
I'm posting code that works but is bad practice and code that doesn't work but would be more maintainable.
The following code with a test for KitKat works, but is bad practice.
public class PreviewTestNextButtonListener implements Button.OnClickListener {
private static final String TAG = "PreviewTestButtonListener";
PreviewTest previewTest;
Camera camera;
public PreviewTestNextButtonListener(PreviewTest context, Camera camera) {
this.previewTest = context;
this.camera = camera;
}
public void onClick(View v) {
Log.v(TAG, "Taking picture");
try {
PhotoSaverPreviewTest photoSaver = new PhotoSaverPreviewTest(previewTest);
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.KITKAT) {
// don't display the progress dialog in kit kat because my Droid Mini running KitKat has a problem with
// this. But the Mini is so fast that the save is instantaneous
previewTest.showProgressDialog();
}
// photoSaver will launch the StoredRotationTest
camera.takePicture(null, null, photoSaver);
} catch (Exception e) {
Log.e(TAG, "failed to start Stored Rotation Test because " + e, e);
}
}
}
In an alternative version, I tried simply calling the ProgressDialog from takePicture() but that doesn't work. I also tried an AsyncTask, but that did not present a ProgressDialog either.
public void onPictureTaken(final byte[] imageData, Camera camera) {
Log.e(TAG, "starting onPictureTaken");
// **** this does not present the ProgressDialog
activity.showProgressDialog();
if (imageData != null) {
Log.e(TAG, "got image data");
camera.startPreview();
Display display = ((android.view.WindowManager) activity.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
int displayRotation = display.getRotation();
try {
// showProgressDialog();
// save the image to disk in the background
RotateAndWriteImageAsync imageWrite = new RotateAndWriteImageAsync(activity, displayRotation, imageData);
imageWrite.mySpecialMove();
Intent intent;
// during set up, launch the stored image rotation test
intent = new Intent(activity, StoredRotationTest.class);
activity.startActivity(intent);
PreviewTest.dismissProgressDialog();
} catch (Exception e) {
Log.e(TAG, "error saving image or start rotation test: " + e);
}
} else {
Log.e(TAG, " ");
Log.e(TAG, "NO IMAGE DATA passed in parameter from camera");
Log.e(TAG, " ");
}
}
And finally, the method that presents the ProgressDialog from the PreviewTest Activity.
/** Called by Next Button which is a bit of kludge.*/
public void showProgressDialog() {
if (progress == null) {
progress = new ProgressDialog(this);
progress.setTitle("Saving picture");
}
progress.show();
}
/** Called by StoredRotationSetup which is a bit of a kludge.*/
public static void dismissProgressDialog() {
if (progress != null && progress.isShowing()) {
progress.dismiss();
}
}
Mark Murphy(aka Commonsware) gave me some guidance during his office hours. ProgressDialogs are bad form: https://ux.stackexchange.com/questions/12637/what-research-is-there-suggesting-modal-dialogs-are-disruptive. My ProgressBar only shows when the user is waiting, but it does not pop up.
ProgressBar solved my problem. Here is the .xml:
<ProgressBar
android:id="#+id/next_progress_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/rotate_orientation_button"
style="#android:style/Widget.ProgressBar.Large"
android:indeterminate="true"
android:visibility="invisible" />
And the Java:
// progress bar
ProgressBar progressBar = (ProgressBar) findViewById(R.id.next_progress_bar);
progressBar.setVisibility(View.VISIBLE);

Android:More efficient solution to fetch images from internet at runtime and show in listview

Scenario: A bit tricky but interesting.
I have sent a request that will give me a JSON response. This response will further contain, say 10, JSON request URLs.
I will then send request to these 10 Urls and each URL will then contain 2 image URLs. That means 20 images in total.
My intentions are to show these images in a ListView as fast as possible to the user.
This is what I've done till now:
Step 1: As soon as the activity starts, pop a ProgressDialog showing loading circle as in youtube.
Step 2: IN AN ASYNC TASK, Send the first request that give URLs of those 10 JSON requests. Send this request then parse & store these 10 URLs present is response.
Step 3: Starting from first(out of 10), send the request that will give the JSON response.
Step 4: Parse this response to fetch the 2 image URLs and store in LinkedList.
Step 5: As we have the actual link of the image now, dismiss the progress dialog and fetch the image.
Step 6: This image will be stored in drawable. I've made a custom BaseAdapter called ImageAdapter that has ArrayList<Drawable> mImages;
Step 7: Store the received drawable in this ArrayList, using: adapter.mImages.add(drawable);
Step 8: Then call adapter.notifyDataSetChanged(); This will update the listview as soon the image is ready to be displayed.
Step 9: Back to step 3 to process further URLs.
Below is the code (striped all the unnecessary code):
ActivityClass
public class ImageViewer extends Activity {
GridView gvImage;
private ProgressDialog progressDialog;
private final static Integer IMAGE_LIMIT = 10;
private ImageAdapter adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.ImageViewer);
gvImage = (GridView) findViewById(R.id.gvImage);
adapter = new ImageAdapter(this);
gvImage.setAdapter(adapter);
progressDialog = ProgressDialog.show(ImageViewer.this, "In Progress",
"Loading...", true, true, new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
finish();
}
});
new SendRequest().execute(null);
} catch (Exception e) {
}
}
class SendRequest extends AsyncTask {
protected Object doInBackground(Object... params) {
try {
HttpClient client = new DefaultHttpClient(httpParameters);
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(BaseRequest_URL);
JSONObject jsonResponse = null;
HttpResponse httpResponse = client.execute(httpGet, localContext);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
jsonResponse = getJSONObjectFromEntity(entity); //getJSONObjectFromEntity() will return JSONObject
processJSON(jsonResponse);
}
progressDialog.dismiss();
} catch (Exception e) {
}
return null;
}
private void processJSON(JSONObject jsonResponse) throws JSONException {
for (int i = 0; i < IMAGE_LIMIT; i++) {
// Some JSON parsing. Output will be 'imageURL' which will be image URL
displayImage(imageURL);
}
}
public void displayImage(String uri150) {
try {
InputStream is = (InputStream) new URL(uri150).getContent();
if(progressDialog.isShowing()){
progressDialog.dismiss();
}
Drawable d = Drawable.createFromStream(is, "image 150");
adapter.mImages.add(d);
handler.sendEmptyMessage(0); // Handler Below
} catch (Exception e) {
}
}
protected void onPostExecute(Object result) {
super.onPostExecute(result);
}
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
adapter.notifyDataSetChanged();
};
};
}
ImageAdapter Class:
public class ImageAdapter extends BaseAdapter {
Context context;
public ArrayList<Drawable> mImages = new ArrayList<Drawable>();
public ImageAdapter(Context c) {
this.context = c;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(context);
try {
imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageDrawable(mImages.get(position));
imageView.setTag("Image" + position);
} catch (Exception e) {
}
return imageView;
}
}
Questions:
The way I see it ImageAdapter is called several times. Is there any other way to reduce it.
How can I optimize the code of ImageAdapter.
Any other improvement?
(the first 2 questions) Adapter doesn't only control which row (view in the list) appears, it also recycles it. In your Adapter, getView creates a new view every time it is called, when it should only create a new one if the old one is not available. Check out Mark Murphy (commonsware)'s adapter here.
In your code, all the images are downloaded during progress dialog. Your user will probably not see them all to the last one and it will definitely burden your memory. I suggest you lazy load both JSON and images (request your JSON, parse it, load the image one-by-one asynchronously depending on how much of the grid your users see/scroll). There have been a lot of discussions regarding image lazy loading and you should definitely start from Fedor's answer.
What I can tell you for sure it is WRONG to store your images in memory, as you can get OutOfMemoryException.
To learn how to work with images and cache visit Displaying Bitmaps Efficiently
Try this library. It is really good for layz loading.
just search for Android LazyImageLoading
Good Luck

Categories

Resources