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.643E.Bear and Destroying Subtrees(DP 期望)
题目链接 \(Description\) 有一棵树.Limak可以攻击树上的某棵子树,然后这棵子树上的每条边有\(\frac{1}{2}\)的概率消失.定义 若攻击以\(x\)为根的子树,高度\(ht ...
- ZOJ 2975 Kinds of Fuwas
K - Kinds of Fuwas Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu De ...
- centos7 打造基于python语言Selenium2自动化开发环境
1. 准备 安装模块 # yum groupinstall "Development tools" # yum install zlib-devel bzip2-devel ope ...
- CAP原则(CAP定理)、BASE理论
CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性),三者不可得兼. CA ...
- Graph database_neo4j 底层存储结构分析(2)
3 neo4j存储结构 neo4j 中,主要有4类节点,属性,关系等文件是以数组作为核心存储结构:同时对节点,属性,关系等类型的每个数据项都会分配一个唯一的ID,在存储时以该ID 为数组的 ...
- sublime text2 用ctags插件实现方法定位(转)
我们用sublime几乎都会首先安装这个插件,这个插件是管理插件的功能,先安装它,再安装其他插件就方便了. 点击sublime的菜单栏 view->show console :现在打开了控制台, ...
- android应用程序签名(转)
概述 Android系统要求,所有的程序经过数字签名后才能安装.Android系统使用这个证书来识别应用程序的作者,并且建立程序间的信任关系.证书不是用于用户控制哪些程序可以安装.证书不需要授权中心来 ...
- Java 与 .NET 的平台发展之争
Java 8即将正式发布,从早期版本中,我们已经可以领略到一些令人兴奋的特性.但是开发者Andrew C. Oliver表示,尽管如此,Java语言在某些特性上还是落后于.Net.比如,Java 8中 ...
- 微信emoji表情编码 、MySQL 存储 emoji 表情符号字符集
相关资料 微信emoji表情编码 微信用户名显示「emoji表情」 PHP处理微信中带Emoji表情的消息发送和接收(Unicode字符转码编码) MySQL 存储emoji表情 MySQL 存储 e ...
- C#复制数组的两种方式,以及效率比较
如何高效地进行数组复制? 如果把一个变量值复制给另外一个数组变量,那么2个变量指向托管堆上同一个引用. 如果想在托管堆上创建另外的一份数组实例,通常使用Array.Copy方法. class Prog ...