-1

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.

LittleFunny
  • 8,155
  • 15
  • 87
  • 198
  • 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 Answers3

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
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
  • 1
    This 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 see what you mean ... thank you for clarifying that to me – MohammedAlSafwan Jan 22 '17 at 23:13
  • how about using this to our advantage !? – MohammedAlSafwan Jan 22 '17 at 23:17
  • 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