前言
如何在安卓应用里提供分享功能,将我们手机中的图片或浏览到的好文章上传到自己的网站?本文整理了一下实现方式。
分享功能分两种情形:
- 我分享给别人,我的app是分享方
- 别人分享给我, 我的app是接收方
分享的数据类型:图片、文本、链接、普通文件。
分享方的实现
在AndroidManifest.xml申明一个FileProvider:
<application>
<!-- make sure within the application tag, otherwise app will crash with XmlResourceParser errors -->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.codepath.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/fileprovider" />
</provider>
</application>
创建资源文件:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="images"
path="Pictures" />
<!--Uncomment below to share the entire application specific directory -->
<!--<external-path name="all_dirs" path="."/>-->
</paths>
然后:
// getExternalFilesDir() + "/Pictures" should match the declaration in fileprovider.xml paths
val file = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png")
// wrap File object into a content provider. NOTE: authority here should match authority in manifest declaration
val bmpUri = FileProvider.getUriForFile(MyActivity.this, "com.codepath.fileprovider", file)
最后:
val intent = Intent().apply {
this.action = Intent.ACTION_SEND
this.putExtra(Intent.EXTRA_STREAM, bmpUri)
this.type = "image/jpeg"
}
startActivity(Intent.createChooser(intent, resources.getText(R.string.send_to)))
分享文字
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "文本内容");
intent.setType("text/plain");
startActivity(intent);
分享图片
private void shareImage(Bitmap bitmap) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(mActivity.getContentResolver(), bitmap, "IMG" + Calendar.getInstance().getTime(), null));
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, uri);
mActivity.startActivity(Intent.createChooser(intent, "title"));
}
分享多图
ArrayList<Uri> imageUris = new ArrayList<>();
imageUris.add(uri);
imageUris.add(uri);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "dlgTitle"));
分享到指定平台
Intent wechatIntent = new Intent(Intent.ACTION_SEND);
wechatIntent.setPackage("com.tencent.mm");
wechatIntent.setType("text/plain");
wechatIntent.putExtra(Intent.EXTRA_TEXT, "分享到微信的内容");
startActivity(wechatIntent);
Java的参考代码
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import java.io.File;
import java.io.FileOutputStream;
public class MainActivity extends AppCompatActivity {
Button share;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
share = findViewById(R.id.share);
imageView = findViewById(R.id.shareimage);
// initialising text field where we will enter data
share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Now share image function will be called
// here we will be passing the text to share
// Getting drawable value from image
BitmapDrawable bitmapDrawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = bitmapDrawable.getBitmap();
shareImageandText(bitmap);
}
});
}
private void shareImageandText(Bitmap bitmap) {
Uri uri = getmageToShare(bitmap);
Intent intent = new Intent(Intent.ACTION_SEND);
// putting uri of image to be shared
intent.putExtra(Intent.EXTRA_STREAM, uri);
// adding text to share
intent.putExtra(Intent.EXTRA_TEXT, "Sharing Image");
// Add subject Here
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject Here");
// setting type to image
intent.setType("image/png");
// calling startactivity() to share
startActivity(Intent.createChooser(intent, "Share Via"));
}
// Retrieving the url to share
private Uri getmageToShare(Bitmap bitmap) {
File imagefolder = new File(getCacheDir(), "images");
Uri uri = null;
try {
imagefolder.mkdirs();
File file = new File(imagefolder, "shared_image.png");
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, outputStream);
outputStream.flush();
outputStream.close();
uri = FileProvider.getUriForFile(this, "com.anni.shareimage.fileprovider", file);
} catch (Exception e) {
Toast.makeText(this, "" + e.getMessage(), Toast.LENGTH_LONG).show();
}
return uri;
}
}
接收方的实现
当另一个应用尝试通过构建 intent 并将它传递给 startActivity() 来共享任何这些内容时,你的应用都将在 Android Sharesheet 或 intent 解析器中列为一个选项。如果用户选择您的应用,相应的Activity将会启动。然后,您需要在自己的代码和界面中妥当处理相关内容。
首先,定义你的Activity:
<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>
在MyActivity中处理传入的内容:
override fun onCreate(savedInstanceState: Bundle?) {
...
when {
intent?.action == Intent.ACTION_SEND -> {
if ("text/plain" == intent.type) {
handleSendText(intent) // Handle text being sent
} else if (intent.type?.startsWith("image/") == true) {
handleSendImage(intent) // Handle single image being sent
}
}
intent?.action == Intent.ACTION_SEND_MULTIPLE
&& intent.type?.startsWith("image/") == true -> {
handleSendMultipleImages(intent) // Handle multiple images being sent
}
else -> {
// Handle other intents, such as being started from the home screen
}
}
...
}
private fun handleSendText(intent: Intent) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
// Update UI to reflect text being shared
}
}
private fun handleSendImage(intent: Intent) {
(intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let {
// Update UI to reflect image being shared
}
}
private fun handleSendMultipleImages(intent: Intent) {
intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let {
// Update UI to reflect multiple images being shared
}
}
参考文档
- https://developer.android.com/training/sharing/receive?hl=zh-cn
- https://juejin.cn/post/6844904104389509134
- https://github.com/wangtaoT/receiveShareDemo