Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

Intent 常用场景 FileProvider 拍照 裁剪


目录

常用的 Intent 场景

拍照、选择照片、裁剪照片

涉及到的权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

需要配置 FileProvider

在清单文件中声明FileProvider:

<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>

res/xml/下添加file_paths.xml配置文件

<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="files"
path="/"/>
<cache-path
name="cache"
path="/"/>
<external-path
name="external"
path="/"/>
<external-files-path
name="external_file_path"
path="/"/>
<external-cache-path
name="external_cache_path"
path="/"/>
<!--<external-media-path
name="external-media-path"
path=""/>-->
</paths>

Activity

public class MainActivity extends ListActivity {
public static final String PATH = Environment.getExternalStorageDirectory().getPath() + File.separator;
public static final String SAVE_FILE_NAME = "savePic.png";
public static final String CROP_FILE_NAME = "cropPic.png"; public static final int REQUEST_CODE_GET_IMG = 1;
public static final int REQUEST_CODE_SAVE_IMG = 2;
public static final int REQUEST_CODE_PICK_IMG = 3; public static final int REQUEST_CODE_CROP_FALSE = 4;
public static final int REQUEST_CODE_CROP_TRUE = 5; public static final int REQUEST_CODE_PICK_CROP_TRUE = 6; private ImageView imageView;
private File saveFile;
private File cropFile; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {
"调用系统相机拍照,并返回拍摄的照片,获取的是裁剪后的小图",
"调用系统相机拍照,并保存照片到指定位置,保存的为原图",
"调用图库获取照片,并返回选择的照片",
"调用图库裁剪照片,并保存照片到指定位置",
"调用图库裁剪照片,并返回裁剪后的照片,不保证一定能成功",
"调用图库获取照片,并返回选择的照片,然后调用图库裁剪照片,并保存照片到指定位置",};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(array)));
imageView = new ImageView(this);
getListView().addFooterView(imageView); saveFile = new File(PATH + SAVE_FILE_NAME);
cropFile = new File(PATH + CROP_FILE_NAME);
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
switch (position) {
case 0://调用系统相机拍照,并返回拍摄的照片,获取的是裁剪后的小图
Intent getCameraPicIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(getCameraPicIntent, REQUEST_CODE_GET_IMG);
break;
case 1://调用系统相机拍照,并保存照片到指定位置,保存的为原图
Uri saveUri = Utils.getFileUri(this, saveFile);
Intent saveCameraPicIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
saveCameraPicIntent.putExtra(MediaStore.EXTRA_OUTPUT, saveUri);
startActivityForResult(saveCameraPicIntent, REQUEST_CODE_SAVE_IMG);
break;
case 2: //调用图库获取照片,并返回选择的照片
Intent pickIntent = new Intent(Intent.ACTION_PICK);
pickIntent.setType("image/*");
startActivityForResult(pickIntent, REQUEST_CODE_PICK_IMG);
break;
case 3: //调用图库裁剪照片,并保存照片到指定位置
Uri dataUri = Utils.getFileUri(this, saveFile);
Intent cropPicIntent = Utils.getCropImageNotReturnDataIntent(dataUri, 400, 400, cropFile);
startActivityForResult(cropPicIntent, REQUEST_CODE_CROP_FALSE);
break;
case 4: //调用图库裁剪照片,并返回裁剪后的照片,不保证一定能成功,特别是大于 200 *200 时通常都会失败
Intent cropPicIntent2 = Utils.getCropImageReturnDataIntent(Utils.getFileUri(this, saveFile), 200, 200);
startActivityForResult(cropPicIntent2, REQUEST_CODE_CROP_TRUE);
break;
case 5: //调用图库获取照片,并返回选择的照片,然后调用图库裁剪照片,并保存照片到指定位置
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_PICK_CROP_TRUE);
break;
default:
break;
}
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) {
Toast.makeText(this, "没有成功返回", Toast.LENGTH_SHORT).show();
return;
}
switch (requestCode) {
case REQUEST_CODE_GET_IMG://调用系统相机拍照,并返回拍摄的照片,获取的是裁剪后的小图
if (data != null && data.getExtras() != null) {
Bitmap dataBitmap = (Bitmap) data.getExtras().get("data");// 注意,拍摄的照片会自动进行压缩,且会压缩的非常非常小!
if (dataBitmap != null) {
imageView.setImageBitmap(dataBitmap);//返回的是Bitmap,因为有大小限制,所以会压缩
showToast("尺寸为" + dataBitmap.getWidth() + " * " + dataBitmap.getHeight()); //188 * 252
}
}
break;
case REQUEST_CODE_SAVE_IMG://调用系统相机拍照,并保存照片到指定位置,保存的为原图
showToast("照片已保存到指定的Uri中");//注意,由于数据已保存到Uri中,所以这里返回的 data 为 null
imageView.setImageBitmap(BitmapFactory.decodeFile(saveFile.getAbsolutePath()));
break;
case REQUEST_CODE_PICK_IMG://调用图库获取照片,并返回选择的照片
if (data != null && data.getData() != null) {
showToast("选择的照片:" + data.getData().toString());//【content://media/external/images/media/247778】
imageView.setImageURI(data.getData());
}
break;
case REQUEST_CODE_CROP_FALSE: //调用图库裁剪照片,并保存照片到指定位置
showToast("剪切后的照片已保存到指定的Uri中");
imageView.setImageBitmap(BitmapFactory.decodeFile(cropFile.getAbsolutePath()));
break;
case REQUEST_CODE_CROP_TRUE: //调用图库裁剪照片,并返回裁剪后的照片,不保证一定能成功
if (data != null) {
Bitmap cropBitmap = data.getParcelableExtra("data");
if (cropBitmap != null) {
imageView.setImageBitmap(cropBitmap);
showToast("尺寸为" + cropBitmap.getWidth() + " * " + cropBitmap.getHeight());
}
}
break;
case REQUEST_CODE_PICK_CROP_TRUE://调用图库获取照片,并返回选择的照片,然后调用图库裁剪照片,并保存照片到指定位置
if (data != null && data.getData() != null) {
Intent cropPicIntent = Utils.getCropImageNotReturnDataIntent(data.getData(), 400, 400, cropFile);
startActivityForResult(cropPicIntent, REQUEST_CODE_CROP_FALSE);
}
break;
default:
break;
}
} private void showToast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
}

工具类

public class Utils {
public static Uri getFileUri(Context context, File saveFile) {
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String authority = context.getPackageName() + ".fileprovider"; //【清单文件中provider的authorities属性的值】
uri = FileProvider.getUriForFile(context, authority, saveFile);
} else {
uri = Uri.fromFile(saveFile);
}
Log.i("bqt", "【uri】" + uri);//【content://{$authority}/files/bqt/temp】或【file:///storage/emulated/0/bqt/temp】
return uri;
} /**
* 调出图库APP的裁剪图片功能,将指定Uri中的图片裁剪为指定大小,裁剪的图片会在 onActivityResult 中的 intent 中返回
* 经过测试发现,这种方式在 7.0 之后不能用了!
*/
public static Intent getCropImageReturnDataIntent(Uri dataUri, int desWidth, int desHeight) {
Intent intent = getCropImageIntent(dataUri, desWidth, desHeight);
//设置为true时,裁剪的图片不会在给定的 uri 中返回,而会在 onActivityResult 中的 intent 中返回
intent.putExtra("return-data", true);
return intent;
} /**
* 调出图库APP的裁剪图片功能,将指定Uri中的图片裁剪为指定大小,裁剪的图片会保存到指定的 uri 中
*/
public static Intent getCropImageNotReturnDataIntent(Uri dataUri, int desWidth, int desHeight, File cropFile) {
Intent intent = getCropImageIntent(dataUri, desWidth, desHeight);
//设置为false时,裁剪的图片会保存到指定的 uri 中,而不会在 onActivityResult 中的 intent 中返回
intent.putExtra("return-data", false);
// 注意:若裁减时打开图片的 uri 与保存图片的 uri 相同,会产生冲突,导致裁减完成后图片的大小变成0Byte
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cropFile));
return intent;
} private static Intent getCropImageIntent(Uri dataUri, int desWidth, int desHeight) {
Intent intent = new Intent("com.android.camera.action.CROP");//指定action是使用系统图库裁剪图片
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //必须加这个临时权限
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(dataUri, "image/*");
intent.putExtra("crop", "true");//可裁剪
intent.putExtra("aspectX", 1);//设置裁剪比例及裁剪图片的具体宽高
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", desWidth);
intent.putExtra("outputY", desHeight);
intent.putExtra("scale", true);//设置是否允许拉伸
intent.putExtra("scaleUpIfNeeded", true);//没什么作用
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//设置输出格式
intent.putExtra("noFaceDetection", true);//设置是否需要人脸识别
return intent;
}
}

其他简单场景

拨打电话

intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:10086"));//打开系统默认拨号程序,不需要权限
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:10000"));//直接呼叫号码,权限:CALL_PHONE
startActivity(intent);

发送短信

Uri uri = Uri.parse("smsto:10086");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "Hello");
startActivity(intent);

发送彩信

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra("sms_body", "Hello");
Uri uri = Uri.parse("content://media/external/images/media/23");//或Uri.parse("file:///sdcard/a.png")
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("image/png");
startActivity(intent);

打开浏览器

Uri uri = Uri.parse("http://www.baidu.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

打开浏览器并搜索内容

Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY,"searchString");//通过浏览器默认搜索引擎搜索内容
startActivity(intent);

发邮件

使用默认邮件应用的默认账户发邮件

Uri uri = Uri.parse("mailto:someone@domain.com");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(intent);

详细设置

Intent intent=new Intent(Intent.ACTION_SEND);
String[] tos = {"1@abc.com", "2@abc.com"};
String[] ccs = {"3@abc.com", "4@abc.com"};
String[] bccs = {"5@abc.com", "6@abc.com"};
intent.putExtra(Intent.EXTRA_EMAIL, tos);// 收件人
intent.putExtra(Intent.EXTRA_CC, ccs); // 抄送
intent.putExtra(Intent.EXTRA_BCC, bccs);// 密送
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");//主题
intent.putExtra(Intent.EXTRA_TEXT, "Hello");//内容
intent.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/eoe.mp3");//附件
intent.setType("message/rfc822"); //或 "text/plain" 或 "audio/mp3"
startActivity(intent);

打开地图并定位到指定位置

Uri uri = Uri.parse("geo:39.9,116.3");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

路径规划

Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9 116.3&daddr=31.2 121.4");//从A地到B地
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

多媒体播放

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/foo.mp3");
intent.setDataAndType(uri, "audio/mp3");//类型Type可以指定为 audio/x-mpeg ,或者不指定也行
startActivity(intent);

获取SD卡下所有音频文件,然后播放第一首

Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

打开应用在应用市场的详情页

Uri uri = Uri.parse("market://details?id=" + "包名"); //搜索应用为 Uri.parse("market://search?q=pname:包名");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

进入手机设置界面

Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
startActivityForResult(intent, 0);

安装和卸载 apk

安装 apk

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + path + "a.apk"), "application/vnd.android.package-archive");
startActivity(intent);

卸载apk

Uri uri = Uri.fromParts("package", strPackageName, null);
Intent it = new Intent(Intent.ACTION_DELETE, uri);
startActivity(it);

查看指定联系人

Uri personUri = ;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(ContentUris.withAppendedId(People.CONTENT_URI, info.id));//联系人ID
startActivity(intent);

调用系统编辑添加联系人

Intent it = newIntent(Intent.ACTION_INSERT_OR_EDIT);
it.setType(Contacts.CONTENT_ITEM_TYPE);
it.putExtra(Contacts.Intents.Insert.NAME, "My Name");
it.putExtra(Contacts.Intents.Insert.COMPANY, "organization");
it.putExtra(Contacts.Intents.Insert.EMAIL,"email");
it.putExtra(Contacts.Intents.Insert.EMAIL_TYPE, Contacts.ContactMethodsColumns.TYPE_WORK);
it.putExtra(Contacts.Intents.Insert.PHONE,"homePhone");
it.putExtra(Contacts.Intents.Insert.PHONE_TYPE,Contacts.PhonesColumns.TYPE_MOBILE);
it.putExtra(Contacts.Intents.Insert.SECONDARY_PHONE,"mobilePhone");
it.putExtra(Contacts.Intents.Insert.TERTIARY_PHONE,"workPhone");
it.putExtra(Contacts.Intents.Insert.JOB_TITLE,"title");
startActivity(it);

打开另一程序

Intent intent = new Intent();
intent.setComponent(new ComponentName(context.getPackageName(), "com.xiaomi.mipushdemo.MainActivity"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intent.setAction("android.intent.action.MAIN");
startActivity(intent);

方式2

boolean exists =new File("/data/data/" + "包名").exists();//判断是否安装目标应用
if (exists) {
Intent intent = getPackageManager().getLaunchIntentForPackage("包名");
startActivity(intent);
}

强制和某QQ聊天

String qqNo = "909120849";
String qqUri = "mqqwpa://im/chat?chat_type=wpa&uin=" + qqNo + "&version=1";
Uri uri = Uri.parse(qqUri);
intent = new Intent(Intent.ACTION_VIEW, uri);//跳转到QQ,并直接进入到和指定QQ号码聊天的界面,且可以是陌生人的QQ号
startActivity(intent);

打开录音机

Intent mi = new Intent(Media.RECORD_SOUND_ACTION);
startActivity(mi);

2018-11-17

Intent 常用场景 FileProvider 拍照 裁剪 MD的更多相关文章

  1. Android调用系统拍照裁剪和选图功能

    最近项目中用到修改用户头像的功能,基本上都是模板代码,现在简单记录一下. 调用系统拍照 private fun openCamera() { //调用相机拍照 // 创建File对象,用于存储拍照后的 ...

  2. Git——常用场景解析

    总结:本篇文章从初识GitHub.Git,实践GitHub的五种常用场景,分别是:git for windows安装,git配置,克隆远程代码到本地,上传本地代码到远程以及Git的常用指令.相信Jam ...

  3. git常用命令常用场景

    在使用git之前,一直用的是svn版本管理:与svn最大不同的是,git有两个仓库,一个是本地仓库,一个是服务器上共享的仓库:本地仓库是每个开发者自己独有的,即使commit提交也只是提交到本地仓库: ...

  4. 4.4系统,拍照-裁剪,resultCode返回0

    问题描述: take photo -> 拍照 -> 确定 -> 截图 -> 保存,此时返回给onActivityResult的resultCode是0,截图无效.我查看图片储存 ...

  5. android隐式intent使用场景解析

    Android 隐式intent相信大家都有用过,大部分场景我们用显式intent已经能满足我们的业务需求,隐式intent大部分都是用来启动系统自带的Activity或Service之类的组件.昨天 ...

  6. Intent常用使用汇总

    方法一:调用默认的短信程序Intent intent = new Intent(Intent.ACTION_VIEW);intent.setType("vnd.android-dir/mms ...

  7. 超实用的 Nginx 极简教程,覆盖了常用场景

    概述 什么是 Nginx? Nginx (engine x) 是一款轻量级的 Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse ...

  8. 超实用的Nginx极简教程,覆盖了常用场景

    概述 安装与使用 安装 使用 nginx 配置实战 http 反向代理配置 负载均衡配置 网站有多个 webapp 的配置 https 反向代理配置 静态站点配置 搭建文件服务器 跨域解决方案 参考 ...

  9. 超实用的 Nginx 极简教程,覆盖了常用场景(转)

    概述 安装与使用 安装 使用 nginx 配置实战 http 反向代理配置 负载均衡配置 网站有多个 webapp 的配置 https 反向代理配置 静态站点配置 搭建文件服务器 跨域解决方案 参考 ...

随机推荐

  1. Linux学习笔记01—安装LInux系统

    1.首先,使用光驱或U盘或你下载的Linux ISO文件进行安装. 界面说明: Install or upgrade an existing system 安装或升级现有的系统 install sys ...

  2. 【原】getInputStream()与getParameterMap()获得Post请求的数据区别

    [前言] 最近在写一个接口,写好以后想测试,自己写ajax(Post方法)来调用接口倒是可以用action所在类的属性的get/set方法获得数据.但是不只是页面的ajax会调用这个接口,还有外系统会 ...

  3. SlickMaster.NET 开源表单设计器快速使用指南

    前言:在企业数据处理过程中,经常需要通过定制表单来输入业务数据.由于涉及的数据比较离散,并不同于ERP系统的紧密关联数据.假如由开发人员每个增加页面,工作量会比较大,后期后期的维护很升级也耗费时间和精 ...

  4. [原创]浅谈H5页面性能测试

    [原创]浅谈H5页面性能测试 H5页面我想各位都不陌生,随着移动互联网兴起,不管是App,还是H5都火起来了,最突出的2个表现是ios/android/前端等工程师薪水大涨,尤其是资深前端工程师40W ...

  5. Java中static、final用法小结(转)

    一.final 1.final变量: 当你在类中定义变量时,在其前面加上final关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对基本类型来说是其值不可变,而对于对象变量来说其引 ...

  6. TIMER门控模式控制PWM输出长度

    TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TI ...

  7. MUI框架之输入框Input

    input输入框的官方api文档:http://dev.dcloud.net.cn/mui/ui/#input 一.输入框类型 输入框的类型是根据type来决定是普通输入框还是密码框,搜索框等类型 & ...

  8. linux内核数据包转发流程(二):中断

    [版权声明:转载请保留出处:blog.csdn.net/gentleliu.邮箱:shallnew*163.com] 内核在处理2层数据包之前,必须先处理中断系统.设立中断系统,才有可能每秒处理成千的 ...

  9. [Git]git教程

    摘要 目前公司项目逐渐都要迁移到git上,使用git进行版本控制及源代码管理. git学习资料 一个小时学会Git 权威Git书籍ProGit(中文版) git官网:http://git-scm.co ...

  10. How do I debug a published XBAP file in VS2010?

    I need to debug a full-trust application either by specifying a URL or, ideally, from within the web ...