0

i made a wallpaper set application, on my device (Nexus 5) it works great but on Galaxy TAB, Fame or even on Optimus it gives java.lang.OutOfMemory error. someone told me to implement public Bitmap decodeAndResizeFile(File f) but i get

here is my MainActivity code package app.technozed.cablewallpapershd;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.net.Uri;
 import android.os.Bundle;
 import android.app.Activity;
 import android.app.WallpaperManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
 import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

ImageView display;
int toPhone;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    System.gc();
    toPhone = R.drawable.wal1;
    display = (ImageView) findViewById(R.id.WPdisplay);
    ImageView image1 = (ImageView) findViewById(R.id.WPimg1);
    ImageView image2 = (ImageView) findViewById(R.id.WPimg2);
    ImageView image3 = (ImageView) findViewById(R.id.WPimg3);
    ImageView image4 = (ImageView) findViewById(R.id.WPimg4);
    ImageView image5 = (ImageView) findViewById(R.id.WPimg5);
    ImageView image6 = (ImageView) findViewById(R.id.WPimg6);
    ImageView image7 = (ImageView) findViewById(R.id.WPimg7);
    ImageView image8 = (ImageView) findViewById(R.id.WPimg8);
    ImageView image9 = (ImageView) findViewById(R.id.WPimg9);
    ImageView image10 = (ImageView) findViewById(R.id.WPimg10);
    Button setWall = (Button) findViewById(R.id.BsetWall);
    image1.setOnClickListener(this);
    image2.setOnClickListener(this);
    image3.setOnClickListener(this);
    image4.setOnClickListener(this);
    image5.setOnClickListener(this);
    image6.setOnClickListener(this);
    image7.setOnClickListener(this);
    image8.setOnClickListener(this);
    image9.setOnClickListener(this);
    image10.setOnClickListener(this);       setWall.setOnClickListener(this);
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

here i implemented it:

public Bitmap decodeAndResizeFile(File f) {

    try {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 70;

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE
                    || height_tmp / 2 < REQUIRED_SIZE)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {
    }
    return null;
}

@Override
public void onClick(View v) {
    switch (v.getId()){
    case R.id.WPimg1:
         display.setImageResource(R.drawable.wal1);
         toPhone = R.drawable.wal1;

here i retrive it:

File file=new File(Uri.parse(String.valueOf(toPhone)));

on the line above i get The constructor File(Uri) is undefined error

Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bmpp);

         break;
    case R.id.WPimg2:
         display.setImageResource(R.drawable.wal2);
         toPhone = R.drawable.wal2;
         break;
    case R.id.WPimg3:
         display.setImageResource(R.drawable.wal3);
         toPhone = R.drawable.wal3;
         break;
    case R.id.WPimg4:
         display.setImageResource(R.drawable.wal4);
         toPhone = R.drawable.wal4;
         break;
    case R.id.WPimg5:
         display.setImageResource(R.drawable.wal5);
         toPhone = R.drawable.wal5;
         break;
    case R.id.WPimg6:
         display.setImageResource(R.drawable.wal6);
         toPhone = R.drawable.wal6;
         break;
    case R.id.WPimg7:
         display.setImageResource(R.drawable.wal7);
         toPhone = R.drawable.wal7;
         break;
    case R.id.WPimg8:
         display.setImageResource(R.drawable.wal8);
         toPhone = R.drawable.wal8;
         break;
    case R.id.WPimg9:
         display.setImageResource(R.drawable.wal9);
         toPhone = R.drawable.wal9;
         break;
    case R.id.WPimg10:
         display.setImageResource(R.drawable.wal10);
         toPhone = R.drawable.wal10;
         break;
    case R.id.BsetWall:
         try{
               WallpaperManager.getInstance(getApplicationContext()).setResource(toPhone);
             Toast.makeText(getApplicationContext(), "Wallpaper was set!", Toast.LENGTH_SHORT).show();
         } catch(IOException e) {
             e.printStackTrace();
             Toast.makeText(getApplicationContext(), "No privileges!", Toast.LENGTH_SHORT).show();
         }
         break;
    }
    }
    }

how can i define it? what i'm doing wrong?

George Lungu
  • 125
  • 2
  • 4
  • 16

3 Answers3

1

The file class takes a java.net.URI in its constructor, you're trying to give it an android.net.Uri.

That's what's wrong as far as I can see.

The File class you're using: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

Takes this URI class: http://docs.oracle.com/javase/7/docs/api/java/net/URI.html

You're passing this: http://developer.android.com/reference/java/net/URI.html

Reinstate Monica
  • 2,767
  • 3
  • 31
  • 40
  • i defined Uri like this: **Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); File file = new File(picturePath);// Bitmap bmpp = decodeAndResizeFile(file);** but `data.getData();` doesn't want to work saying: data cannot be resolved – George Lungu Jan 28 '14 at 07:50
0

I had encountered this error so many times... Finally I came out with one common method to set the image view... Following is the code fragment...

public static void setImageView(ImageView imageView, String path) {
        Log.i("Atul Dravid", path);
        if (path.startsWith("Photo") || path.startsWith("null"))
            return;
        path = path.startsWith("/") ? path : path.substring(6);
        Bitmap picture = (Bitmap) BitmapFactory.decodeFile(path);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        picture = Bitmap.createScaledBitmap(picture, 200, 200, false);
        picture.compress(Bitmap.CompressFormat.JPEG, 20, stream);
        byte[] bitmapArray = stream.toByteArray();
        picture = (Bitmap) BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
        //imageView.setImageURI(fileUri);
        imageView.setImageBitmap(picture);
        imageView.setContentDescription(path);


    }

You may want to modify above code for your requirement of resolution of the picture.

Hope this helps.

EDIT

Technically only difference is that I also added Scaling in my code... Try introducing that in your code fragment... I have not found any noticeable degradation in quality of the picture...

0

Your compile error is because there is no constructor for the class 'File' that takes a Uri object as a parameter. To construct a File object using an Uri, you would do usually call getPath() on the URI to return its path as a String:

File file=new File(Uri.parse(String.valueOf(toPhone)).getPath());

However that will still not solve your problem because 'toPhone' is an integer representing the id of a resource in your project (in this case a drawable). You cannot generate a URI or file path from a resource id in that manner. However in this case, you can work directly with the resource id instead of a file anyway.

Change your decode method to accept a resource identifier (i.e. an integer):

public Bitmap decodeAndResizeFile(int resID) {

...and use the decodeResource method of BitmapFactory instead of decodeStream (using your Activity's context):

Bitmap bmp= BitmapFactory.decodeResource(context.getResources(), resID, o);

Then you can call it with:

Bitmap bmpp = decodeAndResizeFile(toPhone);

Easiest way to get the context is to declare it as a variable in your Activity class:

private Context context;

...and set it in onCreate():

context = this;

You can then use it wherever you need to in your activity.

NigelK
  • 8,255
  • 2
  • 30
  • 28
  • should i define it: `Context context; public myClass(Context context) { this.context = context; }` – George Lungu Jan 27 '14 at 16:23
  • Please see my edit above. The easiest way is to store a reference to your activity's context in onCreate. – NigelK Jan 27 '14 at 16:43
  • the `} catch (FileNotFoundException e) { } return null; }` says *Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body* can i leave only `} catch (Exception e) {` ? – George Lungu Jan 28 '14 at 11:43
  • Yes. If you are no longer using a file, that exception can no longer occur. So you can remove the try/catch. – NigelK Jan 28 '14 at 11:52
  • `case R.id.WPimg1:` `display.setImageResource(R.drawable.wal1);` `toPhone = R.drawable.wal1;` `File file=new` `File(Uri.parse(String.valueOf(toPhone)).getPath());` `Bitmap bmpp = decodeAndResizeFile(toPhone);` `break;` mmmm.. i'm not able to use bmpp more then 1 time, can i use it like this: **bmpp = decodeAndResizeFile(toPhone);** ? – George Lungu Jan 28 '14 at 13:12
  • Declare 'Bitmap bmpp;' once before the switch statement. Then you can use 'bmppp=decode..." as many times as you like. Remove the 'File file=new File...' statement as well since you don't need it and it won't work anyway... – NigelK Jan 28 '14 at 13:20
  • all seems ok, but the app doesn't want to start, can you please take a look i created another question here [link](http://stackoverflow.com/questions/21410641/error-inflating-class-when-trying-to-decodestream) – George Lungu Jan 28 '14 at 16:25