gpt4 book ai didi

java - 我无法在 Android 8 Oreo(华为)中选择 PDF 文件

转载 作者:行者123 更新时间:2023-11-29 02:23:15 28 4
gpt4 key购买 nike

我是 android 的新手,我正在尝试选择 pdf 文件上传到 android 应用程序中的服务器我在华为手机中遇到 api>24 的问题我在 StackOverflow 中寻找类似的问题,但没有解决我的问题 like this question

只有华为手机才有这个问题我试图从三星奥利奥中挑选一个文件,一切正常,但有了华为, Activity 就被压垮了我的代码

   private void imageBrowse() {



if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);

intent.setType("application/pdf");
startActivityForResult(Intent.createChooser(intent, "Select Pdf"), PICK_IMAGE_REQUEST);
}
else {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);

intent.setType("application/pdf");
// intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
// intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Pdf"), PICK_IMAGE_REQUEST);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK) {

if(requestCode == PICK_IMAGE_REQUEST){
Uri picUri = data.getData();



if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
filePath = getPath(this,picUri);

}


NAME = getPathfromURI(picUri);
AlertDialog.Builder a_builder = new AlertDialog.Builder(Teacher_upload_files.this);
a_builder.setMessage("اسم الملف :"+NAME)
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
fileName.setText(NAME);
}
});
AlertDialog alert = a_builder.create();
alert.setTitle("شكرا :) ");
alert.show();

Log.d("picUri", picUri.toString());
// Log.d("filePath", filePath);

// imageView.setImageURI(picUri);

}

}

}

这就是我获取路径的方式

public static String getPath(final Context context, final Uri uri) {

final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];

if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}

// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {

final String id = DocumentsContract.getDocumentId(uri);

final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];

Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}

final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};

return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
}

return null;
}

这里的问题总是null

public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {

Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};

try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}

这是错误

 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.providers.downloads.documents/document/4736 flg=0x43 }} to activity {com.am.ahmad/com.am.ahmad.Teacher_upload_files}: java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/4736
at android.app.ActivityThread.deliverResults(ActivityThread.java:4932)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4975)
at android.app.ActivityThread.-wrap20(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1950)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
Caused by: java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/4736
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:165)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
at android.content.ContentResolver.query(ContentResolver.java:766)
at android.content.ContentResolver.query(ContentResolver.java:716)
at android.content.ContentResolver.query(ContentResolver.java:667)
at com.am.ahmad.Teacher_upload_files.getDataColumn(Teacher_upload_files.java:593)
at com.am.ahmad.Teacher_upload_files.getPath(Teacher_upload_files.java:536)
at com.am.ahmad.Teacher_upload_files.onActivityResult(Teacher_upload_files.java:372)
at android.app.Activity.dispatchActivityResult(Activity.java:7690)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4928)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4975)
at android.app.ActivityThread.-wrap20(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1950)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

最佳答案

我发布了一个将 Uri 转换为文件或文件路径的完整解决方案,它适用于所有 API 和媒体库。

/*
* Copyright (C) 2018 OpenIntents.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

object FileHelperKt {

private const val DOCUMENTS_DIR = "documents"
// configured android:authorities in AndroidManifest (https://developer.android.com/reference/android/support/v4/content/FileProvider)
private const val AUTHORITY = "YOUR_AUTHORITY.provider"
private const val HIDDEN_PREFIX = "."

private val DEBUG = false // Set to true to enable logging
/**
* File and folder comparator. TODO Expose sorting option method
*/
var sComparator = { f1: File, f2: File ->
// Sort alphabetically by lower case, which is much cleaner
f1.name.toLowerCase().compareTo(
f2.name.toLowerCase()
)
}
/**
* File (not directories) filter.
*/
var sFileFilter = { file: File ->
val fileName = file.getName()
// Return files only (not directories) and skip hidden files
file.isFile() && !fileName.startsWith(HIDDEN_PREFIX)
}
/**
* Folder (directories) filter.
*/
var sDirFilter = { file: File ->
val fileName = file.name
// Return directories only and skip hidden directories
file.isDirectory && !fileName.startsWith(HIDDEN_PREFIX)
}

val downloadsDir: File
get() = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

/**
* Gets the extension of a file name, like ".png" or ".jpg".
*
* @param uri
* @return Extension including the dot("."); "" if there is no extension;
* null if uri was null.
*/
fun getExtension(uri: String?): String? {
if (uri == null) {
return null
}

val dot = uri.lastIndexOf(".")
return if (dot >= 0) {
uri.substring(dot)
} else {
// No extension.
""
}
}

/**
* @return Whether the URI is a local one.
*/
fun isLocal(url: String?): Boolean {
return url != null && !url.startsWith("http://") && !url.startsWith("https://")
}

/**
* @return True if Uri is a MediaStore Uri.
* @author paulburke
*/
fun isMediaUri(uri: Uri): Boolean {
return "media".equals(uri.authority!!, ignoreCase = true)
}

/**
* Convert File into Uri.
*
* @param file
* @return uri
*/
fun getUri(file: File?): Uri? {
return if (file != null) Uri.fromFile(file) else null
}

/**
* Returns the path only (without file name).
*
* @param file
* @return
*/
fun getPathWithoutFilename(file: File?): File? {
if (file != null) {
if (file.isDirectory) {
// no file to be split off. Return everything
return file
} else {
val filename = file.name
val filepath = file.absolutePath

// Construct path without file name.
var pathwithoutname = filepath.substring(
0,
filepath.length - filename.length
)
if (pathwithoutname.endsWith("/")) {
pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length - 1)
}
return File(pathwithoutname)
}
}
return null
}

/**
* @return The MIME type for the given file.
*/
fun getMimeType(file: File): String? {
val extension = getExtension(file.name)
if (extension!!.isNotEmpty()) {
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1))
} else {
return "application/octet-stream"
}
}

/**
* @return The MIME type for the give Uri.
*/
fun getMimeType(context: Context, uri: Uri): String? {
val file = File(getPath(context, uri)!!)
return getMimeType(file)
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is local.
*/
fun isLocalStorageDocument(uri: Uri): Boolean {
return AUTHORITY == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
fun isExternalStorageDocument(uri: Uri): Boolean {
return "com.android.externalstorage.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
fun isDownloadsDocument(uri: Uri): Boolean {
return "com.android.providers.downloads.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
fun isMediaDocument(uri: Uri): Boolean {
return "com.android.providers.media.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
fun isGooglePhotosUri(uri: Uri): Boolean {
return "com.google.android.apps.photos.content" == uri.authority
}

/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
fun getDataColumn(context: Context, uri: Uri?, selection: String?, selectionArgs: Array<String>?): String? {

var cursor: Cursor? = null
val column = MediaStore.Files.FileColumns.DATA
val projection = arrayOf(column)

try {
cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
if (cursor != null && cursor.moveToFirst()) {
if (DEBUG)
DatabaseUtils.dumpCursor(cursor)

val columnIndex = cursor.getColumnIndexOrThrow(column)
return cursor.getString(columnIndex)
}
} finally {
cursor?.close()
}
return null
}

/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.<br></br>
* <br></br>
* Callers should check whether the path is local before assuming it
* represents a local file.
*
* @param context The context.
* @param uri The Uri to query.
* @see .isLocal
* @see .getFile
*/
fun getPath(context: Context, uri: Uri): String? {
Timber.d(
"[app] FileHelper - Authority: ${uri.authority}, " +
"Fragment: ${uri.fragment}, " +
"Port: ${uri.port}, " +
"Query: ${uri.query}, " +
"Scheme: ${uri.scheme}, " +
"Host: ${uri.host}, " +
"Segments: ${uri.pathSegments}"
)

val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT

// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// LocalStorageProvider
if (isLocalStorageDocument(uri)) {
// The path is the id
return DocumentsContract.getDocumentId(uri)
}
// ExternalStorageProvider
else if (isExternalStorageDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split((":").toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]

if ("primary".equals(type, ignoreCase = true)) {
return (Environment.getExternalStorageDirectory()).toString() + "/" + split[1]
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
val id = DocumentsContract.getDocumentId(uri)
if (id != null && id.startsWith("raw:")) {
return id.substring(4)
}
val contentUriPrefixesToTry =
arrayOf("content://downloads/public_downloads", "content://downloads/my_downloads")
for (contentUriPrefix in contentUriPrefixesToTry) {
val contentUri =
ContentUris.withAppendedId(Uri.parse(contentUriPrefix), java.lang.Long.valueOf(id!!))
try {
val path = getDataColumn(context, contentUri, null, null)
if (path != null) {
return path
}
} catch (e: Exception) {
}
}

// path could not be retrieved using ContentResolver, therefore copy file to accessible cache using streams
val fileName = getFileName(context, uri)
val cacheDir = getDocumentCacheDir(context)
val file = generateFileName(fileName, cacheDir)
var destinationPath: String? = null
if (file != null) {
destinationPath = file.absolutePath
saveFileFromUri(context, uri, destinationPath)
}
return destinationPath
}
// MediaProvider
else if (isMediaDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split((":").toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]

var contentUri: Uri? = null
when (type) {
"image" -> contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
"video" -> contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
"audio" -> contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}

val selection = "_id=?"
val selectionArgs = arrayOf(split[1])

return getDataColumn(context, contentUri, selection, selectionArgs)
}
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) {
// Return the remote address
if (isGooglePhotosUri(uri)) {
return uri.lastPathSegment
}
return getDataColumn(context, uri, null, null)
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
return uri.path
}

return null
}

/**
* Convert Uri into File, if possible.
*
* @return file A local file that the Uri was pointing to, or null if the
* Uri is unsupported or pointed to a remote resource.
* @author paulburke
* @see .getPath
*/
fun getFile(context: Context, uri: Uri?): File? {
if (uri != null) {
val path = getPath(context, uri)
if (path != null && isLocal(path)) {
return File(path)
}
}
return null
}

/**
* Get the file size in a human-readable string.
*
* @param size
* @return
* @author paulburke
*/
fun getReadableFileSize(size: Int): String {
val bytesInKilobytes = 1024
val dec = DecimalFormat("###.#")
val kb = " KB"
val mb = " MB"
val gb = " GB"
var fileSize = 0f
var suffix = kb

if (size > bytesInKilobytes) {
fileSize = (size / bytesInKilobytes).toFloat()
if (fileSize > bytesInKilobytes) {
fileSize /= bytesInKilobytes
if (fileSize > bytesInKilobytes) {
fileSize /= bytesInKilobytes
suffix = gb
} else {
suffix = mb
}
}
}
return (dec.format(fileSize.toDouble()) + suffix).toString()
}

/**
* Get the Intent for selecting content to be used in an Intent Chooser.
*
* @return The intent for opening a file with Intent.createChooser()
*/
fun createGetContentIntent(): Intent {
// Implicitly allow the user to select a particular kind of data
val intent = Intent(Intent.ACTION_GET_CONTENT)
// The MIME data type filter
intent.type = "*/*"
// Only return URIs that can be opened with ContentResolver
intent.addCategory(Intent.CATEGORY_OPENABLE)
return intent
}

/**
* Creates View intent for given file
*
* @param file
* @return The intent for viewing file
*/
fun getViewIntent(context: Context, file: File): Intent {
// Uri uri = Uri.fromFile(file);
val uri = FileProvider.getUriForFile(context, AUTHORITY, file)
val intent = Intent(Intent.ACTION_VIEW)
val url = file.toString()
if (url.contains(".doc") || url.contains(".docx")) {
// Word document
intent.setDataAndType(uri, "application/msword")
} else if (url.contains(".pdf")) {
// PDF file
intent.setDataAndType(uri, "application/pdf")
} else if (url.contains(".ppt") || url.contains(".pptx")) {
// Powerpoint file
intent.setDataAndType(uri, "application/vnd.ms-powerpoint")
} else if (url.contains(".xls") || url.contains(".xlsx")) {
// Excel file
intent.setDataAndType(uri, "application/vnd.ms-excel")
} else if (url.contains(".zip") || url.contains(".rar")) {
// WAV audio file
intent.setDataAndType(uri, "application/x-wav")
} else if (url.contains(".rtf")) {
// RTF file
intent.setDataAndType(uri, "application/rtf")
} else if (url.contains(".wav") || url.contains(".mp3")) {
// WAV audio file
intent.setDataAndType(uri, "audio/x-wav")
} else if (url.contains(".gif")) {
// GIF file
intent.setDataAndType(uri, "image/gif")
} else if (url.contains(".jpg") || url.contains(".jpeg") || url.contains(".png")) {
// JPG file
intent.setDataAndType(uri, "image/jpeg")
} else if (url.contains(".txt")) {
// Text file
intent.setDataAndType(uri, "text/plain")
} else if ((url.contains(".3gp") || url.contains(".mpg") || url.contains(".mpeg") ||
url.contains(".mpe") || url.contains(".mp4") || url.contains(".avi"))
) {
// Video files
intent.setDataAndType(uri, "video/*")
} else {
intent.setDataAndType(uri, "*/*")
}

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
return intent
}

fun getDocumentCacheDir(context: Context): File {
val dir = File(context.cacheDir, DOCUMENTS_DIR)
if (!dir.exists()) {
dir.mkdirs()
}
logDir(context.cacheDir)
logDir(dir)

return dir
}

private fun logDir(dir: File) {
if (!DEBUG) return
Timber.d("[app] FileHelper log dir=$dir")
val files = dir.listFiles()
for (file in files!!) {
Timber.d("[app] FileHelper path:${file.path}")
}
}

fun generateFileName(name: String?, directory: File): File? {
var name: String? = name ?: return null

var file = File(directory, name!!)

if (file.exists()) {
var fileName: String = name
var extension = ""
val dotIndex = name.lastIndexOf('.')
if (dotIndex > 0) {
fileName = name.substring(0, dotIndex)
extension = name.substring(dotIndex)
}

var index = 0

while (file.exists()) {
index++
name = "$fileName($index)$extension"
file = File(directory, name)
}
}

try {
if (!file.createNewFile()) {
return null
}
} catch (e: IOException) {
Timber.w(e, "[app] FileHelper")
return null
}

logDir(directory)

return file
}

/**
* Writes response body to disk
*
* @param body ResponseBody
* @param path file path
* @return File
*/
fun writeResponseBodyToDisk(body: ResponseBody, path: String): File? {
try {
val target = File(path)

var inputStream: InputStream? = null
var outputStream: OutputStream? = null

try {
val fileReader = ByteArray(4096)

inputStream = body.byteStream()
outputStream = FileOutputStream(target)

while (true) {
val read = inputStream!!.read(fileReader)

if (read == -1) {
break
}

outputStream.write(fileReader, 0, read)
}

outputStream.flush()

return target
} catch (e: IOException) {
return null
} finally {
if (inputStream != null) {
inputStream.close()
}

if (outputStream != null) {
outputStream.close()
}
}
} catch (e: IOException) {
return null
}
}

private fun saveFileFromUri(context: Context, uri: Uri, destinationPath: String) {
var inputStream: InputStream? = null
var bos: BufferedOutputStream? = null
try {
inputStream = context.contentResolver.openInputStream(uri)
bos = BufferedOutputStream(FileOutputStream(destinationPath, false))
val buf = ByteArray(1024)
inputStream!!.read(buf)
do {
bos.write(buf)
} while (inputStream.read(buf) != -1)
} catch (e: IOException) {
e.printStackTrace()
} finally {
try {
inputStream?.close()
bos?.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}

fun readBytesFromFile(filePath: String): ByteArray? {
var fileInputStream: FileInputStream? = null
var bytesArray: ByteArray? = null

try {
val file = File(filePath)
bytesArray = ByteArray(file.length().toInt())

// read file into bytes[]
fileInputStream = FileInputStream(file)
fileInputStream.read(bytesArray)
} catch (e: IOException) {
e.printStackTrace()
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}

return bytesArray
}

@Throws(IOException::class)
fun createTempImageFile(context: Context, fileName: String): File {
// Create an image file name
val storageDir = File(context.cacheDir, DOCUMENTS_DIR)
return File.createTempFile(fileName, ".jpg", storageDir)
}

fun getFileName(context: Context, uri: Uri): String? {
val mimeType = context.contentResolver.getType(uri)
var filename: String? = null

if (mimeType == null) {
val path = getPath(context, uri)
if (path == null) {
filename = getName(uri.toString())
} else {
val file = File(path)
filename = file.name
}
} else {
val returnCursor = context.contentResolver.query(uri, null, null, null, null)
if (returnCursor != null) {
val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
returnCursor.moveToFirst()
filename = returnCursor.getString(nameIndex)
returnCursor.close()
}
}

return filename
}

fun getName(filename: String?): String? {
if (filename == null) {
return null
}
val index = filename.lastIndexOf('/')
return filename.substring(index + 1)
}
}

关于java - 我无法在 Android 8 Oreo(华为)中选择 PDF 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53853044/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com