Android學習心得(18) --- 對APK包動態寫入信息

我在博客上發表一些我的Android學習心得,希望對大家能有幫助。
這一篇我們講述一下在APK包的comment中動態寫入信息。


1、介紹

APK包的壓縮方式是zip,所有和zip有着相同的文件結構,zip文件主要由三部分組成:壓縮的文件內容源數據、壓縮的目錄源數據、目錄結束標識結構。
目錄結束標識結構存在在整個歸檔包的結尾,用來標記壓縮的目錄數據的結束,其結構如下:
123
我們可以在註釋中添加一些我們自己的信息,添加後並不會影響APK的運行,而且可以實現在運行的時候動態的取出其中的信息。


2、實現

首先,我們使用一個未添加的APK,在010 Editor中進行打開查看,運行ZIP格式的模板
1
可以看到,當前這個APK中註釋信息長度爲0,則沒有註釋信息。

下面,我們編寫java程序,將註釋信息添加到其中
注意:註釋信息添加的格式是:(註釋信息,註釋信息長度)

首先,我們將需要寫入的註釋信息寫入到APK文件尾部的comment中:
這是寫入方法:將comment信息和comment長度寫入APK尾部

private static void writeAPK(File file, String comment) {
    // TODO Auto-generated method stub
    ZipFile zipFile = null;
    ByteArrayOutputStream outputStream = null;
    RandomAccessFile accessFile = null;
    try {
        zipFile = new ZipFile(file);
        String zipComment = zipFile.getComment();
        // 判斷是否包含comment信息
        if(zipComment != null) {
            // 如果有 則返回
            return ;
        }
        byte[] bytecomment = comment.getBytes();
        outputStream = new ByteArrayOutputStream();
        // 寫入comment和長度
        outputStream.write(bytecomment);
        outputStream.write(Util.short2Byte((short) bytecomment.length));
        byte[] commentdata = outputStream.toByteArray();

        accessFile = new RandomAccessFile(file, "rw");
        accessFile.seek(file.length() - 2); 
        // comment長度是short類型
        // 重新寫入comment長度,注意Android apk文件使用的是ByteOrder.LITTLE_ENDIAN(小端序);
        accessFile.write(commentdata);
        accessFile.close();
        System.out.println("插入完成!");
    } catch (Exception e) {
        // TODO: handle exception
    } finally {
        try {
            if(zipFile != null) {
                zipFile.close();
            }
            if(outputStream != null) {
                outputStream.close();
            }
            if(accessFile != null) {
                accessFile.close();
            }
        } catch(Exception e) {

        }
    }
}

既然已經插入成功,下面在運行該APK時動態讀取comment信息,然後顯示出來
這個是apk中讀取代碼:

public String readAPK(File file) {
        byte[] bytes = null;
        try {
            RandomAccessFile accessFile = new RandomAccessFile(file, "r");
            long index = accessFile.length();

            bytes = new byte[2];
            index = index - bytes.length;
            accessFile.seek(index);
            accessFile.readFully(bytes);

            int contentLength = stream2Short(bytes, 0);

            bytes = new byte[contentLength];
            index = index - bytes.length;
            accessFile.seek(index);
            accessFile.readFully(bytes);
            String a = new String(bytes, "utf-8");
            Log.d("Hello", a);
            return a;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

3、測試

測試插入程序:
在這次運行例子中,我寫入的信息是qiuyu93422,查看是否插入成功
21
發現,插入成功。
222
插入的是qiuyu93422和000A是長度。


在app中測試讀取comment信息:

我們將讀取的字符串顯示到TextView中:
123123123
成功!


4、源代碼

最後我把源代碼放出來,供大家參考一下。
JAVA插入APK源碼:https://github.com/QyMars/InjectCommentInAPK
APK顯示源碼:https://github.com/QyMars/ShowCommentAPK

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章