Intent.ACTION_GET_CONTENT에서 반환 된 URI에서 파일 이름을 추출하는 방법은 무엇입니까?
타사 파일 관리자를 사용하여 파일 시스템에서 파일 (제 경우에는 PDF)을 선택합니다.
이것이 내가 활동을 시작하는 방법입니다.
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);
String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);
startActivityForResult(chooser, ActivityRequests.BROWSE);
이것이 내가 가진 것입니다 onActivityResult
.
Uri uri = data.getData();
if (uri != null) {
if (uri.toString().startsWith("file:")) {
fileName = uri.getPath();
} else { // uri.startsWith("content:")
Cursor c = getContentResolver().query(uri, null, null, null, null);
if (c != null && c.moveToFirst()) {
int id = c.getColumnIndex(Images.Media.DATA);
if (id != -1) {
fileName = c.getString(id);
}
}
}
}
코드 조각은 http://www.openintents.org/en/node/829에 있는 Open Intents 파일 관리자 지침 에서 차용되었습니다
.
의 목적 if-else
은 이전 버전과의 호환성입니다. 다른 파일 관리자가 모든 종류의 것을 반환한다는 것을 알았 기 때문에 이것이 파일 이름을 얻는 가장 좋은 방법인지 궁금합니다.
예를 들어 Documents ToGo 는 다음과 같은 내용을 반환합니다.
content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf
어떤에 getContentResolver().query()
반환 null
.
더 흥미롭게 만들기 위해 이름이 지정되지 않은 파일 관리자 (클라이언트 로그에서이 URI를 얻었습니다)는 다음과 같은 결과를 반환했습니다.
/./sdcard/downloads/.bin
URI에서 파일 이름을 추출하는 선호하는 방법이 있습니까? 아니면 문자열 구문 분석에 의존해야합니까?
developer.android.com에는 이에 대한 멋진 예제 코드가 있습니다 : https://developer.android.com/guide/topics/providers/document-provider.html
파일 이름을 추출하기위한 압축 버전 ( "this"가 활동이라고 가정) :
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
나는 다음과 같은 것을 사용하고 있습니다.
String scheme = uri.getScheme();
if (scheme.equals("file")) {
fileName = uri.getLastPathSegment();
}
else if (scheme.equals("content")) {
String[] proj = { MediaStore.Images.Media.TITLE };
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
if (cursor != null && cursor.getCount() != 0) {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.TITLE);
cursor.moveToFirst();
fileName = cursor.getString(columnIndex);
}
if (cursor != null) {
cursor.close();
}
}
파일 이름 검색.
private String queryName(ContentResolver resolver, Uri uri) {
Cursor returnCursor =
resolver.query(uri, null, null, null, null);
assert returnCursor != null;
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
returnCursor.moveToFirst();
String name = returnCursor.getString(nameIndex);
returnCursor.close();
return name;
}
짧게 원하면 작동합니다.
Uri uri= data.getData();
File file= new File(uri.getPath());
file.getName();
파일 이름을 얻는 가장 쉬운 방법 :
val fileName = File(uri.path).name
// or
val fileName = uri.pathSegments.last()
올바른 이름을 제공하지 않으면 다음을 사용해야합니다.
fun Uri.getName(context: Context): String {
val returnCursor = context.contentResolver.query(this, null, null, null, null)
val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
returnCursor.moveToFirst()
val fileName = returnCursor.getString(nameIndex)
returnCursor.close()
return fileName
}
아래 코드를 사용하여 프로젝트의 Uri에서 파일 이름 및 파일 크기를 가져옵니다.
/**
* Used to get file detail from uri.
* <p>
* 1. Used to get file detail (name & size) from uri.
* 2. Getting file details from uri is different for different uri scheme,
* 2.a. For "File Uri Scheme" - We will get file from uri & then get its details.
* 2.b. For "Content Uri Scheme" - We will get the file details by querying content resolver.
*
* @param uri Uri.
* @return file detail.
*/
public static FileDetail getFileDetailFromUri(final Context context, final Uri uri) {
FileDetail fileDetail = null;
if (uri != null) {
fileDetail = new FileDetail();
// File Scheme.
if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
File file = new File(uri.getPath());
fileDetail.fileName = file.getName();
fileDetail.fileSize = file.length();
}
// Content Scheme.
else if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Cursor returnCursor =
context.getContentResolver().query(uri, null, null, null, null);
if (returnCursor != null && returnCursor.moveToFirst()) {
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
fileDetail.fileName = returnCursor.getString(nameIndex);
fileDetail.fileSize = returnCursor.getLong(sizeIndex);
returnCursor.close();
}
}
}
return fileDetail;
}
/**
* File Detail.
* <p>
* 1. Model used to hold file details.
*/
public static class FileDetail {
// fileSize.
public String fileName;
// fileSize in bytes.
public long fileSize;
/**
* Constructor.
*/
public FileDetail() {
}
}
public String getFilename()
{
/* Intent intent = getIntent();
String name = intent.getData().getLastPathSegment();
return name;*/
Uri uri=getIntent().getData();
String fileName = null;
Context context=getApplicationContext();
String scheme = uri.getScheme();
if (scheme.equals("file")) {
fileName = uri.getLastPathSegment();
}
else if (scheme.equals("content")) {
String[] proj = { MediaStore.Video.Media.TITLE };
Uri contentUri = null;
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
if (cursor != null && cursor.getCount() != 0) {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE);
cursor.moveToFirst();
fileName = cursor.getString(columnIndex);
}
}
return fileName;
}
String Fpath = getPath(this, uri) ;
File file = new File(Fpath);
String filename = file.getName();
내 버전의 답변은 실제로 @Stefan Haustein과 매우 유사합니다. Android 개발자 페이지 파일 정보 검색 에서 답변을 찾았습니다 . 여기에있는 정보는 스토리지 액세스 프레임 워크 가이드 사이트 보다이 특정 주제에 대해 더 요약되어 있습니다. 쿼리 결과에서 파일 이름을 포함하는 열 인덱스는 OpenableColumns.DISPLAY_NAME
입니다. 열 인덱스에 대한 다른 답변 / 솔루션은 나를 위해 일하지 않았습니다. 다음은 샘플 함수입니다.
/**
* @param uri uri of file.
* @param contentResolver access to server app.
* @return the name of the file.
*/
def extractFileName(uri: Uri, contentResolver: ContentResolver): Option[String] = {
var fileName: Option[String] = None
if (uri.getScheme.equals("file")) {
fileName = Option(uri.getLastPathSegment)
} else if (uri.getScheme.equals("content")) {
var cursor: Cursor = null
try {
// Query the server app to get the file's display name and size.
cursor = contentResolver.query(uri, null, null, null, null)
// Get the column indexes of the data in the Cursor,
// move to the first row in the Cursor, get the data.
if (cursor != null && cursor.moveToFirst()) {
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
fileName = Option(cursor.getString(nameIndex))
}
} finally {
if (cursor != null) {
cursor.close()
}
}
}
fileName
}
먼저 URI
개체를 URL
개체 로 변환 한 다음 File
개체를 사용 하여 파일 이름을 검색해야합니다.
try
{
URL videoUrl = uri.toURL();
File tempFile = new File(videoUrl.getFile());
String fileName = tempFile.getName();
}
catch (Exception e)
{
}
그게 아주 쉽습니다.
xamarin / c #에 대한 Stefan Haustein 함수 :
public string GetFilenameFromURI(Android.Net.Uri uri)
{
string result = null;
if (uri.Scheme == "content")
{
using (var cursor = Application.Context.ContentResolver.Query(uri, null, null, null, null))
{
try
{
if (cursor != null && cursor.MoveToFirst())
{
result = cursor.GetString(cursor.GetColumnIndex(OpenableColumns.DisplayName));
}
}
finally
{
cursor.Close();
}
}
}
if (result == null)
{
result = uri.Path;
int cut = result.LastIndexOf('/');
if (cut != -1)
{
result = result.Substring(cut + 1);
}
}
return result;
}
If you want to have the filename with extension I use this function to get it. It also works with google drive file picks
public static String getFileName(Uri uri) {
String result;
//if uri is content
if (uri.getScheme() != null && uri.getScheme().equals("content")) {
Cursor cursor = global.getInstance().context.getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
//local filesystem
int index = cursor.getColumnIndex("_data");
if(index == -1)
//google drive
index = cursor.getColumnIndex("_display_name");
result = cursor.getString(index);
if(result != null)
uri = Uri.parse(result);
else
return null;
}
} finally {
cursor.close();
}
}
result = uri.getPath();
//get filename + ext of path
int cut = result.lastIndexOf('/');
if (cut != -1)
result = result.substring(cut + 1);
return result;
}
For Kotlin, You can use something like this :
object FileUtils {
fun getFileName(context: Context, uri : Uri) : String {
var fileName = "Unknown"
when (uri.scheme) {
ContentResolver.SCHEME_FILE -> {
fileName = File(uri.path).name
}
ContentResolver.SCHEME_CONTENT -> {
try {
context.contentResolver.query(
uri,
null,
null,
null,
null
)?.apply {
if (moveToFirst()) {
fileName = getString(getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
close()
}
} catch (e : Exception) {
return fileName
}
}
}
return fileName
}
}
This actually worked for me:
private String uri2filename() {
String ret;
String scheme = uri.getScheme();
if (scheme.equals("file")) {
ret = uri.getLastPathSegment();
}
else if (scheme.equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
ret = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
}
return ret;
}
'programing' 카테고리의 다른 글
div 내에서 너무 긴 텍스트 자르기 (0) | 2020.10.20 |
---|---|
Connect 3.0 지원 중단 경고를 제거하는 방법은 무엇입니까? (0) | 2020.10.20 |
엔티티 이름은 엔티티 참조에서 '&'바로 뒤에 와야합니다. (0) | 2020.10.20 |
SQL 네트워크 인터페이스, 오류 : 50-로컬 데이터베이스 런타임 오류가 발생했습니다. (0) | 2020.10.20 |
PHP에서 대시를 CamelCase로 변환 (0) | 2020.10.20 |