无法解决此获取位图错误

时间:2013-12-08 01:59:54

标签: android fileoutputstream

我陷入困境,无论我对编码做什么,我都会遇到同样的问题。 在我的应用程序中,当用户打开它时,会在gridView上创建一个带有图像和滑动抽屉的gridView。在滑动抽屉中是每个listview项目的所有用户安装程序的listView:

<ImageView
  android:id="@+id/ivIcon"
  android:layout_width="wrap_content"
  android:layout_height="fill_parent"
  android:layout_marginRight="5dip"
  android:scaleType="center"
  android:contentDescription="@string/desc"
/>

<LinearLayout
  android:orientation="vertical"
  android:layout_width="0dip"
  android:layout_height="fill_parent"
  android:layout_weight="1"    
>

  <TextView
      android:id="@+id/tvName"
      android:layout_width="fill_parent"
      android:layout_height="0dip"
      android:layout_weight="1"
      android:gravity="center_vertical"         
  />

  <TextView
      android:id="@+id/tvPack"
      android:layout_width="fill_parent"
      android:layout_height="0dip"
      android:layout_weight="1"
      android:singleLine="true"
      android:ellipsize="marquee"         
  />

</LinearLayout>

<CheckBox
  android:id="@+id/addCheckbox"
  android:layout_width="0dp"
  android:layout_height="fill_parent"
  android:layout_weight="0.3"
  android:gravity="center_vertical"
  android:focusable="false" 
 />

应该发生的是,当选中该复选框时,它会从listView项中获取图标,将其转换为位图,将该位图保存到内部存储,从内部存储获取该位图,然后填充gridView与那个图像。这一切都发生在我的两个适配器中,用于listView和gridView。这是listView的适配器:

package com.example.awesomefilebuilderwidget;

IMPORTS

public class AppInfoAdapter extends BaseAdapter {
private Context mContext;
private List<ResolveInfo> mListAppInfo;
private PackageManager mPackManager;
private List<ResolveInfo> originalListAppInfo;
private Filter filter;
private String fname;

public AppInfoAdapter(Context c, List<ResolveInfo> listApp,
        PackageManager pm) {
    mContext = c;
    this.originalListAppInfo = this.mListAppInfo = listApp;
    mPackManager = pm;
    Log.d("AppInfoAdapter", "top");
}

@Override
public int getCount() {
    Log.d("AppInfoAdapter", "getCount()");
    return mListAppInfo.size();
}

@Override
public Object getItem(int position) {
    Log.d("AppInfoAdapter", "getItem");
    return mListAppInfo.get(position);
}

@Override
public long getItemId(int position) {
    Log.d("AppInfoAdapter", "getItemId");
    return position;
}

public static Bitmap scaleDownBitmap(Bitmap default_b, int newHeight, Context c) {

    final float densityMultiplier = c.getResources().getDisplayMetrics().density;

    int h= (int) (100*densityMultiplier);
    int w= (int) (h * default_b.getWidth()/((double) default_b.getHeight()));

    default_b=Bitmap.createScaledBitmap(default_b, w, h, true);
    // TO SOLVE LOOK AT HERE:http://stackoverflow.com/questions/15517176/passing-bitmap-to-other-activity-getting-message-on-logcat-failed-binder-transac
    return default_b;
}

public final static String APP_PATH_SD_CARD = "/TEST/";
public final static String APP_THUMBNAIL_PATH_SD_CARD = "thumbnails";

public boolean saveImageToExternalStorage(Bitmap default_b) {
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + APP_PATH_SD_CARD + APP_THUMBNAIL_PATH_SD_CARD;

try {
File dir = new File(fullPath);
if (!dir.exists()) {
dir.mkdirs();
Log.i("AIA", "Directory created");
}

OutputStream fOut = null;
File file = new File(fullPath, "AFBWIcon.png");
file.createNewFile();
fOut = new FileOutputStream(file);

// 100 means no compression, the lower you go, the stronger the compression
default_b.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
Log.i("AIA", "Icon sent on FOS");
MediaStore.Images.Media.insertImage(mContext.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());

return true;

} catch (Exception e) {
Log.e("saveToExternalStorage()", e.getMessage());
return false;
}
}

public boolean saveImageToInternalStorage(Bitmap default_b) {

    try {
    // Use the compress method on the Bitmap object to write image to
    // the OutputStream
    FileOutputStream fos = mContext.openFileOutput("desiredFilename.png", Context.MODE_PRIVATE);

    // Writing the bitmap to the output stream
    default_b.compress(Bitmap.CompressFormat.PNG, 100, fos);
    fos.close();

    return true;
    } catch (Exception e) {
    Log.e("saveToInternalStorage()", e.getMessage());
    return false;
    }
    }



@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // get the selected entry
    final ResolveInfo entry = (ResolveInfo) mListAppInfo.get(position);

    // reference to convertView
    View v = convertView;

    // inflate new layout if null
    if (v == null) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        v = inflater.inflate(R.layout.layout_appinfo, null);
        Log.d("AppInfoAdapter", "New layout inflated");
    }

    // load controls from layout resources
    ImageView ivAppIcon = (ImageView) v.findViewById(R.id.ivIcon);
    TextView tvAppName = (TextView) v.findViewById(R.id.tvName);
    TextView tvPkgName = (TextView) v.findViewById(R.id.tvPack);
    final CheckBox addCheckbox = (CheckBox) v
            .findViewById(R.id.addCheckbox);
    Log.d("AppInfoAdapter", "Controls from layout Resources Loaded");

    // set data to display
    ivAppIcon.setImageDrawable(entry.loadIcon(mPackManager));
    tvAppName.setText(entry.activityInfo.loadLabel(mPackManager));
    tvPkgName.setText(entry.activityInfo.packageName);

    Log.d("AppInfoAdapter", "Data Set To Display");
    addCheckbox
            .setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    if (addCheckbox.isChecked()) {
                        System.out.println("Checked");
                        PackageManager pm = mContext.getPackageManager();
                        Drawable icon = null;
                        try {
                            icon = pm
                            .getApplicationIcon(entry.activityInfo.packageName);
                        } catch (NameNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        Drawable default_icon = pm.getDefaultActivityIcon();
                        if (icon instanceof BitmapDrawable
                                && default_icon instanceof BitmapDrawable) {
                            BitmapDrawable icon_bd = (BitmapDrawable) icon;
                            Bitmap icon_b = icon_bd.getBitmap();
                            BitmapDrawable default_bd = (BitmapDrawable) pm
                                    .getDefaultActivityIcon();
                            Bitmap default_b = default_bd.getBitmap();
                            if (icon_b == default_b) {
                                // It's the default icon
                                scaleDownBitmap(default_b, 100, v.getContext());
                                Log.d("AppInfoAdapter", "Scale Bitmap Chosen");

                                saveImageToExternalStorage(default_b);
                                saveImageToInternalStorage(default_b);
                                Log.d("AppInfoAdapter", "Scaled BM saved to External Storage");

                                Intent intent = new Intent(v.getContext(), GridViewAdapter.class);
                                // intent.hasExtra("bitmapA");
                                v.getContext().startActivity(intent);
                                Log.d("AppInfoAdapter", "Intent started to send Bitmap");

                            }
                        }
                    } else {
                        System.out.println("Un-Checked");
                    }

                }
            });

    // return view
    return v;
}

这里是gridView的适配器:

package com.example.awesomefilebuilderwidget;

IMPORTS

public class GridViewAdapter extends BaseAdapter {
private Context Context;

// Keep all Images in array list
public ArrayList<Integer> drawables = new ArrayList<Integer>();

CheckBox mCheckBox=null;

// Constructor
public GridViewAdapter(Context c){
    Context = c;
    Log.d("GridViewAdapter", "Constructor is set");

    drawables.add(R.drawable.pattern1);
    Log.d("GridViewAdapter", "pattern1 added");

    drawables.add(R.drawable.pattern2);
    Log.d("GridViewAdapter", "pattern2 added");

    drawables.add(R.drawable.trashcan);
    Log.d("GridViewAdapter", "trashcan added");

    drawables.add(R.drawable.ic_launcher);
    Log.d("GridViewAdapter", "ic_launcher added");

    Bitmap default_b = BitmapFactory.decodeFile("picture"); 
}

public void setCheckBox(CheckBox checkbox){
    mCheckBox=checkbox;
}

@Override
// How many items are in the data set represented by this Adapter
public int getCount() {
    return drawables.size();
}

@Override
// Get the data item associated with the specified position in the
// data set
public Object getItem(int position) {
    return drawables.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

public boolean isSdReadable() {

    boolean mExternalStorageAvailable = false;
    String state = Environment.getExternalStorageState();

    if (Environment.MEDIA_MOUNTED.equals(state)) {
    // We can read and write the media
    mExternalStorageAvailable = true;
    Log.i("isSdReadable", "External storage card is readable.");
    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
    // We can only read the media
    Log.i("isSdReadable", "External storage card is readable.");
    mExternalStorageAvailable = true;
    } else {
    // Something else is wrong. It may be one of many other
    // states, but all we need to know is we can neither read nor write
    mExternalStorageAvailable = false;
    }

    return mExternalStorageAvailable;
    }

public Bitmap getThumbnail() {

    final String APP_PATH_SD_CARD = "/TEST/";
    final String APP_THUMBNAIL_PATH_SD_CARD = "thumbnails";
    String filename = "AFBWIcon.png";

    String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + APP_PATH_SD_CARD + APP_THUMBNAIL_PATH_SD_CARD;
    Bitmap thumbnail = null;

    // Look for the file on the external storage
    try {
    if (isSdReadable() == true) {
    thumbnail = BitmapFactory.decodeFile(fullPath + "/" + filename);
    }
    } catch (Exception e) {
    Log.e("getThumbnail() on external storage", e.getMessage());
    }

    // If no file on external storage, look in internal storage
    if (thumbnail == null) {
    try {
    File filePath = Context.getFileStreamPath(filename);
    FileInputStream fi = new FileInputStream(filePath);
    thumbnail = BitmapFactory.decodeStream(fi);
    } catch (Exception ex) {
    Log.e("getThumbnail() on internal storage", ex.getMessage());
    }
    }
    return thumbnail;
    }



@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Try to reuse the views
    ImageView view = (ImageView) convertView;
    @SuppressWarnings("unused")
    boolean checked = (mCheckBox==null)?false:(((CheckBox)  mCheckBox).isChecked());
    // if convert view is null then create a new instance else reuse it
    if (view == null) {
        view = new ImageView(Context);
        Log.d("GridViewAdapter", "new imageView added");
    }
    if(checked = true){
        isSdReadable();
        getThumbnail();
    } else {
        Log.e("GridView", "Icons not for use");
    }
    view.setImageResource(drawables.get(position));
    view.setScaleType(ImageView.ScaleType.CENTER_CROP);
    view.setLayoutParams(new android.widget.GridView.LayoutParams(70, 70));
    view.setTag(String.valueOf(position));
    return view;
}

}

请注意我在GridView的另一个类中设置了这个:

android.widget.GridView gridView = (android.widget.GridView) findViewById(R.id.GRIDVIEW1);

    // Instance of Adapter Class
    GridViewAdapter mGridViewAdapter= new GridViewAdapter(this);
    gridView.setAdapter(mGridViewAdapter);
    CheckBox mCheckBox = (CheckBox) findViewById(R.id.addCheckbox);
    mGridViewAdapter.setCheckBox(mCheckBox);

现在,问题是两件事:

  1. 当我打开我的应用程序并创建gridView时,我收到此错误:

    12-07 17:51:33.596:内部存储上的E / getThumbnail()(32607):/ data / data / com.example.awesomefilebuilderwidget / files / AFBWIicon.png(没有这样的文件或目录)

  2. 这是有道理的,因为直到复选框的onClick方法(或至少它应该如何)才创建文件

    这导致问题2

    1. 当我点击listView的复选框时,所有它都打印出“已选中”或“未选中”,但从未打印过我之后设置的任何其他日志。这几乎使复选框的整个功能无用。 (即它不会创建图标位图并填充gridView)
    2. 我试图实现一个系统,在单击复选框之后它不会检查文件,但它显然不起作用。

      我该怎么办?!

0 个答案:

没有答案