Как определить тип файла MIME в android?
Предположим, что у меня есть полный путь к файлу, например: (/sdcard/tlogo.png). Я хочу знать его тип mime.
Я создал для него функцию
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);
Ответы
Ответ 1
Прежде всего, вы должны подумать о вызове 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;
}
Ответ 2
Определить MIME-тип любого файла
public String getMimeType(Uri uri) {
String mimeType = null;
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = getAppContext().getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
}
return mimeType;
}
Ответ 3
Решение MimeTypeMap выше вернуло null в моем использовании. Это работает, и это проще:
Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);
Ответ 4
Оптимизированная версия Йенса answere с нуль-безопасности и запасном типа.
@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)
Бонус: вышеперечисленные методы как менее многословная функция расширения Kotlin:
fun File.getMimeType(fallback: String = "image/*"): String {
return MimeTypeMap.getFileExtensionFromUrl(toString())
?.apply { MimeTypeMap.getSingleton().getMimeTypeFromExtension(toLowerCase()) }
?: fallback // You might set it to */*
}
Ответ 5
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();
}
Ответ 6
Обратите особое внимание на решение umerk44 выше. getMimeTypeFromExtension
запускает guessMimeTypeTypeFromExtension
и имеет значение CASE SENSITIVE. Я потратил полдня на это, затем внимательно посмотрел - getMimeTypeFromExtension
вернет NULL
если вы передадите ему "JPG", тогда как он вернет "image/jpeg", если вы передадите "jpg".
Ответ 7
Вот решение, которое я использовал в своем приложении для Android:
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;
}
Ответ 8
Иногда ответы Джеба и Йенса не работают и возвращают нуль. В этом случае я использую следующее решение. Глава файла обычно содержит подпись типа. Я прочитал его и сравню с известным в списком подписей.
/**
*
* @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. Чтобы получить тип видео mime, я использую MediaMetadataRetriever.
Ответ 9
MimeTypeMap
может не распознавать некоторые расширения файлов, такие как flv, mpeg, 3gpp, cpp. Поэтому вам нужно подумать о том, как расширить MimeTypeMap для поддержки вашего кода. Вот такой пример.
http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/net/MimeUtils.java#MimeUtils
Кроме того, здесь приведен полный список типов mime
http://www.sitepoint.com/web-foundations/mime-types-complete-list/
Ответ 10
Я попытался использовать стандартные методы для определения типа mime, но я не могу сохранить расширение файла, используя MimeTypeMap.getFileExtensionFromUrl(uri.getPath()). Этот метод вернул мне пустую строку. Поэтому я сделал нетривиальное решение для сохранения расширения файла.
Вот метод, возвращающий расширение файла
private String getExtention(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 = getExtention(file.getName());
if (MimeTypeMap.getSingleton().hasExtension(extension)) {
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return mimeType;
}
Ответ 11
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
}
Ответ 12
В то время как из свойства/файла (обратите внимание, что в 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);
}
При использовании ContentResolver
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) {
}
Ответ 13
Для 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;
}
Ответ 14
Вышеупомянутое решение вернуло null в случае файла .rar, используя в этом случае URLConnection.guessContentTypeFromName(url).
Ответ 15
mime из локального файла:
String url = file.getAbsolutePath();
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mime = fileNameMap.getContentTypeFor("file://"+url);
Ответ 16
у вас есть несколько вариантов, чтобы получить расширение файла: например:
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;
}
наслаждайтесь кодом:)
Ответ 17
// 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);}
Ответ 18
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);
}
Ответ 19
Также вернул нулевое значение в моем случае путь был
/Хранение/Эмуляция /0/Музыка /01 - Призрак на танцполе .mp3
как обойти использование
val url = 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
}
в результате он возвращает результат успеха:
аудио /MPEG
Надеюсь, это кому-нибудь поможет
Ответ 20
Ни один из ответов здесь не идеален. Вот ответ, объединяющий лучшие элементы всех лучших ответов:
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;
}
}
}
Ответ 21
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());
}
Ответ 22
// 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);
}
Ответ 23
Я столкнулся с подобной проблемой. До сих пор я знаю, что результат может отличаться для разных имен, поэтому, наконец, пришел к этому решению.
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;
}