In an Android application, all of the strings values are hard coded (labels, dialog titles, buttons, etc). My task is to extract all these strings into a resource file. Without manually going through the code and making a lot of c/p, is there a way I can extract all the Strings from the application? Using regexes? I was thinking of writing a Pattern with someting like ".*" Or somehow parsing through the code?
Edit: I am aware of the externalize strings for Eclipse, but it creates .properties file and what I need is an .xml file. So, it would take some effort again to convert it to an .xml file.
I was thinking of writing a simple program that would extract all the strings with the names of the classes the开发者_如何学Cy were found in.
Eclipse provides an externalize strings wizard. For Android-specific solutions: Externalize strings for Android project.
Hope it helps.
I wrote a short program to help me achieve this. I had a file with over hundred Strings in it, so just pressing Ctrl+1 --> Enter in each line would be too much of a hassle.
The little program takes the file location of your .java file as input and puts the info to your console for C&P. One could image improving it to crawl through the file system and do it for all .java files, but it was sufficient for my purpose...
package de.panschk.androidutil;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;
public class ExtractStringHelper {
public static void main (String[] args) throws IOException {
String fileName = "LOCATION OF .JAVA FILE";
FileInputStream fis = new FileInputStream(fileName);
streamToStringReplaceEntities(fis);
fis.close();
}
private static Set<String> varNames= new HashSet<String>();
public static void streamToStringReplaceEntities(InputStream is)
throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream codeOut = new ByteArrayOutputStream();
StringBuffer xmlOut = new StringBuffer();
boolean inLineComment = false;
boolean inMultilineComment = false;
boolean inQuotes = false;
char lastChar = ' ';
ByteArrayOutputStream stringContent = new ByteArrayOutputStream();
int result = bis.read();
while (result != -1) {
boolean inComment = inLineComment || inMultilineComment;
byte b = (byte) result;
// read next byte
result = bis.read();
boolean copyCharToBuffer = true;
if (!inQuotes && !inComment && b == '"') {
stringContent = new ByteArrayOutputStream();
inQuotes = true;
copyCharToBuffer = false;
} else if (inQuotes && b == '"') {
String content = stringContent.toString("UTF-8");
String varName = makeVariableName(content);
inQuotes = false;
addXMLContent(varName, content, xmlOut);
addCodeContent(varName, codeOut);
copyCharToBuffer = false;
} else if (inQuotes) {
copyCharToBuffer = false;
stringContent.write(b);
} else if (!inComment && !inQuotes && lastChar == '/' && b == '/') {
inLineComment = true;
} else if (!inComment && !inQuotes && lastChar == '/' && b == '*') {
inMultilineComment = true;
} else if (inLineComment && b == '\n') {
inLineComment = false;
} else if (inMultilineComment && lastChar == '*' && b == '/') {
inMultilineComment = false;
}
if (copyCharToBuffer) {
codeOut.write(b);
}
lastChar = (char) b;
}
System.out.println(codeOut.toString("UTF-8"));
System.out.println(xmlOut.toString());
}
private static void addCodeContent(String varName,
ByteArrayOutputStream codeOut) throws IOException {
String contentToAdd = "getResources().getString(R.string."+varName+")";
byte[] bytes;
try {
bytes = contentToAdd.getBytes("UTF-8");
codeOut.write(bytes);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private static void addXMLContent(String varName, String content,
StringBuffer xmlOut) {
if (!varNames.contains(varName)) {
content = content.replace("'", "\\'");
xmlOut.append(" <string name=\"").append(varName).append("\">").append(content).append("</string>\n");
varNames.add(varName);
}
}
static String makeVariableName(String s) {
s = s.replace(' ', '_');
s = s.replaceAll("[^A-Za-z0-9_]", "").toLowerCase();
return s;
}
}
精彩评论