您的位置:首页 > 其它

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

2017-04-15 16:00 471 查看
首先说一下我们的需求: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了,如有需要可以下载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: