안드로이드에서 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;
}
MimeTypeMapflv, 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 |