最近在看OpenCamera的源码,表示受益很深,项目地址:https://github.com/almalence/OpenCamera
讲真,从来没有解析过XML ,虽然json很方便,但是遇到了,还是表示学习一下
assets 下的xml 文件 opencamera_modes.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<mode id="single" name="single_mode_name" savename="">
<icon id="gui_almalence_mode_single"/>
<vf id="com.almalence.plugins.histogramvf"/>
<vf id="com.almalence.plugins.barcodescannervf"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.capture" />
<processing id="com.almalence.plugins.simpleprocessing" />
<filter/>
<export id="com.almalence.plugins.export"/>
<sku/>
<howtotext id=""/>
</mode>
<mode id="burstmode" name="burst_mode_name" savename="">
<icon id="gui_almalence_mode_burst"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.histogramvf"/>
<vf id="com.almalence.plugins.barcodescannervf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.burstcapture" />
<processing id="com.almalence.plugins.simpleprocessing" />
<filter/>
<export id="com.almalence.plugins.export"/>
<sku/>
<howtotext id=""/>
</mode>
<mode id="expobracketing" name="expobracketing_mode_name" savename="BKT">
<icon id="gui_almalence_mode_expobracketing"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.expobracketingcapture" />
<processing id="com.almalence.plugins.simpleprocessing" />
<filter/>
<export id="com.almalence.plugins.export"/>
<sku/>
<howtotext id=""/>
</mode>
<mode id="hdrmode" name="hdr_mode_name" savename="HDR">
<icon id="gui_almalence_mode_hdr"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.expobracketingcapture" />
<processing id="com.almalence.plugins.hdrprocessing" />
<filter/>
<export id="com.almalence.plugins.export"/>
<sku id="plugin_almalence_hdr"/>
<howtotext id=""/>
</mode>
<mode id="nightmode" name="night_mode_name" savename="NIGHT" nameHAL="super_mode_name" savenameHAL="SUPER">
<icon id="gui_almalence_mode_night"/>
<iconHAL id="gui_almalence_mode_super"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.nightcapture" />
<processing id="com.almalence.plugins.nightprocessing" />
<filter/>
<export id="com.almalence.plugins.export"/>
<howtotext id=""/>
<sku id="plugin_almalence_super"/>
</mode>
<mode id="video" name="video_mode_name" savename="">
<icon id="gui_almalence_mode_video"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.videocapture" />
<processing id="com.almalence.plugins.simpleprocessing" />
<filter/>
<export id="com.almalence.plugins.export"/>
<sku id="plugin_almalence_video"/>
<howtotext id=""/>
</mode>
<mode id="preshot" name="preshot_mode_name" savename="PRESHOT">
<icon id="gui_almalence_mode_backintime"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.histogramvf"/>
<vf id="com.almalence.plugins.barcodescannervf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.preshotcapture" />
<processing id="com.almalence.plugins.preshotprocessing"/>
<filter/>
<export id="com.almalence.plugins.export"/>
<sku/>
<howtotext id="preshot_mode_howto"/>
</mode>
<mode id="multishot" name="multishot_mode_name" savename="MS">
<icon id="gui_almalence_mode_moving"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.histogramvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.multishotcapture" />
<processing id="com.almalence.plugins.multishotprocessing"/>
<filter/>
<export id="com.almalence.plugins.export"/>
<sku id="plugin_almalence_moving_burst"/>
<howtotext id=""/>
</mode>
<mode id="panorama_augmented" name="panorama_mode_name" savename="PANO">
<icon id="gui_almalence_mode_panorama"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.histogramvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.panoramacapture_augmented" />
<processing id="com.almalence.plugins.panoramaprocessing"/>
<filter/>
<export id="com.almalence.plugins.export"/>
<sku id="plugin_almalence_panorama"/>
<howtotext id=""/>
</mode>
<mode id="bestshotmode" name="bestshot_mode_name" savename="BEST">
<icon id="gui_almalence_mode_bestshot"/>
<vf id="com.almalence.plugins.gridvf"/>
<vf id="com.almalence.plugins.zoomvf"/>
<vf id="com.almalence.plugins.histogramvf"/>
<vf id="com.almalence.plugins.focusvf"/>
<vf id="com.almalence.plugins.infosetvf"/>
<vf id="com.almalence.plugins.aeawlockvf"/>
<vf id="com.almalence.plugins.gyrovf"/>
<capture id="com.almalence.plugins.bestshotcapture" />
<processing id="com.almalence.plugins.bestshotprocessing" />
<filter/>
<export id="com.almalence.plugins.export"/>
<sku/>
<howtotext id=""/>
</mode>
<!-- Default plugin for initial start -->
<defaultmode id="single"/>
</config>
入口是parse(Context context)方法,Google有提供XmlPullParser
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import com.almalence.opencam.cameracontroller.CameraController;
import android.content.Context;
import android.content.res.AssetManager;
import android.os.Build;
import android.util.Xml;
public class ConfigParser
{
private static final String ns = null;
private static List<Mode> modes;
private static ConfigParser configParser;
private static String defaultModeID = "";
public static ConfigParser getInstance()
{
if (configParser == null)
{
configParser = new ConfigParser();
}
return configParser;
}
private ConfigParser()
{
modes = new ArrayList<Mode>();
}
public Mode getMode(String mode)
{
Iterator<Mode> iterator = modes.iterator();
while (iterator.hasNext())
{
Mode tmp = iterator.next();
if (mode.equals(tmp.modeID))
return tmp;
}
return null;
}
public List<Mode> getList()
{
return modes;
}
public Mode getDefaultMode()
{
if (defaultModeID.isEmpty())
defaultModeID = modes.get(0).modeID;
return getMode(defaultModeID);
}
public boolean parse(Context context) throws XmlPullParserException, IOException
{
AssetManager assetManager = context.getAssets();
InputStream in = null;
try
{
in = assetManager.open("opencamera_modes.xml");
} catch (IOException e)
{
return false;
}
try
{
if (modes != null && modes.size() > 0)
modes.clear();
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in, null);
parser.nextTag();
return readConfig(parser);
} finally
{
in.close();
}
}
private boolean readConfig(XmlPullParser parser) throws XmlPullParserException, IOException
{
parser.require(XmlPullParser.START_TAG, ns, "config");
while (parser.next() != XmlPullParser.END_TAG)
{
if (parser.getEventType() != XmlPullParser.START_TAG)
{
continue;
}
String name = parser.getName();
if (name.equals("mode"))
{
Mode tmp = readMode(parser);
modes.add(tmp);
} else if (name.equals("defaultmode"))
{
defaultModeID = readDefaultMode(parser);
} else
{
skip(parser);
}
}
return true;
}
private String readDefaultMode(XmlPullParser parser) throws XmlPullParserException, IOException
{
parser.require(XmlPullParser.START_TAG, ns, "defaultmode");
String modeID = parser.getAttributeValue(null, "id");
//set super mode by default on these devices
if (CameraController.isNexus5or6 ||
CameraController.isFlex2 ||
CameraController.isOnePlusTwo||
CameraController.isGalaxyS7)
{
Iterator<Mode> it = modes.iterator();
while(it.hasNext())
{
Mode mode = it.next();
if(mode.modeID.contains("nightmode"))
modeID = "nightmode";
}
}
parser.nextTag();
return modeID;
}
private Mode readMode(XmlPullParser parser) throws XmlPullParserException, IOException
{
parser.require(XmlPullParser.START_TAG, ns, "mode");
Mode mode = new Mode();
mode.modeID = parser.getAttributeValue(null, "id");
mode.modeName = parser.getAttributeValue(null, "name");
mode.modeSaveName = parser.getAttributeValue(null, "savename");
if ((mode.modeNameHAL = parser.getAttributeValue(null, "nameHAL")) == null)
mode.modeNameHAL = mode.modeName;
if ((mode.modeSaveNameHAL = parser.getAttributeValue(null, "savenameHAL")) == null)
mode.modeSaveNameHAL = mode.modeSaveName;
while (parser.next() != XmlPullParser.END_TAG)
{
if (parser.getEventType() != XmlPullParser.START_TAG)
{
continue;
}
readTag(parser, mode);
}
return mode;
}
private void readTag(XmlPullParser parser, Mode mode) throws IOException, XmlPullParserException
{
String tag = parser.getName();
parser.require(XmlPullParser.START_TAG, ns, tag);
String id = parser.getAttributeValue(null, "id");
if (tag.equals("icon") || tag.equals("iconHAL"))
{
if (tag.equals("iconHAL"))
{
if (id != null)
mode.iconHAL = id;
else
mode.iconHAL = mode.icon;
}
else
{
if (id != null)
{
mode.icon = id;
mode.iconHAL = id;
}
}
}
else if (tag.equals("vf"))
{
if (id != null)
mode.VF.add(id);
} else if (tag.equals("capture"))
{
if (id != null)
mode.Capture = id;
} else if (tag.equals("processing"))
{
if (id != null)
mode.Processing = id;
} else if (tag.equals("filter"))
{
if (id != null)
mode.Filter.add(id);
} else if (tag.equals("export"))
{
if (id != null)
mode.Export = id;
} else if (tag.equals("sku"))
{
if (id != null)
mode.SKU = id;
} else if (tag.equals("howtotext"))
{
if (id != null)
mode.howtoText = id;
}
/*
* add additional tag processing here
*/
else
{
skip(parser);
return;
}
parser.nextTag();
return;
}
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;
default:
break;
}
}
}
}