Reputation: 1
Hey i have spent a lot of time for fixing the error coming with following code. The error is due to out of memory (heap). Till now i didn't find any solution (it's the 3rd day am searching for it, really tired :( ) Somebody pls tell me a good solution.
activity_preview.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/setimage"
tools:context=".Preview" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_above="@+id/ad"
android:layout_alignParentTop="true">
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
<ProgressBar
android:id="@+id/pbDownload"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignLeft="@+id/image"
android:layout_alignRight="@+id/image"
android:layout_below="@+id/textView1"
android:layout_marginTop="15dp" />
<Button
android:id="@+id/save"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/pbDownload"
android:text="Button"
android:visibility="gone" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="4.91"
android:visibility="invisible" />
</LinearLayout>
<com.google.ads.AdView
android:id="@+id/ad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adUnitId="a152e9gh407f4ae69"
ads:loadAdOnCreate="true"
ads:adSize="BANNER"
android:layout_above="@+id/llbuttons"
android:layout_marginBottom="5dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:id="@+id/llbuttons"
android:layout_height="70dp"
android:layout_alignLeft="@+id/scrollView1"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:weightSum="1" >
<Button
android:id="@+id/imageButton2"
android:layout_width="0dp"
android:layout_height="60dp"
android:background="@drawable/custom_setwall"
android:onClick="onclick_setwall"
android:scaleType="fitXY"
android:layout_weight="0.5"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/imageView5"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginRight="5dp"
android:layout_weight="0.25"
android:background="@drawable/custom_save"
android:onClick="onclick_save"
android:scaleType="fitXY" />
<Button
android:id="@+id/imageButton6"
android:layout_width="0dp"
android:layout_height="60dp"
android:background="@drawable/custom_share"
android:onClick="onclick_share"
android:scaleType="fitXY"
android:layout_weight="0.25"
/>
</LinearLayout>
</RelativeLayout>
Preview.java
package com.hb.nfswallpapers;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import com.google.ads.AdRequest;
import com.google.ads.AdView;
import com.hitbytes.nfswallpapers.ImageDownloader;
import com.hitbytes.nfswallpapers.ImageDownloader.ImageLoaderListener;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ImageView.ScaleType;
public class Preview extends Activity {
private ProgressBar pb;
private Button bnxt,bprv,bhome,save,bsave,photos;
private ImageView img;
private static Bitmap bmp;
private TextView percent;
private FileOutputStream fos;
private ImageDownloader mDownloader;
String imagesources;
int pindex,i;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);
initViews();
Bundle extras = getIntent().getExtras();
imagesources = extras.getString("photourl");
/*--- instantiate our downloader passing it required components ---*/
mDownloader = new ImageDownloader(imagesources, pb, save, img, percent, Preview.this, bmp, new ImageLoaderListener() {
@Override
public void onImageDownloaded(Bitmap bmp) {
Preview.bmp = bmp;
/*--- here we assign the value of bmp field in our Loader class
* to the bmp field of the current class ---*/
}
});
/*--- we need to call execute() since nothing will happen otherwise ---*/
mDownloader.execute();
}
private void initViews() {
save = (Button) findViewById(R.id.save);
photos= (Button) findViewById(R.id.imageButton4);
bsave= (Button) findViewById(R.id.imageButton5);
//bnxt=(Button) findViewById(R.id.bnext);
//bprv=(Button) findViewById(R.id.bprev);
/*--- we are using 'this' because our class implements the OnClickListener ---*/
img = (ImageView) findViewById(R.id.imageView1);
img.setScaleType(ScaleType.FIT_XY);
pb = (ProgressBar) findViewById(R.id.pbDownload);
pb.setVisibility(View.INVISIBLE);
percent = (TextView) findViewById(R.id.textView1);
percent.setVisibility(View.INVISIBLE);
}
public void onclick_save(View v)
{
saveImageToSD();
}
public void onclick_share(View v)
{
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
String shareBody = "Find more wallpapers & images https://play.google.com/store/apps/details?id=com.hitbytes.nfswallpapers";
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, imagesources+"\n\n");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
public void onclick_setwall(View v)
{
Random r = new Random();
int rand =r.nextInt(1750-1000) + 1000;
String ran=String.valueOf(rand);
String pin=String.valueOf(pindex);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
/*--- you can select your preferred CompressFormat and quality.
* I'm going to use JPEG and 100% quality ---*/
bmp.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
// get the height and width of screen
int height = metrics.heightPixels;
int width = metrics.widthPixels;
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
try {
wallpaperManager.setBitmap(bmp);
wallpaperManager.suggestDesiredDimensions(width, height);
Toast.makeText(this, "Wallpaper Set", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveImageToSD() {
/*--- this method will save your downloaded image to SD card ---*/
Random r = new Random();
int rand =r.nextInt(1750-1000) + 1000;
String ran=String.valueOf(rand);
String pin=String.valueOf(pindex);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
/*--- you can select your preferred CompressFormat and quality.
* I'm going to use JPEG and 100% quality ---*/
bmp.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
/*--- create a new file on SD card ---*/
File direct = new File(Environment.getExternalStorageDirectory() + "/NFS Wallpapers");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/NFS Wallpapers/");
wallpaperDirectory.mkdirs();
}
File file = new File(new File("/sdcard/NFS Wallpapers/"), ran+pin+"Image.jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
/*--- create a new FileOutputStream and write bytes to file ---*/
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fos.write(bytes.toByteArray());
fos.close();
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,null);
Toast.makeText(this, "Image saved", Toast.LENGTH_SHORT).show();
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setAutoCancel(true)
.setContentTitle("Download complete..!")
.setSmallIcon(R.drawable.ic_launcher)
.setContentText("Image successfully downloaded!");
NotificationCompat.BigPictureStyle bigPicStyle = new NotificationCompat.BigPictureStyle();
bigPicStyle.bigPicture(bmp);
bigPicStyle.setBigContentTitle("Download complete");
mBuilder.setStyle(bigPicStyle);
Intent intent1 = new Intent(Intent.ACTION_VIEW);
intent1.setDataAndType(Uri.fromFile(file), "image/jpeg");
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(100, mBuilder.build());
} catch (IOException e) {
e.printStackTrace();
}
}
}
ImageDownloader.java
package com.hitbytes.nfswallpapers;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class ImageDownloader extends AsyncTask<Void, Integer, Void> {
ProgressBar pb;
String url;
Button save;
Context c;
int progress;
ImageView img;
Bitmap bmp;
TextView percent;
ImageLoaderListener listener;
/*--- constructor ---*/
public ImageDownloader(String url, ProgressBar pb, Button save,
ImageView img, TextView percent, Context c, Bitmap bmp, ImageLoaderListener listener) {
/*--- we need to pass some objects we are going to work with ---*/
this.url = url;
this.pb = pb;
this.save = save;
this.c = c;
this.img = img;
img.setVisibility(View.VISIBLE);
this.percent = percent;
this.bmp = bmp;
this.listener = listener;
}
/*--- we need this interface for keeping the reference to our Bitmap from the MainActivity.
* Otherwise, bmp would be null in our MainActivity*/
public interface ImageLoaderListener {
void onImageDownloaded(Bitmap bmp);
}
@Override
protected void onPreExecute() {
progress = 0;
pb.setVisibility(View.VISIBLE);
percent.setVisibility(View.VISIBLE);
//Toast.makeText(c, "Loading images", Toast.LENGTH_SHORT).show();
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... arg0) {
bmp = getBitmapFromURL(url);
while (progress!=0) {
progress += 100;
publishProgress(progress);
/*--- an image download usually happens very fast so you would not notice
* how the ProgressBar jumps from 0 to 100 percent. You can use the method below
* to visually "slow down" the download and see the progress bein updated ---*/
}
save.setEnabled(true);
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
/*--- show download progress on main UI thread---*/
pb.setProgress(values[0]);
percent.setText("");
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Void result) {
if (listener != null) {
listener.onImageDownloaded(bmp);
}
//Bitmap b = Bitmap.createScaledBitmap(bmp, 200, 200, false);
img.setImageBitmap(bmp);
save.setEnabled(true);
//Toast.makeText(c, "Download complete", Toast.LENGTH_SHORT).show();
super.onPostExecute(result);
}
public static Bitmap getBitmapFromURL(String link) {
/*--- this method downloads an Image from the given URL,
* then decodes and returns a Bitmap object
---*/
try {
URL url = new URL(link);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
Log.e("getBmpFromUrl error: ", e.getMessage().toString());
return null;
}
}
}
Upvotes: 0
Views: 268
Reputation: 820
Take a look into this link: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html it may help you.
You could try to use inJustDecodeBounds and get the image dimensions before decoding it. like:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream input = connection.getInputStream();
BitmapFactory.decodeStream(input ,null,options);
And then set a maximum width and height and decode it. There's a sample code on the like above where you can find two methods to do it.
Upvotes: 1
Reputation: 7069
This error can be solved by code cleaning like removing global variables,string objects on the heap etc. Please see if you can convert global variables to local variables.
ProgressBar pb;
String url;
Button save;
Context c;
int progress;
ImageView img;
Bitmap bmp;
TextView percent;
ImageLoaderListener listener;
Upvotes: 0