I am writing an application which will upload a file to another device. I have to restrict how the file type to be shared to another device. I can check the file extension but is there a safer way to check the file is an apk or not.
Asked
Active
Viewed 1,153 times
-1
-
Possible duplicate of [Get real file extension -Java code](http://stackoverflow.com/questions/2091014/get-real-file-extension-java-code) – chiliNUT Jan 22 '17 at 22:56
-
If you think my answer covers what you were looking for, then can you set it as the accepted answer? – Passer by Jan 24 '17 at 12:07
3 Answers
3
Yes you can. The android apk file is a zip archive.
So you can check if the file is a zip file, and confirm that the classes.dex
and AndroidManifest.xml
files exist.

Passer by
- 562
- 9
- 14
-
Do you know how to get into the file to check it programmatically? – LittleFunny Jan 24 '17 at 21:16
-
I found the solution by using JarFile class and lookup the entry of the manifest file – LittleFunny Jan 24 '17 at 22:46
1
Considering the idea of Passer by, here is a method that checks if a file is a valid APK
public static boolean isAPK(File file) {
FileInputStream fis = null;
ZipInputStream zipIs = null;
ZipEntry zEntry = null;
String dexFile = "classes.dex";
String manifestFile = "AndroidManifest.xml";
boolean hasDex = false;
boolean hasManifest = false;
try {
fis = new FileInputStream(file);
zipIs = new ZipInputStream(new BufferedInputStream(fis));
while ((zEntry = zipIs.getNextEntry()) != null) {
if (zEntry.getName().equalsIgnoreCase(dexFile)) {
hasDex = true;
} else if (zEntry.getName().equalsIgnoreCase(manifestFile)) {
hasManifest = true;
}
if (hasDex && hasManifest) {
zipIs.close();
fis.close();
return true;
}
}
zipIs.close();
fis.close();
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
return false;
}
return false;
}

le Mandarin
- 192
- 10
0
It is possible doing this class:
new MimeTypeMap()
according to the Android documentation should give the right result:
Two-way map that maps MIME-types to file extensions and vice versa.

MohammedAlSafwan
- 872
- 1
- 8
- 25
-
1This relies on the file extension which is what the original question is trying to avoid - https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html#getContentType(java.io.File) – Passer by Jan 22 '17 at 22:53
-
:/ ... you sure ... this should check the MIME type ... not the ext – MohammedAlSafwan Jan 22 '17 at 22:56
-
Yes if the documentation is correct, it's going by a map of file extensions which it compares against, besides `MimetypesFileTypeMap` isn't available in the Android SDK. – Passer by Jan 22 '17 at 22:59
-
sorry .... I corrected my answer to using `MimeTypeMap` which is a `android.webkit` that according to the documentation should do the job – MohammedAlSafwan Jan 22 '17 at 23:04
-
`MimeTypeMap` Two-way map that maps MIME-types to file extensions and vice versa. – MohammedAlSafwan Jan 22 '17 at 23:04
-
My point is [these](https://developer.android.com/reference/android/webkit/MimeTypeMap.html) (If you look at the public methods) require you to provide a file extension. The second closest thing is [URLConnection#guessContentTypeFromStream](https://developer.android.com/reference/java/net/URLConnection.html#guessContentTypeFromStream(java.io.InputStream)) which will probably return zip archive or `application/octet-stream` as apks don't have any special byte headers. – Passer by Jan 22 '17 at 23:10
-
-
-
I have tried using URLConnection.GuessContentTypeFromStream on a pdf file but returning null. The file i passing into the stream is : /storage/emulated/0/Download/file.pdf – LittleFunny Jan 22 '17 at 23:40