안드로이드에서 MIME 파일 유형을 결정하는 방법은 무엇입니까?
다음과 같은 파일의 전체 경로가 있다고 가정합니다. (/sdcard/tlogo.png)그것의 마임 타입을 알고 싶습니다.
나는 그것을 위한 함수를 만들었습니다.
public static String getMimeType(File file, Context context)
{
Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
MimeTypeMap mime = MimeTypeMap.getSingleton();
String type = mime.getExtensionFromMimeType(cR.getType(uri));
return type;
}
하지만 제가 그것을 부르면, 그것은 null을 반환합니다.
File file = new File(filePath);
String fileType=CommonFunctions.getMimeType(file, context);
무엇보다도, 당신은 전화하는 것을 고려해야 합니다.MimeTypeMap#getMimeTypeFromExtension()
다음과 같이:
// url = file path or whatever suitable URL you want.
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
모든 파일의 MIME 유형 탐지
public String getMimeType(Uri uri) {
String mimeType = null;
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
ContentResolver cr = getAppContext().getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
}
return mimeType;
}
위의 MimeTypeMap 솔루션이 내 사용에서 null을 반환했습니다.이것은 작동하고 더 쉽습니다.
Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);
젠스의 응답 최적화 버전은 null-safety 및 fallback-type입니다.
@NonNull
static String getMimeType(@NonNull File file) {
String type = null;
final String url = file.toString();
final String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
}
if (type == null) {
type = "image/*"; // fallback type. You might set it to */*
}
return type;
}
중요: getFileExtensionFromUrl()은 소문자에서만 작동합니다!
업데이트 (19.03.2018)
보너스: 덜 장황한 코틀린 확장 함수로서 위의 방법들:
fun File.getMimeType(fallback: String = "image/*"): String {
return MimeTypeMap.getFileExtensionFromUrl(toString())
?.run { MimeTypeMap.getSingleton().getMimeTypeFromExtension(toLowerCase()) }
?: fallback // You might set it to */*
}
File file = new File(path, name);
MimeTypeMap mime = MimeTypeMap.getSingleton();
int index = file.getName().lastIndexOf('.')+1;
String ext = file.getName().substring(index).toLowerCase();
String type = mime.getMimeTypeFromExtension(ext);
intent.setDataAndType(Uri.fromFile(file), type);
try
{
context.startActivity(intent);
}
catch(ActivityNotFoundException ex)
{
ex.printStackTrace();
}
코틀린에서는 훨씬 더 간단합니다.
솔루션 1:
fun getMimeType(file: File): String? =
MimeTypeMap.getSingleton().getMimeTypeFromExtension(file.extension)
솔루션 2: (파일 확장자 기능)
fun File.mimeType(): String? =
MimeTypeMap.getSingleton().getMimeTypeFromExtension(this.extension)
위의 umerk44의 솔루션에 매우 세심한 주의를 기울입니다.getMimeTypeFromExtension
출호를 합니다.guessMimeTypeTypeFromExtension
대소문자를 구분합니다. 후 . - 저는이대오보내자살다습니았펴보세히고를후해것에▁i다니습살았펴▁-보▁spent▁a자▁took히▁then세.getMimeTypeFromExtension
돌아올 것입니다NULL
하면 "반환됩니다. "를하면 "image/jpeg"가됩니다.JPG"를 전달하면 "image/jpeg"가 반환됩니다.
안드로이드 앱에서 사용한 솔루션은 다음과 같습니다.
public static String getMimeType(String url)
{
String extension = url.substring(url.lastIndexOf("."));
String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl(extension);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(mimeTypeMap);
return mimeType;
}
편집
저는 이것을 위해 작은 도서관을 만들었습니다.하지만 기본 코드는 거의 같습니다.
GitHub에서 사용할 수 있습니다.
솔루션 2020년 9월
Kotlin 사용
fun File.getMimeType(context: Context): String? {
if (this.isDirectory) {
return null
}
fun fallbackMimeType(uri: Uri): String? {
return if (uri.scheme == ContentResolver.SCHEME_CONTENT) {
context.contentResolver.getType(uri)
} else {
val extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase(Locale.getDefault()))
}
}
fun catchUrlMimeType(): String? {
val uri = Uri.fromFile(this)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val path = Paths.get(uri.toString())
try {
Files.probeContentType(path) ?: fallbackMimeType(uri)
} catch (ignored: IOException) {
fallbackMimeType(uri)
}
} else {
fallbackMimeType(uri)
}
}
val stream = this.inputStream()
return try {
URLConnection.guessContentTypeFromStream(stream) ?: catchUrlMimeType()
} catch (ignored: IOException) {
catchUrlMimeType()
} finally {
stream.close()
}
}
그것은 이전의 답변들을 결합한 것이기 때문에 가장 좋은 선택인 것 같습니다.
먼저 URL 연결을 사용하여 유형을 가져오려고 합니다.내용 추측FromStream을 입력하지만 실패하거나 null을 반환하면 Android O 이상에서 다음을 사용하여 mimtype을 가져오려고 합니다.
java.nio.file.Files
java.nio.file.Paths
그렇지 않으면 Android 버전이 O 미만이거나 메서드가 실패하면 ContentResolver 및 MimeTypeMap을 사용하여 형식을 반환합니다.
때때로 젭과 젠스의 대답이 작동하지 않고 null을 반환합니다.이 경우에는 다음 솔루션을 사용합니다.파일 헤드에는 일반적으로 형식 서명이 포함되어 있습니다.저는 그것을 읽고 서명 목록에서 알려진 것과 비교합니다.
/**
*
* @param is InputStream on start of file. Otherwise signature can not be defined.
* @return int id of signature or -1, if unknown signature was found. See SIGNATURE_ID_(type) constants to
* identify signature by its id.
* @throws IOException in cases of read errors.
*/
public static int getSignatureIdFromHeader(InputStream is) throws IOException {
// read signature from head of source and compare with known signatures
int signatureId = -1;
int sigCount = SIGNATURES.length;
int[] byteArray = new int[MAX_SIGNATURE_LENGTH];
StringBuilder builder = new StringBuilder();
for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {
byteArray[i] = is.read();
builder.append(Integer.toHexString(byteArray[i]));
}
if (DEBUG) {
Log.d(TAG, "head bytes=" + builder.toString());
}
for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {
// check each bytes with known signatures
int bytes = byteArray[i];
int lastSigId = -1;
int coincidences = 0;
for (int j = 0; j < sigCount; j++) {
int[] sig = SIGNATURES[j];
if (DEBUG) {
Log.d(TAG, "compare" + i + ": " + Integer.toHexString(bytes) + " with " + sig[i]);
}
if (bytes == sig[i]) {
lastSigId = j;
coincidences++;
}
}
// signature is unknown
if (coincidences == 0) {
break;
}
// if first bytes of signature is known we check signature for full coincidence
if (coincidences == 1) {
int[] sig = SIGNATURES[lastSigId];
int sigLength = sig.length;
boolean isSigKnown = true;
for (; i < MAX_SIGNATURE_LENGTH && i < sigLength; i++) {
bytes = byteArray[i];
if (bytes != sig[i]) {
isSigKnown = false;
break;
}
}
if (isSigKnown) {
signatureId = lastSigId;
}
break;
}
}
return signatureId;
}
signatureId
서명 배열에 있는 서명 인덱스입니다.를 들면 를들면예,
private static final int[] SIGNATURE_PNG = hexStringToIntArray("89504E470D0A1A0A");
private static final int[] SIGNATURE_JPEG = hexStringToIntArray("FFD8FF");
private static final int[] SIGNATURE_GIF = hexStringToIntArray("474946");
public static final int SIGNATURE_ID_JPEG = 0;
public static final int SIGNATURE_ID_PNG = 1;
public static final int SIGNATURE_ID_GIF = 2;
private static final int[][] SIGNATURES = new int[3][];
static {
SIGNATURES[SIGNATURE_ID_JPEG] = SIGNATURE_JPEG;
SIGNATURES[SIGNATURE_ID_PNG] = SIGNATURE_PNG;
SIGNATURES[SIGNATURE_ID_GIF] = SIGNATURE_GIF;
}
이제 파일의 URI가 없어도 파일 형식이 있습니다.다음으로 파일 형식별로 MIME 형식을 가져옵니다.어떤 MIME 유형을 가져올지 모르는 경우 이 표에서 적합한 항목을 찾을 수 있습니다.
다양한 파일 형식에 사용할 수 있습니다.그러나 비디오의 경우 MIME 유형을 얻으려면 비디오 코덱을 알아야 하기 때문에 작동하지 않습니다.비디오의 마임 유형을 가져오려면 MediaMetadataRetriver를 사용합니다.
, 표준메소드사마여유임 결 했 다 를 용 하 없 수 유 습 니 다 할 지 확 을 명 장 파 일 사 여 하 용 을 음 지 만 려 고 하 을 MimeTypeMap.getFileExtensionFromUrl(uri.getPath())
이 메서드는 빈 문자열을 반환했습니다.그래서 저는 파일 확장자를 유지하기 위해 간단한 솔루션을 만들었습니다.
다음은 파일 확장명을 반환하는 방법입니다.
private String getExtension(String fileName){
char[] arrayOfFilename = fileName.toCharArray();
for(int i = arrayOfFilename.length-1; i > 0; i--){
if(arrayOfFilename[i] == '.'){
return fileName.substring(i+1, fileName.length());
}
}
return "";
}
파일 확장자를 유지하면 아래와 같은 MIME 유형을 얻을 수 있습니다.
public String getMimeType(File file) {
String mimeType = "";
String extension = getExtension(file.getName());
if (MimeTypeMap.getSingleton().hasExtension(extension)) {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return mimeType;
}
컨텐츠와 파일 모두에서 유연하게 작동합니다.
public static String getMimeType(Context context, Uri uri) {
String extension;
//Check uri format to avoid null
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
//If scheme is a content
final MimeTypeMap mime = MimeTypeMap.getSingleton();
extension = mime.getExtensionFromMimeType(context.getContentResolver().getType(uri));
} else {
//If scheme is a File
//This will replace white spaces with %20 and also other special characters. This will avoid returning null values on file name with spaces and special characters.
extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uri.getPath())).toString());
}
return extension;
}
MimeTypeMap
flv, syslog, 3gpp, cpp와 같은 일부 하지 못할 수 .따라서 코드를 유지하기 위해 MimeTypeMap을 확장하는 방법을 생각해야 합니다.여기 그러한 예가 있습니다.
또한, 여기 마임 유형의 전체 목록이 있습니다.
http: //www.sitepoint.com/web-foundations/mime-types-complete-list/
Xamarin Android의 경우(위의 @HoaLe의 답변에서)
public String getMimeType(Uri uri) {
String mimeType = null;
if (uri.Scheme.Equals(ContentResolver.SchemeContent))
{
ContentResolver cr = Application.Context.ContentResolver;
mimeType = cr.GetType(uri);
}
else
{
String fileExtension = MimeTypeMap.GetFileExtensionFromUrl(uri.ToString());
mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(
fileExtension.ToLower());
}
return mimeType;
}
get file object....
File file = new File(filePath);
then....pass as a parameter to...
getMimeType(file);
...here is
public String getMimeType(File file) {
String mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString()).toLowerCase());
if (mimetype == null) {
return "*/*";
}
return mimetype;///return the mimeType
}
자산/파일에서 보내는 동안(MimeTypeMap에서 누락된 경우는 거의 없음).
private String getMimeType(String path) {
if (null == path) return "*/*";
String extension = path;
int lastDot = extension.lastIndexOf('.');
if (lastDot != -1) {
extension = extension.substring(lastDot + 1);
}
// Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
extension = extension.toLowerCase(Locale.getDefault());
if (extension.equals("3ga")) {
return "audio/3gpp";
} else if (extension.equals("js")) {
return "text/javascript";
} else if (extension.equals("woff")) {
return "application/x-font-woff";
} else {
// TODO
// anyting missing from the map (http://www.sitepoint.com/web-foundations/mime-types-complete-list/)
// reference: http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/net/MimeUtils.java#MimeUtils
}
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
Content Resolver를 사용하는 동안
contentResolver.getType(uri)
http/https 요청 중
try {
HttpURLConnection conn = httpClient.open(new URL(uri.toString()));
conn.setDoInput(false);
conn.setRequestMethod("HEAD");
return conn.getHeaderField("Content-Type");
} catch (IOException e) {
}
// This will return the mimeType.
// for eg. xyz.png it will return image/png.
// here uri is the file that we were picked using intent from ext/internal storage.
private String getMimeType(Uri uri) {
// This class provides applications access to the content model.
ContentResolver contentResolver = getContentResolver();
// getType(Uri url)-Return the MIME type of the given content URL.
return contentResolver.getType(uri);
}
저도 비슷한 문제에 직면했습니다.지금까지 저는 이름에 따라 결과가 다를 수 있다는 것을 알고 있었고, 마침내 이 해결책에 도달했습니다.
public String getMimeType(String filePath) {
String type = null;
String extension = null;
int i = filePath.lastIndexOf('.');
if (i > 0)
extension = filePath.substring(i+1);
if (extension != null)
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
return type;
}
왜 그런지 모르겠어요MimeTypeMap.getFileExtensionFromUrl()
.space
및일부다반환다니됩문자가른▁s다ers를 합니다.""
파일 이름을 허용 가능한 이름으로 변경하기 위해 이 방법을 썼습니다.그냥 가지고 노는 거예요.String
하지만, 그것은 효과가 있습니다.방법을 , 그방을통해법,,space
하는 문자는 파일이에존여문재문다통로원자음다변해(여기서 "를 통해 .replaceAll(" ", "x")
그리고 다른 부적합한 캐릭터들은 다음을 통해 적합한 캐릭터로 바뀝니다.URLEncoder
따라서 (질문에 제시된 코드와 선택된 답변에 따른) 사용법은 다음과 같아야 합니다.
private String reviseUrl(String url) {
String revisedUrl = "";
int fileNameBeginning = url.lastIndexOf("/");
int fileNameEnding = url.lastIndexOf(".");
String cutFileNameFromUrl = url.substring(fileNameBeginning + 1, fileNameEnding).replaceAll(" ", "x");
revisedUrl = url.
substring(0, fileNameBeginning + 1) +
java.net.URLEncoder.encode(cutFileNameFromUrl) +
url.substring(fileNameEnding, url.length());
return revisedUrl;
}
위 솔루션은 URLConnection을 사용하여 .rar 파일의 경우 null을 반환했습니다.내용 추측이 경우 TypeFromName(url)이 작동했습니다.
로컬 파일에서 mime:
String url = file.getAbsolutePath();
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mime = fileNameMap.getContentTypeFor("file://"+url);
확장자를 수 예를 들어, 1-message 예다 선다 있습니 권 : 1-String filename = uri.getLastPathSegment();
이 링크 보기
2-이 코드도 사용할 수 있습니다.
filePath .substring(filePath.lastIndexOf(".")+1);
하지만 이것은 좋은 접근법이 아닙니다. 3-파일의 URI가 있는 경우 이 코드를 사용합니다.
String[] projection = { MediaStore.MediaColumns.DATA,
MediaStore.MediaColumns.MIME_TYPE };
4-URL이 있는 경우 다음 코드를 사용합니다.
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
코드를 즐기십시오.
// new processing the mime type out of Uri which may return null in some cases
String mimeType = getContentResolver().getType(uri);
// old processing the mime type out of path using the extension part if new way returned null
if (mimeType == null){mimeType URLConnection.guessContentTypeFromName(path);}
public static String getFileType(Uri file)
{
try
{
if (file.getScheme().equals(ContentResolver.SCHEME_CONTENT))
return subStringFromLastMark(SystemMaster.getContentResolver().getType(file), "/");
else
return MimeTypeMap.getFileExtensionFromUrl(file.toString()).toLowerCase();
}
catch(Exception e)
{
return null;
}
}
public static String getMimeType(Uri file)
{
try
{
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(getFileType(file));
}
catch(Exception e)
{
return null;
}
}
public static String subStringFromLastMark(String str,String mark)
{
int l = str.lastIndexOf(mark);
int end = str.length();
if(l == -1)
return str;
return str.substring(l + 1, end);
}
또한 내 경우 경로가 null 값을 반환했습니다.
/storage/emulated/0/Music/01 - Ghost on the Dance Floor.mp3
사용에 관한 일로서.
valurl = inUrl.replace(" ",")
그래서 방법은 다음과 같습니다.
@JvmStatic
fun getMimeType(inUrl: String?): String {
if (inUrl == null) return ""
val url = inUrl.replace(" ","")
var type: String? = null
val extension = MimeTypeMap.getFileExtensionFromUrl(url)
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase())
}
if(type ==null){
val cR = WifiTalkie.getApplicationContext().contentResolver
type = cR.getType(Uri.parse(url))
}
if (type == null) {
type = "*/*" // fallback method_type. You might set it to */*
}
return type
}
결과적으로 성공 결과를 반환합니다.
오디오/오디오
누구에게 도움이 되길 바랍니다.
여기서 완벽한 답은 하나도 없습니다.다음은 모든 주요 답변의 최상의 요소를 결합한 답변입니다.
public final class FileUtil {
// By default, Android doesn't provide support for JSON
public static final String MIME_TYPE_JSON = "application/json";
@Nullable
public static String getMimeType(@NonNull Context context, @NonNull Uri uri) {
String mimeType = null;
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = context.getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = getExtension(uri.toString());
if(fileExtension == null){
return null;
}
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
if(mimeType == null){
// Handle the misc file extensions
return handleMiscFileExtensions(fileExtension);
}
}
return mimeType;
}
@Nullable
private static String getExtension(@Nullable String fileName){
if(fileName == null || TextUtils.isEmpty(fileName)){
return null;
}
char[] arrayOfFilename = fileName.toCharArray();
for(int i = arrayOfFilename.length-1; i > 0; i--){
if(arrayOfFilename[i] == '.'){
return fileName.substring(i+1, fileName.length());
}
}
return null;
}
@Nullable
private static String handleMiscFileExtensions(@NonNull String extension){
if(extension.equals("json")){
return MIME_TYPE_JSON;
}
else{
return null;
}
}
}
Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
File file = new File(filePatch);
Uri uris = Uri.fromFile(file);
String mimetype = null;
if
(uris.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr =
getApplicationContext().getContentResolver();
mimetype = cr.getType(uris);
} else {
String fileExtension =
MimeTypeMap.getFileExtensionFromUrl(uris.toString());
mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase());
}
제 생각에 가장 쉬운 방법은 다음 리소스 파일을 참조하는 것입니다.
언급URL : https://stackoverflow.com/questions/8589645/how-to-determine-mime-type-of-file-in-android
'programing' 카테고리의 다른 글
각도 6 입력 키에 입력 추가 (0) | 2023.08.23 |
---|---|
Jenkins에서 PowerShell 스크립트를 작업으로 실행하는 방법 (0) | 2023.08.23 |
printf()가 플로트를 더블로 승격시키는 이유는 무엇입니까? (0) | 2023.08.23 |
Apache POI를 사용하여 암호로 보호되는 Excel 파일을 생성하시겠습니까? (0) | 2023.08.23 |
SSRS 디자이너의 데이터 집합 패널(보고서 데이터)이 사라졌습니다. (0) | 2023.08.18 |