Intent 常用场景 FileProvider 拍照 裁剪 MD
Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
Intent 常用场景 FileProvider 拍照 裁剪
目录
常用的 Intent 场景
拍照、选择照片、裁剪照片
涉及到的权限
需要配置 FileProvider
Activity
工具类
其他简单场景
拨打电话
发送短信
发送彩信
打开浏览器
打开浏览器并搜索内容
发邮件
打开地图并定位到指定位置
路径规划
多媒体播放
打开应用在应用市场的详情页
进入手机设置界面
安装和卸载 apk
查看指定联系人
调用系统编辑添加联系人
打开另一程序
强制和某QQ聊天
打开录音机
常用的 Intent 场景
拍照、选择照片、裁剪照片
涉及到的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
需要配置 FileProvider
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
在清单文件中声明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的更多相关文章
- Android调用系统拍照裁剪和选图功能
最近项目中用到修改用户头像的功能,基本上都是模板代码,现在简单记录一下. 调用系统拍照 private fun openCamera() { //调用相机拍照 // 创建File对象,用于存储拍照后的 ...
- Git——常用场景解析
总结:本篇文章从初识GitHub.Git,实践GitHub的五种常用场景,分别是:git for windows安装,git配置,克隆远程代码到本地,上传本地代码到远程以及Git的常用指令.相信Jam ...
- git常用命令常用场景
在使用git之前,一直用的是svn版本管理:与svn最大不同的是,git有两个仓库,一个是本地仓库,一个是服务器上共享的仓库:本地仓库是每个开发者自己独有的,即使commit提交也只是提交到本地仓库: ...
- 4.4系统,拍照-裁剪,resultCode返回0
问题描述: take photo -> 拍照 -> 确定 -> 截图 -> 保存,此时返回给onActivityResult的resultCode是0,截图无效.我查看图片储存 ...
- android隐式intent使用场景解析
Android 隐式intent相信大家都有用过,大部分场景我们用显式intent已经能满足我们的业务需求,隐式intent大部分都是用来启动系统自带的Activity或Service之类的组件.昨天 ...
- Intent常用使用汇总
方法一:调用默认的短信程序Intent intent = new Intent(Intent.ACTION_VIEW);intent.setType("vnd.android-dir/mms ...
- 超实用的 Nginx 极简教程,覆盖了常用场景
概述 什么是 Nginx? Nginx (engine x) 是一款轻量级的 Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse ...
- 超实用的Nginx极简教程,覆盖了常用场景
概述 安装与使用 安装 使用 nginx 配置实战 http 反向代理配置 负载均衡配置 网站有多个 webapp 的配置 https 反向代理配置 静态站点配置 搭建文件服务器 跨域解决方案 参考 ...
- 超实用的 Nginx 极简教程,覆盖了常用场景(转)
概述 安装与使用 安装 使用 nginx 配置实战 http 反向代理配置 负载均衡配置 网站有多个 webapp 的配置 https 反向代理配置 静态站点配置 搭建文件服务器 跨域解决方案 参考 ...
随机推荐
- Codeforces Round #281 (Div. 2) A. Vasya and Football 模拟
A. Vasya and Football 题目连接: http://codeforces.com/contest/493/problem/A Description Vasya has starte ...
- Codeforces Round #272 (Div. 2) D. Dreamoon and Sets 构造
D. Dreamoon and Sets 题目连接: http://www.codeforces.com/contest/476/problem/D Description Dreamoon like ...
- HDU 4772 Zhuge Liang's Password (2013杭州1003题,水题)
Zhuge Liang's Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- mui选择器和dom获取元素的区别(记得把mui对象转为dom对象才能调用用dom方法)
<!DOCTYPE html><html> <head><meta charset="UTF-8"><meta name=&q ...
- Programming 2D Games 读书笔记(第五章)
http://www.programming2dgames.com/chapter5.htm 示例一:Planet 真正示例的开始,首先是载入2张图片 1.Graphics添加了2个方法 load ...
- delphi Image处理
procedure ImageDrawText(ATextEdo: IGGCCADTextEDO); var oImageBitmap: TBitmap; x1,x2,y1,y2: double; b ...
- 使用java中replaceAll方法替换字符串中的反斜杠
今天在项目中使用java中replaceAll方法将字符串中的反斜杠("\")替换成空字符串(""),结果出现如下的异常: java.util.regex.Pa ...
- In House打包流程
在一个app历经数周持续开发和多个版本快速内部迭代之后,当我们需要把这个版本发布到我们实际应用场景中,面对我们真实用户去say hi时,如果自身产品在发布(内测版本)之前确实找到一些潜在切相对稳定的种 ...
- C#高级编程小结
小结 这几章主要介绍了如何使用新的dynamic类型,还讨论了编译器在遇到dynamic类型时会做什么.还讨论了DLP,可以把它包含在简单的应用程序中.并通过Pythin使用DLR,执行Python脚 ...
- sk_buff的数据预留和对齐
转自:http://blog.csdn.net/keepmovingnow/article/details/45850387 数据预留和对齐主要由skb_reserve().skb_put().skb ...