android apk共享资源,共享文件  |  Android 开发者  |  Android Developers

本文介绍如何在Android应用中响应其他应用的文件请求,通过创建一个文件选择Activity来让用户选择文件,并使用ContentURI进行共享。在Android 6.0及以上版本,需要特别考虑权限问题。首先定义一个监听文件选择的ListView,当用户选择文件后,使用FileProvider生成内容URI并授予临时读取权限。最后,将内容URI和权限放入Intent中返回给请求方应用。
摘要由CSDN通过智能技术生成

将应用设置为使用内容 URI 共享文件后,您便可以响应其他应用对这些文件的请求。有一种方法可以响应这些请求,那就是从服务器应用提供一个其他应用可以调用的文件选择界面。通过这种方法,客户端应用可让用户从服务器应用选择文件,然后获得所选文件的内容 URI。

本课程介绍了如何在应用中创建响应文件请求的文件选择

接收文件请求

如需接收来自客户端应用的文件请求并使用内容 URI 进行响应,您的应用应提供一个文件选择

如需了解如何在客户端应用中实现文件请求,请参阅请求共享文件一课。

创建文件选择 Activity

如需设置文件选择

...

...

android:name=".FileSelectActivity"

android:label="@File Selector" >

android:name="android.intent.action.PICK"/>

android:name="android.intent.category.DEFAULT"/>

android:name="android.intent.category.OPENABLE"/>

在代码中定义文件选择 Activity

接下来,定义一个 files/images/ 目录中的可用文件,并允许用户选取所需的文件。以下代码段说明了如何定义此

Kotlin

class MainActivity : Activity() {

// The path to the root of this app's internal storage

private lateinit var privateRootDir: File

// The path to the "images" subdirectory

private lateinit var imagesDir: File

// Array of files in the images subdirectory

private lateinit var imageFiles: Array

// Array of filenames corresponding to imageFiles

private lateinit var imageFilenames: Array

// Initialize the Activity

override fun onCreate(savedInstanceState: Bundle?) {

...

// Set up an Intent to send back to apps that request a file

resultIntent = Intent("com.example.myapp.ACTION_RETURN_FILE")

// Get the files/ subdirectory of internal storage

privateRootDir = filesDir

// Get the files/images subdirectory;

imagesDir = File(privateRootDir, "images")

// Get the files in the images subdirectory

imageFiles = imagesDir.listFiles()

// Set the Activity's result to null to begin with

setResult(Activity.RESULT_CANCELED, null)

/*

* Display the file names in the ListView fileListView.

* Back the ListView with the array imageFilenames, which

* you can create by iterating through imageFiles and

* calling File.getAbsolutePath() for each File

*/

...

}

...

}Java

public class MainActivity extends Activity {

// The path to the root of this app's internal storage

private File privateRootDir;

// The path to the "images" subdirectory

private File imagesDir;

// Array of files in the images subdirectory

File[] imageFiles;

// Array of filenames corresponding to imageFiles

String[] imageFilenames;

// Initialize the Activity

@Override

protected void onCreate(Bundle savedInstanceState) {

...

// Set up an Intent to send back to apps that request a file

resultIntent =

new Intent("com.example.myapp.ACTION_RETURN_FILE");

// Get the files/ subdirectory of internal storage

privateRootDir = getFilesDir();

// Get the files/images subdirectory;

imagesDir = new File(privateRootDir, "images");

// Get the files in the images subdirectory

imageFiles = imagesDir.listFiles();

// Set the Activity's result to null to begin with

setResult(Activity.RESULT_CANCELED, null);

/*

* Display the file names in the ListView fileListView.

* Back the ListView with the array imageFilenames, which

* you can create by iterating through imageFiles and

* calling File.getAbsolutePath() for each File

*/

...

}

...

}

响应文件选择

用户选择共享文件后,您的应用必须确定用户选择了哪个文件,然后为该文件生成内容 URI。

在使用 intent 将文件的 URI 从一个应用发送到另一个应用时,您必须谨慎获取其他应用可以读取的 URI。在搭载 Android 6.0(API 级别 23)及更高版本的设备上执行此操作需要特别小心,因为此 Android 版本中的权限模型发生了变化,特别是 危险的权限,接收方应用可能没有该权限。

考虑到这些因素,我们建议您避免使用

不允许跨配置文件共享文件。

要求您的应用在搭载 Android 4.4(API 级别 19)或更低版本的设备上拥有

要求接收方应用拥有

您可以不使用 URI 权限来授予其他应用对特定 URI 的访问权限。虽然 URI 权限不适用于file:// URI,但它们适用于与内容提供程序关联的 URI。

在 指定可共享目录一节。

以下代码段展示了如何检测所选文件并为其生成内容 URI:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {

...

// Define a listener that responds to clicks on a file in the ListView

fileListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->

/*

* Get a File for the selected file name.

* Assume that the file names are in the

* imageFilename array.

*/

val requestFile = File(imageFilenames[position])

/*

* Most file-related method calls need to be in

* try-catch blocks.

*/

// Use the FileProvider to get a content URI

val fileUri: Uri? = try {

FileProvider.getUriForFile(

this@MainActivity,

"com.example.myapp.fileprovider",

requestFile)

} catch (e: IllegalArgumentException) {

Log.e("File Selector",

"The selected file can't be shared: $requestFile")

null

}

...

}

...

}Java

protected void onCreate(Bundle savedInstanceState) {

...

// Define a listener that responds to clicks on a file in the ListView

fileListView.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

* imageFilename array.

*/

File requestFile = new File(imageFilename[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: " + requestFile.toString());

}

...

}

});

...

}

请记住,您只能为特定的文件生成内容 URI,该文件需要位于包含 元素的元数据文件所指定的目录中。如需了解如何指定该目录,请参阅指定可共享目录一节。如果您针对未指定的路径中的

授予文件访问权限

您已经获得了要与其他应用共享的文件的内容 URI,现在要做的就是允许客户端应用访问该文件。如需允许访问,您需要向客户端应用授予访问权限,方法是将该内容 URI 添加到

以下代码段展示了如何设置文件的读取权限:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {

...

// Define a listener that responds to clicks on a file in the ListView

fileListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->

...

if (fileUri != null) {

// Grant temporary read permission to the content URI

resultIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

...

}

...

}

...

}Java

protected void onCreate(Bundle savedInstanceState) {

...

// Define a listener that responds to clicks in the ListView

fileListView.setOnItemClickListener(

new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView> adapterView,

View view,

int position,

long rowId) {

...

if (fileUri != null) {

// Grant temporary read permission to the content URI

resultIntent.addFlags(

Intent.FLAG_GRANT_READ_URI_PERMISSION);

}

...

}

...

});

...

}

注意:调用

请勿使用 文件共享中所述),而不是仅针对此实现。

与请求方应用共享文件

如需与请求文件的应用共享文件,请将包含内容 URI 和权限的

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {

...

// Define a listener that responds to clicks on a file in the ListView

fileListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->

...

if (fileUri != null) {

...

// Put the Uri and MIME type in the result Intent

resultIntent.setDataAndType(fileUri, contentResolver.getType(fileUri))

// Set the result

setResult(Activity.RESULT_OK, resultIntent)

} else {

resultIntent.setDataAndType(null, "")

setResult(RESULT_CANCELED, resultIntent)

}

}

}Java

protected void onCreate(Bundle savedInstanceState) {

...

// Define a listener that responds to clicks on a file in the ListView

fileListView.setOnItemClickListener(

new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView> adapterView,

View view,

int position,

long rowId) {

...

if (fileUri != null) {

...

// Put the Uri and MIME type in the result Intent

resultIntent.setDataAndType(

fileUri,

getContentResolver().getType(fileUri));

// Set the result

MainActivity.this.setResult(Activity.RESULT_OK,

resultIntent);

} else {

resultIntent.setDataAndType(null, "");

MainActivity.this.setResult(RESULT_CANCELED,

resultIntent);

}

}

});

为用户提供在选择文件后立即返回到客户端应用的方法。一种方式是提供复选标记或完成按钮。使用按钮的

Kotlin

fun onDoneClick(v: View) {

// Associate a method with the Done button

finish()

}Java

public void onDoneClick(View v) {

// Associate a method with the Done button

finish();

}

如需了解其他相关信息,请参阅:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值