Android Intent.ACTION_SEND ——实现分享功能

本文详细介绍如何使用Android系统内置的分享功能,包括分享文本、图片和其他文件类型的基本方法。此外,还介绍了如何筛选分享目标应用及处理多种文件类型的分享。

安卓系统本身可以很简便的实现分享功能,因为我们只需向startActivity传递一个ACTION_SEND的Intent,系统就为我们弹出一个应用程序列表。其实在系统的文件管理器中,这应该是我们常用的功能(包括文件的打开Intent.ACTION_VIEW)。

下面列出一个简单的分享方式

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);

前两行代码不用说了,就是一个简单的Action Intent,第三行的Intent.EXTRA_TEXT,是文本类型,还有EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC, EXTRA_SUBJECT等等,这些看字面意思就可以理解。 
重点说一下Intent.EXTRA_STREAM。 
设置合适的MIME类型,并且在附件数据中的EXTRA_STREAM中放一个指向数据的URI,就可以来分享二进制数据。这个通常用来分享图片,但是也可以用来分享任何类型的二进制内容,比如视频,文件等等。

Intent shareIntent = newIntent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));

下面说一下Intent.setType这个方法: 
参数有很多种,简单列出几个,”text/plain”、”image/jpeg”、”audio/mp4a-latm”、”audio/x-mpeg”、 “video/mp4”还有很多很多… 
这里给出一个获取类型的方法

    /**
     * 根据文件后缀名获得对应的MIME类型。
     * @param filePath
     */
    public static String getMimeType(String filePath) {
        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        String mime = "text/plain";
        if (filePath != null) {
            try {
                mmr.setDataSource(filePath);
                mime = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
            } catch (IllegalStateException e) {
                return mime;
            } catch (IllegalArgumentException e) {
                return mime;
            } catch (RuntimeException e) {
                return mime;
            }
        }
        return mime;
    }
我们可以**同时发送多条内容**,要发送多条数据,使用ACTION_SNED_MULTIPLE和一个指向数据的URI list。MIME类型根据分享的内容不同而不同。例如,如果分享3张JPEG图片,那么类型为"image/jpeg"。如果有不同的图片类型,那么就应该用"image/*"来匹配处理不同类型图片的activity。如果要处理各种不同的类型就应该用"*/*"了。正如前面提到的,分析和处理分享是数据是接收程序的事情了。
但是需要明确的一点是,**要确保URI指向的数据要可以被接收程序访问到**。

另外一个知识点就是,我们可以对分享的App进行筛选,比如我只想分享到QQ和微信平台,不关心人人网,迅雷这样的App
可通过Intent.createChooser方法实现,
首先我们定义一个Action Intent

 

String type = getMimeType(path);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file));
            shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            shareIntent.setType(getMimeType(path));

然后获取可以用来发送该类型文件的ResolveInfo列表,也就是可以发送这种文件的应用列表信息

List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(shareIntent, 0);

通过包名筛选出我们想要的应用

ArrayList<Intent> targetIntents = new ArrayList<Intent>();
                for (ResolveInfo info : resInfo) {
                    ActivityInfo activityInfo = info.activityInfo;
                    if (activityInfo.packageName.contains("com.tencent.mobileqq")
                            ||activityInfo.packageName.contains("com.tencent.mm")) {
                        Intent intent = new Intent(Intent.ACTION_SEND);
                        intent.setPackage(activityInfo.packageName);
                        intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file));
                        intent.setClassName(activityInfo.packageName, activityInfo.name);
                        targetIntents.add(intent);
                    }


                }

最后用Intent.createChooser打开

Intent chooser = Intent.createChooser(targetIntents.remove(0), "Send mail...");
                chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{}));
                context.startActivity(chooser);

到此,利用Intent.ACTION_SEND进行分享就差不多介绍完了,是不是比申请友盟以及各个平台要方便的多…

附上源码,以作备用

   /**
     * 发送文件
     * @param context
     * @param path
     */
    public static void sendFileByOtherApp(Context context, String path) {
        File file = new File(path);
        if (file.exists()) {
            String type = getMimeType(path);
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file));
            shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            shareIntent.setType(getMimeType(path));
            List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(shareIntent, 0);
            if (!resInfo.isEmpty()) {
                ArrayList<Intent> targetIntents = new ArrayList<Intent>();
                for (ResolveInfo info : resInfo) {
                    ActivityInfo activityInfo = info.activityInfo;
                    if (activityInfo.packageName.contains("com.tencent.mobileqq")
                            ||activityInfo.packageName.contains("com.tencent.mm")) {
                        Intent intent = new Intent(Intent.ACTION_SEND);
                        intent.setPackage(activityInfo.packageName);
                        intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file));
                        intent.setClassName(activityInfo.packageName, activityInfo.name);
                        targetIntents.add(intent);
                    }


                }
                Intent chooser = Intent.createChooser(targetIntents.remove(0), "Send mail...");
                chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{}));
                context.startActivity(chooser);

            }
        }

    }

当然,我们也可以做一个Activity,像QQ微信一样,来接收文件或者wen z,只要会使用intentfilter就可以了

<intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>

然后在oncreate方法中

if (Intent.ACTION_SEND.equals(action) && type != null) {
        if ("text/plain".equals(type)) {
            handleSendText(intent); // 处理发送来的文字
        } else if (type.startsWith("image/")) {
            handleSendImage(intent); // 处理发送来的图片
        }
    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
        if (type.startsWith("image/")) {
            handleSendMultipleImages(intent); // 处理发送来的多张图片
        }
    } else {
        // 处理其他intents,比如由主屏启动
    }

这样基本用法就介绍完了,基本的分享功能差不多可以完成,但是想要分享图文内容,或者自定义分享界面,可能就需要再深度挖掘了。

转载url : https://blog.youkuaiyun.com/wuzhiguo1314/article/details/52950764

更多 Android 原生分享使用,可参考下面链接:https://blog.youkuaiyun.com/qq_27570955/article/details/52685456

但是这个界面的SurveyActivity.java:package com.example.bus; import android.os.Bundle; import android.widget.*; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.app.AlertDialog; public class SurveyActivity extends AppCompatActivity { private static final String FEEDBACK_EMAIL = "2689724318@qq.com"; // 修改为你自己的邮箱地址 private static final String EMAIL_SUBJECT = "用户调研反馈"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_survey); // 显示 ActionBar 上的返回箭头 if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setTitle("用户调研"); } // 绑定控件 RadioGroup radioGroupRating = findViewById(R.id.radioGroupRating); CheckBox cbUi = findViewById(R.id.cb_ui); CheckBox cbSpeed = findViewById(R.id.cb_speed); CheckBox cbInformation = findViewById(R.id.cb_information); CheckBox cbOther = findViewById(R.id.cb_other); EditText etSuggestion = findViewById(R.id.et_suggestion); Button btnSubmit = findViewById(R.id.btn_submit); // 提交按钮点击事件 btnSubmit.setOnClickListener(v -> { // 获取评分 int selectedId = radioGroupRating.getCheckedRadioButtonId(); String rating = "未评分"; if (selectedId == R.id.rb1) rating = "1分"; else if (selectedId == R.id.rb2) rating = "2分"; else if (selectedId == R.id.rb3) rating = "3分"; else if (selectedId == R.id.rb4) rating = "4分"; else if (selectedId == R.id.rb5) rating = "5分"; // 获取满意度选项 StringBuilder satisfaction = new StringBuilder(); if (cbUi.isChecked()) satisfaction.append("界面美观易用, "); if (cbSpeed.isChecked()) satisfaction.append("加载速度快, "); if (cbInformation.isChecked()) satisfaction.append("功能丰富实用, "); if (cbOther.isChecked()) satisfaction.append("其他, "); String satisfactionStr = satisfaction.length() > 0 ? satisfaction.substring(0, satisfaction.length() - 2) : "无"; // 获取建议 String suggestion = etSuggestion.getText().toString().trim(); if (suggestion.isEmpty()) suggestion = "无"; // 拼接邮件正文 String body = String.format( "用户调研反馈\n\n" + "【整体评分】\n%s\n\n" + "【满意项】\n%s\n\n" + "【改进建议】\n%s\n\n" + "---\n来自 Android 客户端自动提交", rating, satisfactionStr, suggestion ); // 发送邮件 sendEmail(body); }); } /** * 发送邮件核心方法 */ private void sendEmail(String body) { try { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); // 纯文本 // 设置收件人邮箱(必须为字符串数组) intent.putExtra(Intent.EXTRA_EMAIL, new String[]{FEEDBACK_EMAIL}); // 设置主题和正文 intent.putExtra(Intent.EXTRA_SUBJECT, EMAIL_SUBJECT); intent.putExtra(Intent.EXTRA_TEXT, body); // 启动系统选择器 startActivity(Intent.createChooser(intent, "选择邮件客户端")); } catch (Exception e) { Toast.makeText(this, "无法启动邮件应用,请安装Gmail、QQ邮箱等程序", Toast.LENGTH_LONG).show(); } } @Override public boolean onSupportNavigateUp() { onBackPressed(); // 执行返回操作 return true; // 表示已处理该事件 } } 为什么我调试的过程中,点击提交反馈,我的QQ邮箱没收到反馈记录呢
11-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值