Android 分享文件
来源:互联网 发布:apache tomcat 6 编辑:程序博客网 时间:2024/05/16 19:43
第一部分:发送简单数据给其他App
最简单的方式是通过Intent:
比如要分享文本给其他App,可以这样
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类型,Android系统将运行它;如果有多个应用程序匹配,系统显示一个对话框(消歧“选择器”),允许用户选择一个应用程序。但是这种方式如果只有一个或者用户之前操作已经选择了默认打开该类型的App则不会显示选择对话框。如果你要总是显示选择对话框,可以这样定义: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)));
如果你要一次分享多条数据,可以使用ACTION_SEND_MULTIPLE:
比如
ArrayList<Uri> imageUris = new ArrayList<Uri>();imageUris.add(imageUri1); // Add your image URIs hereimageUris.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.."));
如果你的应用需要支持处理某种类型的数据可以在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>
处理传进来的数据,可以按照一下方式处理: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 }}
如果你要通过Actionbar菜单的方式来分享数据,可以这样menu菜单可以这样定义
<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>
在Activity中可以这样使用private ShareActionProvider mShareActionProvider;...@Overridepublic 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 intentprivate void setShareIntent(Intent shareIntent) { if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(shareIntent); }}
第二部分发送文件给App(它是通过 FileProvider来实现的
)
实现步骤如下
第一步,在xml文件加下面新建一个文件(比如名字叫filepaths)
filepaths.xml文件内容如下
<paths> <files-path path="images/" name="myimages" /></paths>
paths节点下面总共有如下子节点"root-path","files-path","cache-path","external-path","external-files-path","external-cache-path",子节点属性只有path和name。path就是共享文件路径,name就是你给当前
这个子节点分享的文件取的一个别名。
第二步就是在manifest文件下添加如下定义
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.myapp.fileprovider" android:grantUriPermissions="true" android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider>
其中meta-data属性一定要,它指定了分享文件的name,这个name是系统指定的,不能随便填写,resource指定了分享文件的xml
。
我们再在客户端的manifest文件中在显示共享文件的Activity下面添加如下配置
<activity android:name=".FileSelectActivity" android:label="@File Selector" > <intent-filter> <action android:name="android.intent.action.PICK"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.OPENABLE"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> </activity>
当别的App请求访问我们提供的文件(图片),并且我们的图片很多的时候,我们会显示一个列表(比如ListView)给它选择
,这个时候我们Item点击事件可以如下定义
protected void onCreate(Bundle savedInstanceState) {
// Set up an Intent to send back to apps that request a file mResultIntent =new Intent("com.example.myapp.ACTION_RETURN_FILE");...//set up an Intent to send back to apps that requesst a file
mResutIntent=new Intent("com.example.myapp.ACTION_RETURN_FILE") // Define a listener that responds to clicks on a file in the ListView mFileListView.setOnItemClickListener( new AdapterView.OnItemClickListener() { @Override /* * When a filename in the ListView is clicked, get its * content URI and send it to the requesting app */ public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) { /* * Get a File for the selected file name. * Assume that the file names are in the * mImageFilename array. */ File requestFile = new File(mImageFilename[position]); /* * Most file-related method calls need to be in * try-catch blocks. */ // Use the FileProvider to get a content URI try { fileUri = FileProvider.getUriForFile( MainActivity.this, "com.example.myapp.fileprovider", requestFile); } catch (IllegalArgumentException e) { Log.e("File Selector", "The selected file can't be shared: " + clickedFilename); }
} }); ... }if (fileUri != null) {// Grant temporary read permission to the content URI mResultIntent.addFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION);... // Put the Uri and MIME type in the result Intent mResultIntent.setDataAndType( fileUri, getContentResolver().getType(fileUri)); // Set the result MainActivity.this.setResult(Activity.RESULT_OK, mResultIntent); } else { mResultIntent.setDataAndType(null, ""); MainActivity.this.setResult(RESULT_CANCELED, mResultIntent); }
到这里我们服务端即共享文件端的配置已经配置好了。
接下来就是客户端的,也就是请求接受共享文件端
public class MainActivity extends Activity { private Intent mRequestFileIntent; private ParcelFileDescriptor mInputPFD; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRequestFileIntent = new Intent(Intent.ACTION_PICK); mRequestFileIntent.setType("image/jpg"); ... } ... protected void requestFile() { /** * When the user requests a file, send an Intent to the * server app. * files. */ startActivityForResult(mRequestFileIntent, 0); ... } ...}
我们接着重写client即请求共享文件App的onActivityResult回调
/* * When the Activity of the app that hosts files sets a result and calls * finish(), this method is invoked. The returned Intent contains the * content URI of a selected file. The result code indicates if the * selection worked or not. */ @Override public void onActivityResult(int requestCode, int resultCode, Intent returnIntent) { // If the selection didn't work if (resultCode != RESULT_OK) { // Exit without doing anything else return; } else { // Get the file's content URI from the incoming Intent Uri returnUri = returnIntent.getData(); /* * Try to open the file for "read" access using the * returned URI. If the file isn't found, write to the * error log and return. */ try { /* * Get the content resolver instance for this context, and use it * to get a ParcelFileDescriptor for the file. */ mInputPFD = getContentResolver().openFileDescriptor(returnUri, "r"); } catch (FileNotFoundException e) { e.printStackTrace(); Log.e("MainActivity", "File not found."); return; } // Get a regular file descriptor for the file FileDescriptor fd = mInputPFD.getFileDescriptor(); ... } }
到这里文件共享方式就完毕了.
由于这个URI不包含目录路径,客户端应用程序无法发现和服务器应用程序打开的任何其他文件。
只有客户端应用程序才可以访问该文件,并且只对服务器应用程序授予的权限进行访问。权限是临时的,
所以一旦客户端应用程序的任务堆栈完成,该文件将不再在服务器应用程序之外访问。
当接收活动的Activity等组件的堆栈处于活动状态时,在意图中授予的权限保持有效。当堆栈完成后,权限将被自动移除。
授予客户端应用程序中的一个活动的权限将自动扩展到该应用程序的其他组件。
0 0
- Android 分享单个文件
- android建立文件分享
- android 分享文件
- android分享各种文件
- Android分享文件
- Android 分享文件
- Android使用NFC分享文件
- Android 调用系统的分享界面,进行文件分享
- Android文件/文件夹批量蓝牙分享
- [Android应用] 蓝牙分享apk安装文件
- android 文件操作方法集合类分享
- android 文件操作方法集合类分享
- android studio 分享文件到github
- Android 源码分享之小米文件管理器
- android学习(十二) 分享文件 FileProvider
- 关于android 多文件分享的问题
- Android Intent分享文件|分享图片|分享文字|功能的实现
- Android 实现文件分享功能(共享多个文件)
- 创建文件判断
- 来电铃声和通话中的提示音
- 作用域是什么
- Linux下PPTPD搭建VPN服务器连接后无法上外网及619错误的解决办法
- Android Studio 使用小技巧和快捷键
- Android 分享文件
- 深度优先搜索与广度优先搜索
- XMind中关于“大图”的操作技巧(二)
- HDU 1004(map) Let the Balloon Rise
- Android客户端和Java服务器端Socket代码连的坑(接空指针异常问题)
- Hadoop中Combiner的使用
- Ubuntu安装搜狗输入法
- Java时间
- Paxos 实现日志复制同步