FileProvider的Server和Client
来源:互联网 发布:栗山千明知乎 编辑:程序博客网 时间:2024/05/16 12:33
实例1
ServerTest
当你配置了FileProvider,且当有应用向你请求文件时,你需提供一个窗体,该窗体能实现如下功能:(三步)
→可以被请求文件的应用唤起(就是能被隐式Intent唤起)。
→将自己能够分享的文件显示在窗体里(你可以用ListView实现,安卓官方教程也以这个控件作为例子实现)。
→当用户点击了某个文件,该窗体能提供这个文件的URL(就是将URL返回给调用他的窗体)。
配置清单文件的过滤器
AndroidManifest.xml
<activity android:name=".ShowFile" android:label="@string/title_activity_show_file" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.PICK"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter></activity><provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.servertest.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /></provider>
在res里面创建一个xml文件夹,在里面再创建一个file_paths.xml
<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path="/images"/></paths>
content_show_file.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/file_list" android:layout_width="match_parent" android:layout_height="wrap_content"/></LinearLayout>
showFile.class
通过配置ListView实现(我的代码将分享的路径:手机内存/files/images/ )
public class ShowFile extends AppCompatActivity { private File filesDir;//他将指向内存路径files private File imageDir;//指向images子路径的:files/images private File[] imageFiles;//images子路径的所有文件 private String[] imageFileNames;//images子路径的所有文件名字 private Uri fileUri;//image图片地址 private Intent resultIntent;//返回的intent @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.content_show_file); //获取ListView ListView fileListView = (ListView)findViewById(R.id.file_list); //设置Intent resultIntent = new Intent("com.example.clienttest.ACTION_RETURN_FILE"); //获取文件路径以及名字 filesDir = Environment.getExternalStorageDirectory(); imageDir = new File(filesDir, "images"); //判断目录是否存在 if(!imageDir.exists()){ imageDir.mkdirs(); try{ File file = new File(imageDir,"picture.jpg"); OutputStream out = new FileOutputStream(file); Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.picture); //把drawable下的图片拷贝到sdcard的images目录下 bitmap.compress(Bitmap.CompressFormat.JPEG,90,out); out.flush(); out.close(); }catch (IOException e){ e.printStackTrace(); } } //获取images子路径下所有文件 imageFiles = imageDir.listFiles(); //将文件的名字装填 imageFileNames = new String[imageFiles.length]; for(int i = 0; i<imageFiles.length; i++){ imageFileNames[i] = imageFiles[i].getName(); } /* 通过ListView将文件的名字显示出来 同时设置ListView响应用户对文件的选择 */ fileListView.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,imageFileNames)); fileListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int postion, long l) { Log.e("server","1"); File requestFile = new File(imageDir,imageFileNames[postion]); try{ //标识为"com.example.servertest.provider"的FileProvider获取到文件requestFile,并返回被封装过的URI fileUri = FileProvider.getUriForFile(ShowFile.this, "com.example.servertest.fileprovider",requestFile); }catch (Exception e){ e.printStackTrace(); } /* 当用户选择了某个文件,而且服务器成功地得到文件的URI,将URI返回给客户端。 */ if(fileUri!=null){ //为RUI添加访问权限 resultIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //设置数据以及数据类型 resultIntent.setDataAndType(fileUri,getContentResolver().getType(fileUri)); ShowFile.this.setResult(RESULT_OK,resultIntent); finish(); } else { resultIntent.setDataAndType(null,""); ShowFile.this.setResult(RESULT_CANCELED,resultIntent); finish(); } } }); }}
现在,服务器的设置已经完成,当有应用需要请求文件,你将可以将你自己的文件给提供出去
△总结:到底服务器都做了什么
→配置FileProvider,指定authorities,指定可分享文件的那个路径(通过配置xml文件)。
→配置,使他能被客户端的隐式Intent唤起。
→配置ListView,当服务器被唤起时,提供一个可被分享的文件的列表。
→配置点击事件响应,当客户端选择文件,生成文件的URI,同时提供相关权限,并且将该文件的URI给客户端(setResult()方法)。
ClientTest
概述:客户端即请求获取某些文件的应用程序。
客户端要做些什么:
→配置Intent,指定客户端想请求访问什么文件
(1)intent.setAction(Intent.ACTION_PICK);
(2)intent.setType(“image/*”);
→启动访问:当用户想访问某些文件,一般情况下,应当是在某个按钮点击事件响应函数里面执行:执行方法: startActivityForResult(intent, 0);
→当服务器提供了想要的文件,客户端要处理自己所得到的文件。
onActivityResult(int requestCode, int resultCode, Intent returnIntent);
方法里面,returnIntent参数,他带着从服务器里返回来的文件URL,通过他来打开我们想访问的文件
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="com.example.clienttest.ACTION_RETURN_FILE"/> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="获取图片"/> <TextView android:id="@+id/file_uri" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/file_type" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/file_name" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/file_size" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/imageview" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
MainActivity.class
public class MainActivity extends AppCompatActivity { private TextView fileUri; private TextView fileType; private TextView fileName; private TextView fileSize; private ImageView imageView; private Intent requestIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestIntent = new Intent(Intent.ACTION_PICK); requestIntent.setType("image/jpg"); Button button = (Button) findViewById(R.id.button); fileUri = (TextView) findViewById(R.id.file_uri); fileType = (TextView) findViewById(R.id.file_type); fileName = (TextView) findViewById(R.id.file_name); fileSize = (TextView) findViewById(R.id.file_size); imageView = (ImageView) findViewById(R.id.imageview); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivityForResult(requestIntent,0); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case 0: if (resultCode == RESULT_OK) { Uri returnUri = data.getData(); fileUri.setText("uri: " + returnUri); fileType.setText("type: " + getContentResolver().getType(returnUri)); Cursor cursor = getContentResolver().query(returnUri, null, null, null, null); int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE); cursor.moveToNext(); fileName.setText("name: " + cursor.getString(nameIndex)); fileSize.setText("size: " + cursor.getLong(sizeIndex)); imageView.setImageURI(returnUri); } break; default: break; } }}
当服务器窗体退出之后,客户端的onActivityResult()将被调用。returnIntent参数,就是服务器返回的Intent。Intent包含了文件URI,URI里包含文件各种信息。openFileDescriptor()方法返回ParcelFileDesctiptor,通过ParcelFileDescriptor实例,可以得到FileDescriptor对象,客户端可以通过”FileDescriptor”对象读取那个文件。
△总结:客户端到底做了什么事
→配置一个启动服务器的Intent
→调用方法启动访问
→当得到了服务器的返回信息,处理信息。
- FileProvider的Server和Client
- jvm的client和server
- FileProvider的拍照和打开相册功能
- client JVM 和 server JVM 的区别
- client和server相互调用的方法
- 一个简单的server和client程序
- 简单的TCP连接Server和Client
- hotspot 虚拟机的server和client模式
- JVM的server模式和client模式
- 基于TCP的server和client编写。
- JVM的Server模式和Client模式
- 实现Server和client端的通信
- ZigBee server和 client
- Real differences between “java -server” and “java -client”-JVM Server和JVM Client的不同
- python的server和client的简单建立
- linux下的tcp的server和client编程
- Android 7.0之访问文件的权限和FileProvider类
- 介绍---memory和client/server
- 第三方框架中关于HUD有MBProgressHUD和SVProgressHUD
- stack-structured algorithm and queue-structured algorithm
- JAVA网络编程入门
- 单链表的实现(给定某结点,删除它;给定某结点,在他前面插入一个结点等)
- python os.path模块常用方法
- FileProvider的Server和Client
- 实验二(2)用单链表实现信息操作
- SVProgressHUD(2.0.3)原来是这样
- A few useful things to learn about ML
- 游戏设计之我见 —— Strike Vector EX游玩心得以及思考
- Qt 学习之路 2(62):保存 XML
- c++知识点---类模板的使用
- spring data 常用的几种CURD方法
- 纪念人生中第一篇博客