Intent 常用场景 FileProvider 拍照 裁剪

Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 [email protected]

目录

目录
常用的 Intent 场景
拍照、选择照片、裁剪照片
涉及到的权限
需要配置 FileProvider
Activity
工具类
其他简单场景
拨打电话
发送短信
发送彩信
打开浏览器
打开浏览器并搜索内容
发邮件
打开地图并定位到指定位置
路径规划
多媒体播放
打开应用在应用市场的详情页
进入手机设置界面
安装和卸载 apk
查看指定联系人
调用系统编辑添加联系人
打开另一程序
强制和某QQ聊天
打开录音机

常用的 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:[email protected]");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(intent);

详细设置

Intent intent=new Intent(Intent.ACTION_SEND);
String[] tos = {"[email protected]", "[email protected]"};
String[] ccs = {"[email protected]", "[email protected]"};
String[] bccs = {"[email protected]", "[email protected]"};
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

原文地址:https://www.cnblogs.com/baiqiantao/p/9975628.html

时间: 2024-10-07 08:54:13

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

git常用命令常用场景

在使用git之前,一直用的是svn版本管理:与svn最大不同的是,git有两个仓库,一个是本地仓库,一个是服务器上共享的仓库:本地仓库是每个开发者自己独有的,即使commit提交也只是提交到本地仓库:这只是git流行起来的一个优势之一,另外linux作者开发的这套版本管理工具,很接地气,也是流行起来的一大亮点.扯了这么多没用的,言归正卷,那么在日常开发工作中,哪些git命令是我们常用到的呢?下面就说说几个常用命令的常用场景,至于这些命令详细使用就不在本文讨论之内. 1.git命令别名 使用过gi

[Linux运维]常用场景模拟 -- cpu使用率模拟

[Linux运维]常用场景模拟 -- cpu使用率模拟 from http://www.cnblogs.com/zk47/p/4771105.html 1 单个核 100%: 代码 kill_cpu.c #include <stdlib.h> int main() { while(1); return 0; } 运行 $ gcc -o out kill_cpu.c $ ./out 看top的结果: $ top top - 15:44:08 up 207 days, 21:29, 2 users

cocos2dx 游戏开发中常用场景切换方式以及特性

runWithScene(CCScene* scene):启动游戏,并运行scene 场景.这个方法在主程序启动时第一次启动主场景时调用. replaceScene(CCScene* scene):直接使用传入的scene 替换当前场景来切换画面,当前场景将被释放.这是切换场景时 最常用的方法. pushScene(CCScene* scene):在不释放旧场景内存的情况下运行新场景,推进新场景相当于在当前可见的纸上再放一张纸,而之前的纸位置何持不变.适用情况: 1.推进一个经常被用到的场景,例

Activity的4种加载模式最佳解答及Intent常用标识

Activity的4种状态: 活动的:当一个Activity在栈顶,它是可视的.有焦点.可接受用户输入的.Android试图尽最大可能保持它活动状态,杀死其它Activity来确保当前活动Activity有足够的资源可使用.当另外一个Activity被激活,这个将会被暂停. 暂停:在很多情况下,你的Activity可视但是它没有焦点,换句话说它被暂停了.有可能原因是一个透明或者非全屏的Activity被激活. 当被暂停,一个Activity仍会当成活动状态,只不过是不可以接受用户输入.在极特殊的

Git&mdash;&mdash;常用场景解析

总结:本篇文章从初识GitHub.Git,实践GitHub的五种常用场景,分别是:git for windows安装,git配置,克隆远程代码到本地,上传本地代码到远程以及Git的常用指令.相信James已经尝到了Git的滋味. Git是什么?是版本控制工具,是协同开发的利器. "版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统:对于软件开发领域来说,版本控制是最重要的一环." 如何使用呢?首次接触Git时,James认为:大可不必去弄清楚Git的工作原理,

LogMiner常用场景

1 LogMiner常用场景 1.1 用LogMiner跟踪特定用户所做的更改 本节例子,查出用户joedevo在特定时间范围内对数据库所做的所有操作,步骤如下: 1.创建LogMiner字典 使用LogMiner分析joedevo相关的数据,必须在joedevo对它的所有表做任何的更改操作前创建LogMiner字典或者直接使用在线字典,本例使用已提取到重做日志文件中的LogMiner字典. 2.添加重做日志文件 在joedevo对数据库做了一些更改操作之后,可以指定对应的重做日志文件来分析:

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

问题描述: take photo -> 拍照 -> 确定 -> 截图 -> 保存,此时返回给onActivityResult的resultCode是0,截图无效.我查看图片储存的情况,拍完照是有存储好的,但截图后没有存储,图片变成了0byte. 原因: private void cropImageUri(Uri uri, int requestCode){Intent intent = new Intent("com.android.camera.action.CROP&

Python描述符常用场景详解

Descriptors( 描述符 ) 是语言中一个深奥但很重要的一个黑魔法,它被广泛应用于 Python 语言的内核,熟练掌握描述符将会为 Python程序员 的工具箱添加一个额外的技巧.本文将讲述描述符的定义以及一些常见的场景,并且在文末会补充一下 __getattr , __getattribute__, __getitem__ 这三个同样涉及到属性访问的魔术方法,希望对大家 学习python有所帮助. 描述符的定义 descr__get__(self, obj, objtype=None)

android隐式intent使用场景解析

Android 隐式intent相信大家都有用过,大部分场景我们用显式intent已经能满足我们的业务需求,隐式intent大部分都是用来启动系统自带的Activity或Service之类的组件.昨天有个业务场景就是,我在第三方依赖库 module A里面有个Activity A,现在需要在Activity A里面启动 module app里面的Activity B,我想了一下,可以用隐式intent来实现这个功能,而且实现代码最简洁,不用修改或添加其他代码. 隐式intent很简单,首先要在A