如何从gallary中选择图像并将其设置为位图

时间:2016-04-19 15:48:10

标签: android bitmap

imageButton RecyclerView.Adapter需要intent从图片库中选择图片。这是我用方法onImageSelected(uri, getContentResolver())

将Uri传递给适配器的主类
public class MainForSemesterMessageFeedT extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 1 && resultCode == Activity.RESULT_OK) {
        if(data != null) {
            Uri uri = data.getData();
            FeedListAdapter adapter = new FeedListAdapter();
            adapter.onImageSelected(uri, getContentResolver());
        }
    }
}

这是适配器类:

public class FeedListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_FEED = 1;

private int PICK_IMAGE_REQUEST = 1;
private Bitmap bitmap;
private ImageView img;
private Uri filepath;


private List<FeedItem> feedItems;
Context context;
Activity activity;
private SQLiteHandler db;
private StringRequest stringRequest;
private RequestQueue requestQueue;

private ImageLoader imageLoader = AppController.getInstance().getImageLoader();


public FeedListAdapter() {

}

public FeedListAdapter(List<FeedItem> feedItems, Activity activity) {
    this.feedItems = feedItems;
    this.activity = activity;
    notifyItemRangeChanged(0, feedItems.size());
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    this.context = parent.getContext();
    if (viewType == TYPE_HEADER) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_header, parent, false);
        return new VHHeader(v);
    } else if (viewType == TYPE_FEED) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_item_row, parent, false);
        return new VHItem(v);
    }
    throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof VHItem) {
        FeedItem feedItem = getItem(position);
        ((VHItem) holder).name.setText(feedItem.getName());
        //converting timestamp into x ago format
        CharSequence timeAgo = DateUtils.getRelativeTimeSpanString(Long.parseLong(feedItem.getTimeStamp()), System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS);
        ((VHItem) holder).timestamp.setText(timeAgo);
        if (!TextUtils.isEmpty(feedItem.getStatus())) {
            ((VHItem) holder).statusMsg.setText(feedItem.getStatus());
            ((VHItem) holder).statusMsg.setVisibility(View.VISIBLE);
        } else {
            ((VHItem) holder).statusMsg.setVisibility(View.GONE);
        }

        if (feedItem.getUrl() != null) {
            ((VHItem) holder).url.setText(Html.fromHtml("<a href=\"" + feedItem.getUrl() + "\">" + feedItem.getUrl() + "</a> "));
            // making url clickable
            ((VHItem) holder).url.setMovementMethod(LinkMovementMethod.getInstance());
            ((VHItem) holder).url.setVisibility(View.VISIBLE);
        } else {
            ((VHItem) holder).url.setVisibility(View.GONE);
        }
        ((VHItem) holder).profilePic.setImageUrl(feedItem.getProfilePic(), imageLoader);

        if (feedItem.getImge() != null) {
            ((VHItem) holder).feedImageView.setImageUrl(feedItem.getImge(), imageLoader);
            ((VHItem) holder).feedImageView.setVisibility(View.VISIBLE);
            ((VHItem) holder).feedImageView.setResponseObserver(new FeedImageView.ResponseObserver() {
                @Override
                public void onError() {

                }

                @Override
                public void onSuccess() {

                }
            });
        } else {
            ((VHItem) holder).feedImageView.setVisibility(View.GONE);
        }
    } else if (holder instanceof VHHeader) {
        db = new SQLiteHandler(context);
        HashMap<String, String> data = db.getUserDetails();
        ((VHHeader) holder).imageView.setImageUrl(data.get("photo"), imageLoader);
        String user_question = ((VHHeader) holder).editText.getText().toString().trim();

        // here I set the image from bitmap to imageview
        ((VHHeader) holder).headerImageView.setImageBitmap(bitmap);
        ((VHHeader) holder).headerImageView.setVisibility(View.VISIBLE);

        Message.message(context, ""+bitmap);
    }


}

private FeedItem getItem(int position) {
    return feedItems.get(position - 1);
}

@Override
public int getItemCount() {
    return feedItems.size() + 1;
}

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

// We need to work here in VHHeader. the other ViewHolder "VHItem" is to parse data from json so no need to worry about it
private class VHHeader extends RecyclerView.ViewHolder implements View.OnClickListener {
    EditText editText;
    ImageView headerImageView;
    NetworkImageView imageView;
    Button post;
    ImageButton selectImageBtn;


    public VHHeader(View v) {
        super(v);
        //this one I need to show the pic. which Visibility is visible in onBindViewHolder
        headerImageView = (ImageView) v.findViewById(R.id.header_imageview);
        editText = (EditText) v.findViewById(R.id.header_tv);
        selectImageBtn = (ImageButton) v.findViewById(R.id.header_select_img);
        imageView = (NetworkImageView) v.findViewById(R.id.header_user_photo);
        post = (Button) v.findViewById(R.id.header_post_btn);
        post.setOnClickListener(this);
        selectImageBtn.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        HashMap<String, String> data = db.getUserDetails();
        final String user_id = data.get("uid");
        final String display_picture = data.get("photo");
        final String name = data.get("name");
        final String user_post = editText.getText().toString().trim();

        // also dont worry about this post. its just to post the status. it works fine.
        if (view.getId() == post.getId()) {
            stringRequest = new StringRequest(Request.Method.POST, AppConfig.URL_ADD_FEED, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.e("RESPONSE", response.toString());
                    try {
                        JSONObject object = new JSONObject(response);
                        boolean error = object.getBoolean("error");
                        if (!error) {
                            Message.message(context, "Posted");
                            notifyDataSetChanged();

                        } else {
                            String error_msg = object.getString("error_msg");
                            Message.message(context, error_msg);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Message.message(context, error.getMessage());
                }
            }) {
                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                    long millis = System.currentTimeMillis() % 1000;
                    Map<String, String> param = new HashMap<String, String>();
                    param.put("user_id", user_id);
                    param.put("name", name);
                    param.put("status", user_post);
                    param.put("q_image", "");
                    param.put("display_picture", display_picture);
                    param.put("timestamp", String.valueOf(millis));
                    return param;
                }
            };
            requestQueue = Volley.newRequestQueue(context);
            requestQueue.add(stringRequest);

        }
        // Here I choose the image from gallary. works fine.
        if(view.getId() == selectImageBtn.getId()) {
            Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("image/*");
            activity.startActivityForResult(intent, PICK_IMAGE_REQUEST);
        }

    }
}


// Dont wory about this. it is use to parse data from json.
private class VHItem extends RecyclerView.ViewHolder {
    TextView name, timestamp, statusMsg, url;
    NetworkImageView profilePic;
    FeedImageView feedImageView;

    public VHItem(View v) {
        super(v);
        if (imageLoader == null) {
            AppController.getInstance().getImageLoader();
        }
        name = (TextView) itemView.findViewById(R.id.name);
        timestamp = (TextView) itemView.findViewById(R.id.timestamp);
        statusMsg = (TextView) itemView.findViewById(R.id.txtStatusMsg);
        url = (TextView) itemView.findViewById(R.id.txtUrl);
        profilePic = (NetworkImageView) itemView.findViewById(R.id.profilePic);
        feedImageView = (FeedImageView) itemView.findViewById(R.id.feedImage1);

    }
}


@Override
public int getItemViewType(int position) {
    if (isPositionHeader(position)) {
        return TYPE_HEADER;
    } else {
        return TYPE_FEED;
    }
}

private boolean isPositionHeader(int position) {
    return position == 0;
}


// This is used to encode image. I didnot used this method anywhere yet. will use it for server storing.
public String getStringImage(Bitmap btmp) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    btmp.compress(Bitmap.CompressFormat.JPEG,100,baos);
    byte[] imageBytes = baos.toByteArray();
    String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
    return encodedImage;
}

// The uri comes from Acitivity
public void onImageSelected(Uri uri, ContentResolver contentResolver) {
    try {
        bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri);
        // when i show this bitmap in Toast. I throws null pointer exception here too.
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

我很困惑如何在Adapter中从gallery中选择图像并将其存储在位图中,以便我可以使用该位图图像执行其他任务,例如将其发送到在线数据库。

This is the screenshot of the app

2 个答案:

答案 0 :(得分:1)

//add this to your manifest file
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    //add to your activity
    private static int IMAGE_GALLERY_REQUEST =1;
    //add to your onclick method
    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                        File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
                        String pictureDirectoryPath = pictureDirectory.getPath();
                        Uri data=Uri.parse(pictureDirectoryPath);
                        photoPickerIntent.setDataAndType(data,"image/*");
                        startActivityForResult(photoPickerIntent,IMAGE_GALLERY_REQUEST);
    //add to your activity
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == IMAGE_GALLERY_REQUEST) {
                Uri imageUri = data.getData();
                InputStream inputstream;
                try {
                    inputstream = getContentResolver().openInputStream(imageUri);
                    //the "image" received here it the image itself
                    Bitmap image = BitmapFactory.decodeStream(inputstream);
                    //YOU CAN ASSIGN IT TO YOUR IMAGE BUTTON HERE IF YOU WANT
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }    

答案 1 :(得分:0)

您可以通过此调用显示内置图像选择器:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
activity.startActivityForResult(intent, AVATAR_REQUEST_CODE);

要进行调用,您需要在适配器类中使用活动引用。但是,获取所选图像的Uri的唯一方法是通过onActivityResult从活动中获取。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // On avatar image selected
    if (requestCode == AVATAR_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        if (data != null) {
            Uri uri = data.getData();

            // do you stuff here
         }
     }
}

我可以想到在适配器类中获取Uri的一种方法是在适配器类中放置一个公共方法:

public void onImageSelected(Uri uri) {
     // do you stuff here
}

然后在您的活动类中,调用adapter.onImageSelected(uri):

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // On avatar image selected
    if (requestCode == AVATAR_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        if (data != null) {
            Uri uri = data.getData();                
            adapter.onImageSelected(uri)
         }
     }
}

获得Uri后,您可以执行位图并上传内容。