Extract_icon_from_APK

Extracting Icons from APK using .NET

knowventBanner

The packaging and construction of APK files is rather simple on the surface. APK’s are really just compressed zip files. So one would imagine pulling out the selected app icon would be simple.

As you may or may not know, in order to find out which icon is selected as the app default icon you need to read the AndroidManifest.xml file. Once you have read through the AndroidManifest.xml file you will need to cross reference the icon’s resource id by reading the Resource.arsc to get url of the icon file. To make matters worse, these files are not just in any ordinary text/xml format. They are saved in a proprietary binary format.

But it doesn’t need to be this difficult.

Iteedee.ApkReader

I have open sourced a .NET library written in C# for reading/parsing APK manifest (AndroidManifest.xml) and resource data (Resources.arsc). You can find the Iteedee.ApkReader project on Github. The goal of this library is to programmatically extract base meta-data from an android application APK, including the app’s main icon location.

Reading the your APK Info

The first thing you will need to do it parse your application’s APK file into a useable data set. This article will cover doing so using the Iteedee.ApkReader’s APKInfo object. For more information on setting up parsing your application’s APK using this library read my article on Parsing APK Manifest with C# .NET.

ApkReader apkReader = new ApkReader();
ApkInfo info = apkReader.extractInfo(manifestData, resourcesData);

Once you have executed the extractInfo method and given your app is using an icon image you will have the all related in the info.iconFileName list.

This examples shows how to loop through all of the related icon locations and extract them from the APK:

for (var i = 0; i < info.iconFileName.Count; i++)
{
    ExtractApkFile.ExtractFileAndSave(APKfilePath, info.iconFileName[i], @"SampleAPK\icons\", i);
}

Again, we are uncompressing the APK to pull out the related App icon files:

public static void ExtractFileAndSave(string APKFilePath, string fileResourceLocation, string FilePathToSave, int index)
{
    using (ICSharpCode.SharpZipLib.Zip.ZipInputStream zip = new ICSharpCode.SharpZipLib.Zip.ZipInputStream(File.OpenRead(APKFilePath)))
    {
        using (var filestream = new FileStream(APKFilePath, FileMode.Open, FileAccess.Read))
        {
            ICSharpCode.SharpZipLib.Zip.ZipFile zipfile = new ICSharpCode.SharpZipLib.Zip.ZipFile(filestream);
            ICSharpCode.SharpZipLib.Zip.ZipEntry item;
            while ((item = zip.GetNextEntry()) != null)
            {
                if (item.Name.ToLower() == fileResourceLocation)
                {
                    string fileLocation = Path.Combine(FilePathToSave, string.Format("{0}-{1}", index, fileResourceLocation.Split(Convert.ToChar(@"/")).Last()));
                    using (Stream strm = zipfile.GetInputStream(item))
                    using (FileStream output = File.Create(fileLocation))
                    {
                        try
                        {
                            strm.CopyTo(output);
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }

                }
            }
        }
    }
}

Conclusion

Once you have the Manifest related data, pulling out any resource image is as simple as uncompromising the application APK and saving them to disk.

Let us know below if this help you out or if you have any questions…

Posted in .NET, Android, Mobile and tagged , , .