安卓6.0通过URI进行图片分享问题总结

来源:互联网 发布:媒体矩阵 是什么意思 编辑:程序博客网 时间:2024/05/16 04:39

首先说一下我们的需求:xml文件定义的界面,生成图片然后分享到微信朋友或者朋友圈

遇到的问题:

        1.xml文件如何在后台默默的生成一张图片?

        2.如何直接分享到微信朋友圈?

        3.安卓6.0及以上版本适配,也就是通过URI分享的问题

        一。xml文件生成图片

        其实如果一个页面我们生成一个bitmap是非常简单的,重新定义一个画布然后调用跟布局的draw方法,接收一下就可以了,但是现在的情况是我们的界面不能在界面上显示,而是需要在背后默默的生成一张图片,上面的方法就不管用了,问题是为什么呢?我们先来分析一下,界面显示出来调用的顺序的解析加在布局、测量、布局、绘制然后显示出来了,那么我们不显示只是加在布局呢?只有解析加在布局这一个过程走了,其他都没有走,所以我们需要手动调用测量、布局工作,然后再按照传统的方法调用绘制接收结果。好了,思路有了,直接上代码:

       1.xml文件如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >    <Button        android:onClick="openBlue"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="打开蓝牙开始聊天"/>    <ImageView        android:id="@+id/fl_holder"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:src="@mipmap/ic_launcher"/></LinearLayout>
2.解析加在布局:

   View rankView = inflater.inflate(R.layout.activity_main, null);
       3.然后我们需要手动测量、布局

    /**     *      * @param v 布局view     * @param width 宽度  宽度高度需要我们手动告诉     * @param height 高度     */    private void layoutView(View v, int width, int height) {        v.layout(0, 0, width, height);        int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.AT_MOST);        int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);        v.measure(measuredWidth, measuredHeight);        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());    }
4.现在可以接收最后生成的图片

    /**     * 由布局生成图片  view的宽高一定要大于0     * @param view     */    private void loadBitmapFromView(View view) {        int width = view.getWidth();        int height = view.getHeight();        bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(bitmap);        view.draw(canvas);    }
好了,第一问题解决了,我们已经拿到了布局生成的图片了,下面就是如何直接分享到微信

       二。bitmap分享到微信

由于图片大小我们首先说不是很确定,然后就是说6.0以后安卓已经不允许直接跨应用之间传递数据了,所以我们还是用最保险的思路,那就是先将图片保存到本地,然后再通过URI分享到微信

        1.保存生成的图片到本地,并且通知本地图库扫描更新媒体库

        String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) +"/hui/";        File f = new File(filePath);        if (!f.exists()) {            f.mkdirs();        }        File file = new File(f, getStringFromCalendar()+".png");
注意上面我们保存的位置很关键,因为下面我们6.0以上手机适配需要用的,图片名字随便,算了还是把方法贴出来吧:

     /**     * 图片保存的名称     *根据日期生成对应的名称     * @return     */    public  String getStringFromCalendar() {        Calendar calendar = Calendar.getInstance();        calendar.setTimeInMillis(System.currentTimeMillis());        int yearNow = calendar.get(Calendar.YEAR);        int monthNow = calendar.get(Calendar.MONTH) + 1;        int dayNow = calendar.get(Calendar.DAY_OF_MONTH);        int hourNow = calendar.get(Calendar.HOUR_OF_DAY);        int minuteNow = calendar.get(Calendar.MINUTE);        int secondNow = calendar.get(Calendar.SECOND);        int millisecond = calendar.get(Calendar.MILLISECOND);        String detailName = Integer.toString(yearNow) + Integer.toString(monthNow)                + Integer.toString(dayNow) + "_" + Integer.toString(hourNow)                + Integer.toString(minuteNow) + Integer.toString(secondNow)                + Integer.toString(millisecond);        return detailName;    }
保存图片:

    /**     * 保存位图到本地并且扫描媒体库     * @param bitmap     * @return void     */    public void SavaImage(Bitmap bitmap, File file){        FileOutputStream fileOutputStream=null;        try {            fileOutputStream = new FileOutputStream(file);            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);            fileOutputStream.close();            Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);            scanIntent.setData(Uri.fromFile(file));            sendBroadcast(scanIntent);        } catch (Exception e) {            e.printStackTrace();        }    }
2.将文件开始分享到微信:

        Uri parse = Uri.fromFile(file);        Intent intent = new Intent();        ComponentName comp;        String type = "1";        switch (type) {            case "1"://分享给好友                comp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareImgUI");                ;                break;            default://分享到朋友圈                comp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareToTimeLineUI");                break;        }        intent.setComponent(comp);        intent.setAction(Intent.ACTION_SEND);        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        intent.setType("image/*");        intent.putExtra(Intent.EXTRA_STREAM, parse);//uri为你要分享的图片的uri        startActivity(intent);
分享到微信已经成功了一半了,然并卵6.0手机直接报无法找到资源文件????什么鬼?


         三。开始进行6.0手机适配

         1.首先说需要动态申请读写权限,如果没有权限,上面保存文件会失败的,随意本地没有保存的图片,分享必然会失败

         2.最大的坑来了,URI进行适配处理

          功能清单文件添加如下(和activity平级):

        <provider            android:name="android.support.v4.content.FileProvider"            android:authorities="包名.fileProvider"            android:exported="false"            android:grantUriPermissions="true">            <meta-data                android:name="android.support.FILE_PROVIDER_PATHS"                android:resource="@xml/filepaths" />        </provider>
  res文件夹下添加xml文件夹,并且添加filepaths文件,文件中内容如下:

     <paths>          <external-path path="." name="external_storage_root" />     </paths>
好了大功告成了,现在可以了。如有不对的地方还请各位看客提出意见建议。

最后还是把demo上传到csdn了,如有需要可以下载。





1 0
原创粉丝点击