歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android中如何實現OEM

前幾天接到個需求,如何根據一個基礎的Android App來生成100個或更多的App,要求App icon和App name都不一樣(可能還會有配置文件)。這個有點類似於為App貼上自己的標簽,但具體功能由別人提供,有點類似於OEM,下面來分析下如何實現

仔細想一下其實這個就是apk的編譯和反編譯的應用,再加上個簽名(不簽名的話無法使用)。只不過是用代碼實現罷了

准備工作

1、配置好Java開發環境

2、下載google提供的apk編譯和反編譯工具 (包含apktool.jar、apktool.bat、aapt.exe三個文件)

3、下載google提供的簽名工具(包含sign.bat、signapk.jar兩個文件)

icon覆蓋和strings文件修改

我們都知道,在Android應用中應用的icon和應用的名稱是在AndroidManifest.xml中指定的,應用名稱的話有可能直接寫死,但多數是這種情況

            android:icon ="@drawable/ic_launcher"
            android:label ="@string/app_name"

我們只要覆蓋drawable-*下對應名字的icon圖片和修改values-*路徑下strings.xml中對應名字的屬性值就行了,為了簡單起見在這裡以drawable-hdpi和values-zh-rCN路徑來介紹

AndroidManifest.xml解析

通過上面的介紹,我們需要從 AndroidManifest.xml獲取icon和label兩個屬性的值,下面是一個簡單的解析類,該注意的地方都有注釋

/**
 * @author Tibib
 *
 */
public class AndroidManifestParser {
 
        public String NS = "http://schemas.android.com/apk/res/android" ;

    public AppInfo parse(InputStream in) throws Exception {
        try {
              //使用pull解析庫
            XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
              NS = parser.getNamespace();
              //設置使用 namespaces特性
            parser.setFeature(XmlPullParser. FEATURE_PROCESS_NAMESPACES , true );
            parser.setInput(in, "UTF-8" );
            parser.nextTag();
            return readAppInfo(parser);
        } catch (Exception e){
            e.printStackTrace();
              throw e;
        } finally {
            in.close();
        }
    }

 
    private AppInfo readAppInfo(XmlPullParser parser) throws Exception{
      AppInfo appInfo = new AppInfo();
        while (parser.next() != XmlPullParser. END_TAG) {
            if (parser.getEventType() != XmlPullParser. START_TAG) {
                continue ;
            }
            String name = parser.getName();
            // Starts by looking for the General tag
            if ("application" .equals(name)){
            String attrLabelValue = parser.getAttributeValue( NS, "label" );
            String attrIconValue = parser.getAttributeValue( NS, "icon" );
            appInfo.setAppName(attrLabelValue.split( "/" )[1]);
            appInfo.setIconName(attrIconValue.split( "/" )[1]);
            }
            else {
                skip(parser);
            }
        }
        return appInfo;
      }

        // Skips tags the parser isn't interested in. Uses depth to handle nested tags. i.e.,
    // if the next tag after a START_TAG isn't a matching END_TAG, it keeps going until it
    // finds the matching END_TAG (as indicated by the value of "depth" being 0).
    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        if (parser.getEventType() != XmlPullParser. START_TAG) {
            throw new IllegalStateException();
        }
        int depth = 1;
        while (depth != 0) {
            switch (parser.next()) {
            case XmlPullParser. END_TAG:
                    depth--;
                    break ;
            case XmlPullParser. START_TAG:
                    depth++;
                    break ;
            }
        }
    }

}

Copyright © Linux教程網 All Rights Reserved