Android开发培训(05)--创建数据共享

第一章 分享简单的数据

android程序一件很不错的事情就是可以和不同的程序进行数据共享。为什么要构造不属于程序的核心呢?

这章主要讲述你可以在不同的程序间通过Intent和ActionProvider发送和接收数据。

1. 向其它程序发送简单的数据

当你创建一个intent的时候,你应该指定你的intent将要触发的操作。android定义了许多的动作,其中包括ACTION_SEND,就像你猜的那样,表明这个intent可以向其它的activity发送数据,甚至是向其它程序发送数据。向其它的activity发送数据很简单,所有你需要做的就是指定数据,和它的类型,系统会识别出可以接收处理的程序,然后把这些程序呈现给用户供用户选择,如果只有一个程序的话,系统就会直接打开那个程序。同样的,你可以在manifest中指定相关的内容,接收其它的activity向你发送的数据。

通过intent在不同的程序间发送数据是最常用的方式,intent可以快速地传递用户的数据简单地向用户最喜欢的app分享数据。

注意最佳的分享数据的方式在在ActionBar中使用ShareActionProvider。

2. 发送文本消息

这直接和普通的使用ACTION_SEND方式是从一个activity向另一个activity发送文本内容。比如,内置的浏览器可以向其它的任何程序分享现在网址所显示的网页。

这是非常有用的,比如通过email或者是社交网络分享一片文章或者网站,下面是一个实现的例子

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);
如果这里有一个app它的过滤器中含有ACTION_SEND和mine类型是text/plain,安卓系统就会运行它。如果这里多余一个app可供选择,那么系统就会把这些app给用户选择。

但是,如果你调用Intent.createChooser(),传递你的Intent对象,你总是会显示选择器,这样做有以下的好处:

不管用户之前有没有设置默认的程序,它都会把选择器给用户选择。

如果没有程序可供选择,那么Android系统就会提示一些系统信息。

你可以制定选择器的标题。

下面是更新的代码

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));

可供选择的,下面是一个标准的intent携带信息:EXTRA_EMAIL,EXTRA_CC,EXTRA_BCC,EXTRA_SUBJECT。 如果接收程序没有去使用他们,那么它们会忽略这些信息。

注意一些邮箱app,比如gmail,会从intent的extra的EXTRA_EMAIL, EXTRA_CC, 中得到字符串数组。

3. 发送二进制内容

二进制数据通常使用ACTION和MINE结合的方式向其它的activity发送,会把uri数据放置在额外内容中,EXTRA命名为EXTRA_STREAM,下面是一个分享图片的最常见的使用,但是可以用来分享其它的任何二进制内容。

Intent shareIntent = new Intent();
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)));
需要注意下面的内容:

你可以使用"*/*"为mime类型,但是这只会匹配普通的数据资源。

接收的对象需要权限去获取指定的Uri内容,建议的做法是如下:

将你要分享的数据存储在你自己的ContentProvider中,确保其它的程序有权限获取你的provider.通常的机制是通过per_URI permission,它会确保接收数据的程序有暂时的访问权限。一个简单的方法就是使用FileProvider帮组类创建一个ContentProvider实例。

使用系统MediaStore,这个MediaStore主要是针对视频,音频图片文件。文件可以通过MediaStore的scanFile函数,里面传递content://的Uri进行分享。

4. 发送很多的内容

为了分享更多的数据,可以使用ACTION_SEND_MULTIPLE动作和一系列的只向这个内容的uri,这个MIME类型可以各种各样。比如你分享3张JPEG图片,那么图片还是"image/jpeg".对于其它的混合图片类型,它可以是“image/*"去匹配可以处理这种类型的数据。你只有在分享多种数据类型的时候才会使用"*/*"这种类型,下面是一个程序片段:

ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1); // Add your image URIs here
imageUris.add(imageUri2);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "Share images to.."));

第二章 从其它的程序中接收数据

就像你可以给其它啊程序发送数据那样,你也可以接收其它程序的数据。想象别的程序怎么和你的程序打交道,你想从别的程序中的到什么样的数据类型。比如,一个社交网络程序会对一个文本雷人,一个有趣的网址,感兴趣。Google+会接收文本,单张图片或者多张图片。使用这个app,用户很容易就可以从gallery app中开启一个新的Google+程序。

1. 更新你的Manifest文件

intent过滤器告诉系统它能过接收什么样的intent。像之前的文章你构建intent那样,你可以创建intent 过滤器,这样就可以接收其它程序的动作。你使用<intent-filter>元素在你的manifest文件中定义intent filter文件。比如,如果你的程序可以接收处理文本内容,或者其它的图片内容,那么你的manifest文件看起来应该是这样子的。

<activity android:name=".ui.MyActivity" >
    <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>
</activity>
当其它的程序要分享那些内容构建intent并且通过startActivity启动的时候,你的程序就会被intent 选择器列出来供用户选择。如果用户选择你的程序,那么对应的(.ui.MyActivity)Activity就会被启动,然后你需要写合适的程序处理这些内容。

2. 处理发送过来的intent

为了处理通过Intent发送过来的内容,你可以通过getIntent获取一个intent对象。一旦你有了这个对象,你可以检查它的内容,然后在决定下一步怎么做。记住入股这个Activity可以被别的程序启动,你需要把intent考虑进去。

void onCreate (Bundle savedInstanceState) {
    ...
    // Get intent, action and MIME type
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_SEND.equals(action) && type != null) {
        if ("text/plain".equals(type)) {
            handleSendText(intent); // Handle text being sent
        } else if (type.startsWith("image/")) {
            handleSendImage(intent); // Handle single image being sent
        }
    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
        if (type.startsWith("image/")) {
            handleSendMultipleImages(intent); // Handle multiple images being sent
        }
    } else {
        // Handle other intents, such as being started from the home screen
    }
    ...
}

void handleSendText(Intent intent) {
    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
    if (sharedText != null) {
        // Update UI to reflect text being shared
    }
}

void handleSendImage(Intent intent) {
    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (imageUri != null) {
        // Update UI to reflect image being shared
    }
}

void handleSendMultipleImages(Intent intent) {
    ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    if (imageUris != null) {
        // Update UI to reflect multiple images being shared
    }
}
注意:检查传送过来的数据的时候需要格外的小心,你永远不知道别数据给你传送了什么。比如错误的mine类型,或者是超大的文件。记住不要在UI线程上做这些事情,应该单独开一个线程处理这些数据。

更新一个ui可以很简单就像弹出一个编辑框,也可以很复杂就像是处理一个有趣的照片,这些都是取决于你的程序想怎么做。


第三章  增加一个简单的分享动作

在你的ActionBar实现一个有效的用户友好的分享按键。一个AnctionProvider, 一旦添加到你的列表中,可以对他进行外观和行为的改造。

在ShareActionProvider中,你提供一个分享的intent,r然后这个分享做了其余的事情。

1. 更新菜单申明

开启一个ShareActionProviders,你需要定于android:actionProviderClass属性,

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
            android:id="@+id/menu_item_share"
            android:showAsAction="ifRoom"
            android:title="Share"
            android:actionProviderClass=
                "android.widget.ShareActionProvider" />
    ...
</menu>
你还要高数provider你需要分享什么东西。

2. 设置分享intent

为了使ShareActionProvider工作,你必须提供一个share intent, 这个分享intent和你之前文章中描述的一样,有ACTION_SEND和其它的一些数据。为了分享intent,你首先需要找到Activity或者fragment对应的MenuItem,接下来通过MenuItem.getActionProvider()接收到一个ShareActionProvider实例,然后使用setShareIntent来根性你的分享intent,下面是一个示例

private ShareActionProvider mShareActionProvider;
...

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate menu resource file.
    getMenuInflater().inflate(R.menu.share_menu, menu);

    // Locate MenuItem with ShareActionProvider
    MenuItem item = menu.findItem(R.id.menu_item_share);

    // Fetch and store ShareActionProvider
    mShareActionProvider = (ShareActionProvider) item.getActionProvider();

    // Return true to display menu
    return true;
}

// Call to update the share intent
private void setShareIntent(Intent shareIntent) {
    if (mShareActionProvider != null) {
        mShareActionProvider.setShareIntent(shareIntent);
    }
}

你可以在很多时候更新你的内容,比如你向设置信息,或者更新ui,比如你想在gallery app中全屏查看照片,你就可以通过share intent 跳转到那个界面上。

更多的信息请参考ShareActionProvider 对象。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值