Иногда ответы Джеба и Дженса не работают и возвращают ноль. В этом случае я использую следующее решение. Заголовок файла обычно содержит тип подписи. Я читаю и сравниваю с известными в списке подписей .
/**
*
* @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 видео, я использую MediaMetadataRetriever .