Android 高仿微信 你可能要发送的图片

来源:互联网 发布:shell脚本与python 编辑:程序博客网 时间:2024/06/07 08:51

   微信发送图片有个功能,就是当你拍完照片,或者保存一个张照片的时候,你点击聊天框的“+”号,微信会有个提示,你可能要发送的图片,并且附上相应的图片。要实现这个功能,分两个步骤。

1,取数据,就是从多媒体库里取出最近的图片。

2,展示,把这张图片展示出来,其实就是做一个popWindow

下图展示我做的Demo:从今日头条随便保存了一张图片


下面我们就分两步走来一步一步实现这个功能:

1,从多媒体库中取出最近要使用的图片

先封装一个图片类 ImageItem:
public class ImageItem implements Serializable {    public String name;       //图片的名字    public String path;       //图片的路径    public long size;         //图片的大小    public int width;         //图片的宽度    public int height;        //图片的高度    public String mimeType;   //图片的类型    public long addTime;      //图片的创建时间    /** 图片的路径和创建时间相同就认为是同一张图片 */    @Override    public boolean equals(Object o) {        if (o instanceof ImageItem) {            ImageItem item = (ImageItem) o;            return this.path.equalsIgnoreCase(item.path) && this.addTime == item.addTime;        }        return super.equals(o);    }}
这里最主要的字段是path 和addTime。

再者实现自己的LoaderCallbacks:ImageDataSource
public class ImageDataSource implements LoaderManager.LoaderCallbacks<Cursor> {    public static final int LOADER_ALL = 0;         //加载所有图片    public static final int LOADER_CATEGORY = 1;    //分类加载图片    private final String[] IMAGE_PROJECTION = {     //查询图片需要的数据列            MediaStore.Images.Media.DISPLAY_NAME,   //图片的显示名称  aaa.jpg            MediaStore.Images.Media.DATA,           //图片的真实路径  /storage/emulated/0/pp/downloader/wallpaper/aaa.jpg            MediaStore.Images.Media.SIZE,           //图片的大小,long型  132492            MediaStore.Images.Media.WIDTH,          //图片的宽度,int型  1920            MediaStore.Images.Media.HEIGHT,         //图片的高度,int型  1080            MediaStore.Images.Media.MIME_TYPE,      //图片的类型     image/jpeg            MediaStore.Images.Media.DATE_ADDED     //图片被添加的时间,long型  1450518608            };    private FragmentActivity activity;    /**     * 图片加载完成的回调接口     */    private OnImagesLoadedListener loadedListener;    /**     * @param activity       用于初始化LoaderManager,需要兼容到2.3     * @param path           指定扫描的文件夹目录,可以为 null,表示扫描所有图片     * @param loadedListener 图片加载完成的监听     */    public ImageDataSource(FragmentActivity activity, String path, OnImagesLoadedListener loadedListener) {        this.activity = activity;        this.loadedListener = loadedListener;        LoaderManager loaderManager = activity.getSupportLoaderManager();        if (path == null) {            loaderManager.initLoader(LOADER_ALL, null, this);//加载所有的图片        } else {            //加载指定目录的图片            Bundle bundle = new Bundle();            bundle.putString("path", path);            loaderManager.initLoader(LOADER_CATEGORY, bundle, this);        }    }    @Override    public Loader<Cursor> onCreateLoader(int id, Bundle args) {        CursorLoader cursorLoader = null;        //扫描所有图片        if (id == LOADER_ALL)//时间逆序            cursorLoader = new CursorLoader(activity, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, null, null, IMAGE_PROJECTION[6] + " DESC");        //扫描某个图片文件夹        if (id == LOADER_CATEGORY)            cursorLoader = new CursorLoader(activity, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION, IMAGE_PROJECTION[1] + " like '%" + args.getString("path") + "%'", null, IMAGE_PROJECTION[6] + " DESC");        return cursorLoader;    }    @Override    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {        //imageFolders.clear();        ImageItem imageItem = new ImageItem();        //只取第一个        if (data != null) {           // ArrayList<ImageItem> allImages = new ArrayList<>();   //所有图片的集合,不分文件夹            if (data.moveToFirst()) {                //查询数据                String imageName = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));                String imagePath = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));                long imageSize = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));                int imageWidth = data.getInt(data.getColumnIndexOrThrow(IMAGE_PROJECTION[3]));                int imageHeight = data.getInt(data.getColumnIndexOrThrow(IMAGE_PROJECTION[4]));                String imageMimeType = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[5]));                long imageAddTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[6]));                //long imageTokenTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[7]));              /*  SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");                //前面的lSysTime是秒数,先乘1000得到毫秒数,再转为java.util.Date类型                java.util.Date dt = new Date(imageAddTime*1000);                String sDateTime = sdf.format(dt);  //得到精确到秒的表示:08/31/2006 21:08:00                dt = new Date(imageTokenTime);                String sTakenTime =  sdf.format(dt);                Log.e("latestImage","imageAddTime=="+sDateTime+":::::"+imageTokenTime);*/                //封装实体                //ImageItem imageItem = new ImageItem();                imageItem.name = imageName;                imageItem.path = imagePath;                imageItem.size = imageSize;                imageItem.width = imageWidth;                imageItem.height = imageHeight;                imageItem.mimeType = imageMimeType;                imageItem.addTime = imageAddTime;            }        }        //回调接口,通知图片数据准备完成      //  ImagePicker.getInstance().setImageFolders(imageFolders);        loadedListener.onImagesLoaded(imageItem);    }    @Override    public void onLoaderReset(Loader<Cursor> loader) {        //System.out.println("--------");    }    /** 所有图片加载完成的回调接口 */    public interface OnImagesLoadedListener {        void onImagesLoaded(ImageItem imageItem);    }}
从cursor取出第一张图片并赋值到ImageItem上,那么这次取数据就完成了,然后回调到相应的Activity上,在Activity中这样调用:
  new ImageDataSource(this, null, this);
在回调接口中处理数据:
@Override    public void onImagesLoaded(ImageItem imageItem) {        latestImage = imageItem ;         }

2,把从库中取出的图片展示出来

展示图片用PopWindow ,自定义一个popWindow 来实现:
pop 的布局文件:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="90dp"    android:layout_height="135dp"    android:orientation="vertical"    android:background="@drawable/recommendphoto_bubble"    android:padding="5dp">    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:textSize="12sp"        android:text="你可能要发送的照片:"/>    <ImageView        android:id="@+id/recommendphoto_img"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_marginTop="2dp"        android:scaleType="centerCrop"        android:background="@drawable/recommendphoto_bg"        android:layout_marginBottom="7dp"/></LinearLayout>

布局文件很简单,就两个控件和背景,pop 的具体实现:

/** * 推荐图片提示框 刚拍完照后,显示你可能要发送的图片 * */public class RecommendPhotoPop extends PopupWindow {    /**     *     */    private ImageView iv;    /**     *     */    private static Context context;    public RecommendPhotoPop(Context context) {        this.context = context;        View view = LayoutInflater.from(context).inflate(R.layout.layout_recommendphoto_pop,null,false);        iv = (ImageView) view.findViewById(R.id.recommendphoto_img);        setContentView(view);        setWidth(dip2px(90));        setHeight(dip2px(135));        setFocusable(false);        setBackgroundDrawable(new BitmapDrawable());        // 设置点击其他地方 就消失 (只设置这个,没有效果)        setOutsideTouchable(true);    }    public  void setImgPath(final String path) {        iv.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {            }        });        Glide.with(context).load(path).crossFade().centerCrop()                .into(iv);    }    /**     * 显示图片提示     * @param context     * @param view     */    public  static  RecommendPhotoPop recommendPhoto(Context context, View view,String path) {                final RecommendPhotoPop recommendPhotoPop = new RecommendPhotoPop(context);                recommendPhotoPop.setImgPath(path);                int x = getScreenWidth(context) - dip2px(92);                int y = getScreenHeight(context) - view.getMeasuredHeight() - dip2px(138);       // recommendPhotoPop.showAsDropDown(view);               recommendPhotoPop.showAtLocation(view, Gravity.NO_GRAVITY,x,y);                return recommendPhotoPop;    }    /** dip转换px */    public  static int dip2px(int dip) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dip * scale + 0.5f);    }    /** pxz转换dip */    public static int px2dip(int px) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (px / scale + 0.5f);    }    /**     * 获得屏幕高度     *     * @param context     * @return     */    public  static int getScreenWidth(Context context) {        WindowManager wm = (WindowManager) context                .getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        return outMetrics.widthPixels;    }    /**     * 获得屏幕宽度     *     * @param context     * @return     */    public  static int getScreenHeight(Context context) {        WindowManager wm = (WindowManager) context                .getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        return outMetrics.heightPixels;    }}
这里pop也实现了,看看主Activity 的实现:

布局:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/colorPrimary"    >    <Button        android:id="@+id/btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="你想发送的图片"        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        android:layout_margin="5dp"        />    <ImageView        android:id="@+id/image"        android:layout_width="400dp"        android:layout_height="400dp" /></RelativeLayout>

代码:

public class MainActivity extends AppCompatActivity implements ImageDataSource.OnImagesLoadedListener {    private ImageView imageView ;    private Button btn ;    private ImageItem latestImage ;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        imageView = (ImageView)findViewById(R.id.image);        btn = (Button)findViewById(R.id.btn);        /**         * 申请权限         */        if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)        {            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},0 );        }else {            new ImageDataSource(this, null, this);        }        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                RecommendPhotoPop.recommendPhoto(MainActivity.this,btn,latestImage.path);            }        });        //String url = "https://ws1.sinaimg.cn/large/610dc034ly1fiednrydq8j20u011itfz.jpg";       // Glide.with(this).load(url).diskCacheStrategy(DiskCacheStrategy.ALL).into(imageView);    }    @Override    public void onImagesLoaded(ImageItem imageItem) {        latestImage = imageItem ;        Glide.with(this).load(imageItem.path).into(imageView);    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        switch (requestCode)        {            case 0:                if(grantResults[0] == PackageManager.PERMISSION_GRANTED)                {                    new ImageDataSource(this, null, this);                }                break;        }    }
附上权限和依赖:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 compile 'com.github.bumptech.glide:glide:3.7.0'


源码:高仿微信你可能要发送的图片