Android学习笔记(十九)分享简单数据

发送文本内容

   Android中使用ACTION_SEND最常用和最简单就是发送文本内容从一个Activity到另一个。例如,内嵌的浏览器可以分享当前呈现的页面的URL,作为一个文本内容和其他程序共享。
例如:
  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);
     如果安装程序有的过滤器匹配上了ACTION_SEND 并且MIME type 为 text/plain,则该Adroid应用就会启动运行起来,如果系统中有多个应用程序的过滤器接受该过滤条件,则系统就会呈现一个选择器对话框。让用户选择需要运行的程序。如下图,在我的手机中分享一张图片时弹出的选择应用对话框:

  如果调用了Intent.createChooser()方法,则会android会总是呈现选择器,这样有以下影响:
  • 即使用户之前为该intent选择了一个默认的处理程序,选择器对话框也会呈现。
  • 如果没有应用程序匹配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)));
效果图如下:
Android学习笔记(十九)分享简单数据_第1张图片

发送二进制内容

    二进制数据可以通过ACTION_SEND事件来共享,同时要设置适当的MINE类型,将URI命名Intent.EXTRA_STREAM类型的数据。 通常二进制的分享,用于图片,同时也应用于所有二进制数据的分享。
例如:
   Intent shareIntent = new Inent();
    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 type为“*/*”,但是这只会被那些能处理通用数据流的Activity匹配。
  • 接收intent的应用程序必须具有接入URI所指定的数据的权限。这里有一些方法可以获取这些许可:
    • 将数据写入所有APP可读的外部/共享存储设备上,通过Uri.formFile()来创建可以被分享的intent通过的URI。然而,不是所有的应用程序都会生成类型为 file:// 的 Uri。
    • 通过方法使用模型为MODE_WORLD_READABLE的openFileOutput() 将数据写入到应用程序的内部文件夹中的文件中。Uri.formFile()将会创建一个file:// 类型的Uri来分享你的intent.
    • 可以通过调用方法scanFile()来扫描images、videos、audio文件,并添加到系统的MediaStore中去。回调方法onScanCompleted()返回一个 content://类型的Uri
    • 可以通过insertImage()方法来向系统MediaStore中插入images,该方法会返回一个content:// 类型的Uri。注意,一旦添加到系统MediaStore设备上的任何应用程序都可以访问内容。
    • 将你的数据存储到自己的ContentProvider中,并且要确保其他Apps正确拥有访问该provider的权限。

发送多个内容

   要发送多部分的内容,应使用ACTION_SEND_MULTIPLE类型ACTION,并指定一系列的指向内容的URI。发送相同MINE类型的数据时指定同一MINE类型,发送多多种类型的图片时,使用“image/*”指定MINE 类型。如果发送不同种类的数据时应使用"*/*".例如:
 ArrayList<Uri> imageUris = new ArrayList<Uri>();
 imageUris.add(imageUri1); 
 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..."));

从其他Apps中接收内容

  通过定义intent过滤器来接收需要的intent数据。例如:
<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>
这里我们定义了三个过滤器:
第一个我们过滤出action为SEND且MineType为image/*的intent数据;
第二个我们过滤出action为SEND且mineType为text/plain的intent数据;
第三个我们过滤出mineType为action为SEND_MAULTIPLE且minetype为image/*的inten数据。
当其他应用程序要分享intent时,并调用了startActivity()方法,Android系统将会列出intent选择器,如果用户选择了你的应用程序,则相应的Activity会启动。

处理接收到的intent数据

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  Intent intent = getIntent();
  String action = intent.getAction();
  String type = intent.getType();
  if (Intent.ACTION_SEND.equals(action)) {
    if ("text/plain".equals(type)) {
	handleSendText(intent);
     } else if (type.startsWith("image/")) {
	handleSendImage(intent);
     }
  } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) {
     if (type.startsWith("image/")) {
	handleSendMultipleImages(intent);// 处理多个image文件的发送
      }
  } else {  
     // 其他类型的ACTION
   }
}
public void handleSendText(Intent intent) {
   String shareText = intent.getStringExtra(Intent.EXTRA_TEXT);
   if (shareText != null) {
      //处理获接收到的文本
   }
}
public void handleSendImage(Intent intent) {
   Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
   if (imageUri != null) {
   //处理接收到的图片
   }
}
public void handleSendMultipleImages(Intent intent) {
   ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
   if (imageUris != null) {
     //处理接收到的图片
   }
}
注意:
 特别的注意检查接收到的数据,因为,你不知道其他应用程序会发送什么数据。比如,错误的MIME type设置,或者发送的图片额外的大。同时,应该注意,在处理二进制数据时,应当在一另外一个线程中去处理,而不是在主UI的线程去处理。

添加分享菜单

 在我们的Activity中要添加分享菜单,这里我们在menu文件夹下新建一个share_menu.xml文件并添加分享的item,如下:
<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>
 这里通过android:actionProviderClass类指定了分享菜单的支持类为android.widget.ShareActionProvider
这样我们就可以在我们的Activtiy中看到设置的分享菜单了:如下图:
Android学习笔记(十九)分享简单数据_第2张图片 
 此时分享菜单不能点击(为禁用状态),这是因为我们还没有设置分享的数据,所以为仅用状态。在我们的Activity中我们通过下面的方法来设置分享数据
private ShareActionProvider mShareActionProvider;
....
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   getMenuInflater().inflate(R.menu.share_menu, menu);
   MenuItem item = menu.findItem(R.id.menu_item_share);
   //找到分享菜单的支持类对象
   mShareActionProvider  = (ShareActionProvider) item.getActionProvider();
   return true;
}
//这里来设置share的数据,设置后share菜单将可用
private void setShareIntent(Intent shareIntent) {
   if (mShareActionProvider != null) {
      mShareActionProvider.setShareIntent(shareIntent);
   }
}
 如上面在构建好需要分享的itent后调用setShareIntent方法,将intent设置到分享菜单的类提供者上。此时分享菜单就可用,我们点击后就可以分享我们intent中指定的数据了。如图:
Android学习笔记(十九)分享简单数据_第3张图片

你可能感兴趣的:(Android学习笔记(十九)分享简单数据)