定义构造函数文件(Uri)?

时间:2014-01-27 14:53:22

标签: android bitmap out-of-memory

我制作了一个壁纸设置应用程序,在我的设备(Nexus 5)上,它工作得很好但是在Galaxy TAB,Fame甚至是Optimus上都会产生java.lang.OutOfMemory错误。 有人告诉我实现公共位图decodeAndResizeFile(文件f)但我得到了

这是我的MainActivity代码     包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;
}

这里我实现了它:

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;

在这里我会回复它:

  

文件文件=新文件(Uri.parse(String.valueOf(toPhone)));

在上面的行上我得构造函数文件(Uri)未定义错误

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;
    }
    }
    }

我该如何定义它?我做错了什么?

3 个答案:

答案 0 :(得分:0)

文件类在其构造函数中使用java.net.URI,你试图给它一个android.net.Uri。

就我所见,这就是错误。

您正在使用的File类: http://docs.oracle.com/javase/7/docs/api/java/io/File.html

采用此URI类:http://docs.oracle.com/javase/7/docs/api/java/net/URI.html

你传递了这个:http://developer.android.com/reference/java/net/URI.html

答案 1 :(得分:0)

我遇到过这么多次错误......最后我提出了一种常用的方法来设置图像视图......以下是代码片段...

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);


    }

您可能需要修改上述代码,以满足您对图片分辨率的要求。

希望这有帮助。

编辑

技术上唯一不同的是我在我的代码中添加了Scaling ...尝试在你的代码片段中引入它......我没有发现图片质量明显下降......

答案 2 :(得分:0)

您的编译错误是因为类'File'没有构造函数将Uri对象作为参数。要使用Uri构造File对象,通常会在URI上调用getPath()以将其路径作为String返回:

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

然而,这仍然无法解决您的问题,因为'toPhone'是一个整数,表示项目中资源的ID(在本例中为drawable)。您无法以这种方式从资源ID生成URI或文件路径。但是,在这种情况下,您可以直接使用资源ID而不是文件。

更改您的解码方法以接受资源标识符(即整数):

public Bitmap decodeAndResizeFile(int resID) {

...并使用BitmapFactory的decodeResource方法而不是decodeStream(使用Activity的上下文):

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

然后你可以用:

来调用它
Bitmap bmpp = decodeAndResizeFile(toPhone);

获取上下文的最简单方法是将其声明为Activity类中的变量:

private Context context;

...并将其设置为onCreate():

context = this;

然后,您可以在活动中的任何地方使用它。