outofmemory error using bitmaps Android - java

I've created an android app, which chooses a picture from Gallery and displays a preview.
#Override
public void onClick(View v) {
if (v.getId()== R.id.button){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
After the image is selected, the preview should be shown.
Yet, it works only for the first time. And later when I click back, it shows outOfMemoryException

working with bitmaps in android costs you a lot of memory, which needs a hude attention because of memory leaks.
you can always use
System.gc()
to garbage collect and free up some memory.
or
bitmap.recycle();
cheack out these blog post that I used when I developed my image editing app.
Curious-create.org
Evendanan.net

Working with bitmaps in android often throws the OutOfMemory error. Bitmaps need to be handled properly. you might want to look at the following libraries used specifically for image loading and working with bitmaps in android:
https://github.com/nostra13/Android-Universal-Image-Loader
https://github.com/novoda/ImageLoader
You can also implement your own imageloader. You can find the code for that easily.

you are probably caching a lot of bitmaps, so you could use ImageLoader and do something like this:
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
this).memoryCache(new WeakMemoryCache())
.discCache(new UnlimitedDiscCache(new File("/cache"))).build();
also try somehow to release bitmaps after you no longer need them

Related

How do I display a PDF after pushing a button in the Android app I'm making?

I'm currently working on making an Android app, but have been having some trouble. I want to be able to push a button with the title of the document as it's TextView and then have that document open to be read. I've looked around for guides but everything I've found is either out of date or doesn't explain any of the code shown. Does anyone know how I can put such a thing in my app? At this point, I'm not even sure where to start with the process.
Note, I'm working in Java not Kotlin.
UPDATE: I was directed to a solution using intents. Now there seems to be an issue loading the file. My code is this:
public class atotf_pdf extends literature {
File file = new File("/storage/emulated/0/AToTF Preview.pdf");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
Uri pdfURI = FileProvider.getUriForFile(atotf_pdf.this, "net.whispwriting.whispwriting.provider", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(pdfURI, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
Is it something here that's causing the error?
It looks like the file is somehow not being stored in the filesystem when the app is installed.
Just like #ruben said, you could use a WebView for such a task: https://developer.android.com/reference/android/webkit/WebView. For more information about using WebView to display content, you can take a look at this post: How can I display a pdf document into a Webview?
Another potential solution could be using intents, which has also been discussed before: How to open a PDF via Intent from SD card
Hopefully this helps!

Loading Image in Image View using Glide

I am working on an app which show an image which is loaded from my firebase database. I used Glide for that purpose.
I am using a button, on the click of that button a new activity will open which shows the image fetched from the url. The image load perfectly if url loaded correctly but if I cancelled in between, the app is crashing. Why it is happening and also, Is there any option to save the image in cache using glide, so that It can load it once and show without fetching it from firebase.
Here is my code to display image from url:
public void showImage(){
mStorageRef.child("TimeTable").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
url = uri.toString();
RequestOptions options = new RequestOptions().centerCrop().placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher_round);
Toast.makeText(TimeTable.this, uri.toString(),Toast.LENGTH_SHORT).show();
Glide.with(TimeTable.this).load(url).apply(options).into(image);
}
});
}
Here is the Error log, when I closed the activity before image loaded completely..
Please ask if any further details are required.
You can cache your images loading using Glide. I am referring to the tutorial here where you can learn the basics of image caching using Glide.
Now about the crashing problem, it clearly says that you are trying to load something from an activity which is already destroyed. As you have a firebase listener added where you are loading the image, you need to destroy the listener as you are leaving the activity.
You might consider using onPause, onDestroy functions to handle the remove listener action. Check the removeEventListener function of Firebase.
However, I would recommend using activity scoped versions of the loaders so that Firebase task takes care of these things by itself. Please see the answer here.

Android - While handling an image is it better to store it or use it in temporary memory?

I'm trying to build an app that takes a picture with the camera an sends it back to the main activity to display it in an ImageVew. I saw a tutorial that saves the image in the SD Card when the picture is taken. I'm able to save the file but I'm having difficulties getting the location of the stored image.
I think that storing the image in the SD Card is too much work since that image is not that important.
Is there a way to "save" the image I just took with the camera in a BitMap element? if so is it more efficient than storing it in the SD Card?
Here is my MainActivity.java:
public class MainActivity extends AppCompatActivity {
private Uri imgLocation;
ImageView mImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button capture = (Button) findViewById(R.id.am_btn_camera);
capture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imgLocation = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "fname_" +
String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, imgLocation);
startActivityForResult(intent, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
Log.e("URI",imgLocation.toString());
mImageView.setImageBitmap(BitmapFactory.decodeFile(imgLocation.toString()));
}
}}
It is better to just save it on the external/internal storage and then access it. It is even better to use a third-party library to handle all the image rendering and their lazy-loading like:
Glide
Picasso
Fresco
Most of these libraries will focus on handling resources from HTTP URLs, but they can still be used to load information from a local file or a Content Provider.
Handling images with Bitmaps might cause OutOfMemoryError easily as shown in this link. Although, in this case, since you are only using 1 Bitmap, there is not a lot to worry about.
It's almost always better to save it in the file system and pass the filepath within activities.
Android Bitmaps literally consume a lot of memory, and it's never a good idea to keep it in memory unless it's really required.
I know, it's a bit of a hassle to store it in the file system and pass the file reference, but it'll prevent a lot of unwanted outOfMemory errors later within your app.
Use Picasso. It will automatically cache the file for you on the filesystem.
If you need to retain that file on disk for longer periods, you must save it yourself.

Eclipse Java Memory Error: Heap. Developing in Android with Phonegap.

I have a Android App I have developed, It has been created from a successful ios App that was released and works fine. On one device it works correctly, no errors and does not crash. However on another device (newer, newer version of Android, faster processor) it crashes. Here are the memory errors when it crashes.
The app is designed to take a picture and to then use that picture as the background for a canvas, then a screen shot is taken. I can go through this process once, but then if I repeat the process and take another picture, the application crashes on exit of the camera API for the second time. And displays these errors. The application is Developed in Eclipse using Phonegap and Jquery mobile. I am unsure which parts of my code I should post to help this problem, but please feel free to ask if you feel some may be relevant.
Any help is really appreciated.
Okay, if you review my post on why we run out of memory on PhoneGap Android apps:
http://simonmacdonald.blogspot.ca/2012/07/change-to-camera-code-in-phonegap-190.html
You may find some tips when you use the camera.getPicture() command. Other than that I'm currently working on fixing some of these Camera issues by bringing everything in house instead of firing a camera intent.
You can make such trick.... To set picture as background use...
public void setbg(){
String pathName = Environment.getExternalStorageState() + "scm_pic.jpg";
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeFile(pathName);
BitmapDrawable bd = new BitmapDrawable(res, bitmap);
View view = findViewById(R.id.container);
view.setBackgroundDrawable(bd);
}
And then when you don't need this picture or want to #Override onPause methods or to switch another activity use...
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
To use it in #Override use for examole...
unbindDrawables(findViewById(R.id.container));
System.gc();
if you use camera means Destination type must in FILE_URL in android. because DATA_URI gives base64 string so it gives out of memory error sometime. First u get URL from camera then Convert base64 format using filesystem concepts...

Beautiful way to come over bug with ACTION_IMAGE_CAPTURE

I faced problem: ACTION_IMAGE_CAPTURE intent's behaviour depends on hardware manufacturer.
I think, best way to get photo from camera inserted in photo gallery must be something like following
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, CAPTURE_IMAGE_REQUEST);
and then get uri in onActivityResult:
switch (requestCode) {
case CAPTURE_IMAGE_REQUEST: {
if(resultCode == Activity.RESULT_OK) {
Uri uri = intent.getData();// content uri of photo in media gallery
//do something with this
}
break;
}
But I see, that this doesn't work on many devices; moreover, I found several different scenarios of Camera app behaviour:
some devices have bug with this event, so there is no way to get fullsized photos, and you can get 512px wide photo using tmp file in public directory only
some devices (including mine) insert taken photo into gallery, but does not return Uri. (getData() returns null, intent extras have only boolean key 'specify-data', value = true) If I try to get photo through the public tempfile then photo will be inserted into both gallery and tempfile.
some devices don't insert taken photos to gallery - and I must do it manually
I dont know, but there can be other different scenarious
So, is there best practices in managing such problems to cover a wide range of devices and manufacturers?
In this case I need take photo from camera, get it inserted into gallery, then get uri of photo in gallery.
A part of this has already been answered :
Check the implementation of hasImageCaptureBug()
For the null problem, maybe you can watch over the Gallery folder?
I don't think you should be checking for other cases. Google and Android OEM's monitor those issues so report them and hopefully they will be fixed.

Categories

Resources