一点声明:我的水平有限 这里仅仅只能写出我认为可行的方案 和 代码
文字国际化 其实是android编码的规范之一。但是不同的运营商提供的SDK 这块处理的都不一样。
就目前我接触过的平台来说。当乐 UC 91 360 算做得很好。
但是其他小平台 特别是有一个运营商 他们客户端技术才一个人。
都很不注重android文字国际化的问题。打包进ane的资源 布局文件XML必须是规范的国际化处理的。
否则就会在打包APK的时候报错。
例如下面:
一般这个错误在打包ANE的时候是不会报的。而在打包APK的时候就会报出来。
如图所示 这个错误主要是由于 ANE中的资源文件夹RES下的layout文件夹下的布局XML中的text 被SDK客户端程序员直接用代码写的。所以会直接写在layout的布局XML里面。
而一般android官方开发标准推荐更标准化的写法。把layout中的text的内容写入 value文件夹下的string.xml中。
而我们的ADT打包就是遵从这种标准。
例如layout某XML的一段:
[cc lang=”java”]
package
{
import flash.desktop.Clipboard;
import flash.desktop.ClipboardFormats;
import flash.desktop.NativeDragManager;
import flash.display.InteractiveObject;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NativeDragEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFormat;
import flashButton.backButton;
/**
*
* @author Rect 2013-4-16
*
*/
[SWF(width=”800″ , height=”600″)]
public class FileXMLHandle extends Sprite
{
private var sp:Sprite;
private var mapAry:Array = [];
private var test:TextField;
private var beginBtn:backButton;
private var SelectBtn:backButton;
private var outBtn:backButton;
private var textSize:TextField;
private var textQuality:TextField;
private var fileObj:FileReference = new FileReference();
private var selectedSaveFile:File;
private var fileArr:Array = [];
private var key:String;
public function FileXMLHandle()
{
super();
init();
}
private function init():void{
sp = new Sprite();
test = new TextField();
test.defaultTextFormat = (new TextFormat(“”,18,0xFFFFF));
test.text = “拖入此处”;
test.width = 400;
test.height = 400;
test.wordWrap = true;
test.multiline = true;
sp.addChild(test);
sp.graphics.beginFill(0x3CB371);
sp.graphics.drawRect(0,0,800,600);
sp.graphics.endFill();
this.addChild(sp);
sp.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, onDragInHandler);
sp.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onDropHandler);
selectedSaveFile = new File();
selectedSaveFile.addEventListener(flash.events.Event.SELECT, onSelectedSaveFile);
var fileFilt:FileFilter = new FileFilter(“输出文件(*.xml)”, “*.xml”);
fileArr.push(fileFilt);
beginBtn = new backButton(“开始”);
beginBtn.x = 600,beginBtn.y = 110;
beginBtn.mouseEnabled = false;
beginBtn.addEventListener(MouseEvent.CLICK,onChick);
this.addChild(beginBtn);
SelectBtn = new backButton(“选择string.xml”);
SelectBtn.x = 600,SelectBtn.y = 10;
SelectBtn.addEventListener(MouseEvent.CLICK,onSelectFile);
this.addChild(SelectBtn);
outBtn = new backButton(“选择输出文件夹”);
outBtn.x = 600,outBtn.y = 60;
outBtn.addEventListener(MouseEvent.CLICK,onSelectPath);
this.addChild(outBtn);
}
private function onSelectedSaveFile(e:flash.events.Event):void
{
var str:String = selectedSaveFile.nativePath;
var __reg:RegExp = new RegExp(‘\\\\’, ”);
switch(key)
{
case “file”:
motherFileArys = str.replace(/\\/g,”/”);
break;
case “path”:
outPath = str.replace(/\\/g,”/”);
trace(outPath)
break;
}
if(motherFileArys && outPath)HandleMaps();
}
private var motherFileArys:String = null;
private var outPath:String = null;
private var _loaderImages:URLLoader = new URLLoader();
private var stringXML:XML;
private var miscXML:XML;
private function HandleMaps():void{
_loaderImages.addEventListener(Event.COMPLETE,loaderInitListeners);
_loaderImages.load(new URLRequest(motherFileArys));
}
private function loaderInitListeners(evt:Event):void {
_loaderImages.removeEventListener(Event.COMPLETE,loaderInitListeners);
stringXML = XML(_loaderImages.data);
_loaderImages.close();
}
/**********************************/
private function onChick(ev:MouseEvent):void{
HandleMap();
}
private function onSelectFile(ev:MouseEvent):void{
key = “file”;
selectedSaveFile.browse(fileArr);
}
private function onSelectPath(ev:MouseEvent):void{
key = “path”;
selectedSaveFile.browseForDirectory(“请选择目录”);
}
private function textDown(ev:MouseEvent):void{
var text:TextField = ev.currentTarget as TextField;
text.text = “”;
}
protected function onDragInHandler(event : NativeDragEvent) : void
{
var transferable :Clipboard = event.clipboard;
if(transferable.hasFormat(ClipboardFormats.FILE_LIST_FORMAT))
{
var files : Array = transferable.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
if(files)
{
var file : File = File(files[0]);
if(file && file.name.indexOf(“.xml”) >= 0 || file && file.name.indexOf(“.XML”) >= 0)
{
NativeDragManager.acceptDragDrop(event.currentTarget as InteractiveObject);
}
}
}
}
private var motherFileAry:Array = [];
private var sonFileAry:Array = [];
private var xmlHead:String = ‘‘;
protected function onDropHandler(event : NativeDragEvent) : void
{
motherFileAry = [];
sonFileAry = [];
var transferable :Clipboard = event.clipboard;
var files : Array = transferable.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
if(files)
{
var file :File;
for(var t:int = 0;t
}
var filePath:String = motherFileArys ;
var f:FileStream = new FileStream();
var fl:File = new File(filePath);
f.open(fl,FileMode.WRITE);
var xmlStr1:String = stringXML.toString();
var pattern1:RegExp = /\n/g;
xmlStr1=xmlStr1.replace(pattern1, “\r\n”);
f.writeUTFBytes(String(xmlHead+”\r\n”+ xmlStr1));
f.close();
}
private function loaderInitListener(evt:Event):void {
_loaderImage.removeEventListener(Event.COMPLETE,loaderInitListener);
var xml:XML = XML(_loaderImage.data);
walk(xml);
makeFile(xml);
HandleMap();
}
private function makeFile(str:XML):void{
var filePath:String = (sonFileAry.splice(0,1)) ;
var f:FileStream = new FileStream();
var fl:File = new File(filePath);
f.open(fl,FileMode.WRITE);
var xmlStr:String = str.toString();
var pattern:RegExp = /\n/g;
xmlStr=xmlStr.replace(pattern, “\r\n”);
f.writeUTFBytes(String(xmlHead+”\r\n”+ xmlStr));
f.close();
}
private var stringArr:Array = [];
private var stringName:Array = [];
private var stringLen:int = 0;
private function walk( node:XML ):void {
var androidNS:Namespace = new Namespace(“android”,”http://schemas.android.com/apk/res/android”);
node.addNamespace(androidNS);
// Loop over all of the child elements of the node
for each ( var element:XML in node.elements( ) ) {
// Output the label attribute
var attributes:XMLList = element.attributes( );
for(var t:int = 0;t<100;t++) { if(!attributes[t]) break; var str:String = attributes[t] ; var pattern4:RegExp=/[\u4e00-\u9fa5]/; if(pattern4.test(str)) { stringArr.push(str); stringName.push("DW_string_" + stringLen); attributes[t] = "@string/DW_string_" + stringLen.toString(); stringLen++; } } walk( element ); } } } } [/cc] Buton [cc lang="java"] package flashButton { import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; public class backButton extends Sprite { private var _buttonName:String; private var _szWide:Number; private var _szHeight:Number; private var _Color:int; public function backButton( buttonName:String, szWide:Number = 180, szHeight:Number = 40, Color:int = 0xFFFFFF) { _buttonName = buttonName; _szWide = szWide; _szHeight = szHeight; _Color = Color; init(); } private var _text:TextField; private var _textFormat:TextFormat; private function init():void{ _text = new TextField(); _text.mouseEnabled = false; _text.text = _buttonName; _text.x = 2; _text.y = 2; _text.width = _szWide-5; _text.height = _szHeight-5; _text.autoSize = TextFieldAutoSize.CENTER; _textFormat = new TextFormat(); _textFormat.size = 25; _textFormat.color = 0;//0x228b22; _text.setTextFormat(_textFormat); addChild(_text); this.graphics.beginFill(_Color,.9); this.graphics.drawRoundRect(0,0,_szWide,_szHeight,5,5); this.graphics.endFill(); this.addEventListener(MouseEvent.ROLL_OVER,onMouseOver); this.addEventListener(MouseEvent.ROLL_OUT,onMouseOut); } private function onMouseOut(ev:MouseEvent):void{ this.graphics.clear(); this.graphics.beginFill(_Color,.9); this.graphics.drawRoundRect(0,0,_szWide,_szHeight,5,5); this.graphics.endFill(); } private function onMouseOver(ev:MouseEvent):void{ this.graphics.clear(); this.graphics.beginFill(0xeedd82,.9); this.graphics.drawRoundRect(1,1,_szWide-1,_szHeight-1,5,5); this.graphics.endFill(); } } } [/cc] 使用方式: A.选择 要处理的资源文件 res/value/string.xml B.选择输出文件夹(用来输出处理过的布局xml) C.拖动 res/layout下的所有XML到程序界面 D.点击开始 E.结束后把输出文件夹的XML复制到res/layout下 完工。。 PS:这里只针对中文 一般英文的比较少 手动修改就是了
兄弟
这个正则表达式为什么
var __reg:RegExp = new RegExp(‘\\\’, ”);
是三个\\\?是二个还是四个\才对吧
不知道为什么,在使用百度推送3.0SDK进行ANE打包后,按照前面的方法进行了资源本地化,可在生成APK的时候还是出错了,出错是
创建文件出错
aapt tool failed:invalid resource directory name:c:\user\xxx\AppData\Local\temp\xxx-xxx…\res/value
2.4的SDK打包,生成APK都一切正常
能不能集成一个百度推送啊,,搞了好久,始终有问题哎,,
资源没处理好.资源本地化已经OK,但是少部分资源被清空了,查找几字节的资源文件 在原来的地方再copy过去.或者您修改下资源本地化的代码.@JHM
aapt tool failed:invalid resource directory name:c:\xxx..xxx\res/value
在打包ANE时,在Android-ARM目录下有res\value\string.xml并且,对相应字符串都作了配置,不知道是何原故?
错误信息不完整 我估计是你资源处理出错了。你看看string.xml下的每一项是否配错@JHM
你好,能针对百度推送进行一次ANE打包嘛,实在是搞不定,照着这里面的教程都看了几遍,始终有问题。
SDK源文件发我吧.我只能周末才有时间抱歉.@JHM
你好!我会报这种资源不匹配的错误,No resource found that matches the given name (at 'background' with value '@drawable/pop_up_box_bg').是什么原因,还有一个
9-patch image C:\Users\Administrator\AppData\Local\Temp\1\be2cfe19-7135-4b4c-bce5-be5b3588e78d\res\drawable-hdpi\egame_close_button_normal.9.png malformed.这种图片格式还会报错
@sandy, 我也遇到这个问题了,能请教您怎么解决吗
使用android SDK的一款9-patch工具对每一个9.png文件处理一下 便可.@sandy
aapt tool failed:invalid resource directory name:E:\flash bulider4.6.0\sdks\4.6.0\lib\android\lib\resources\captive_runtime/res\drawable-xxhdpi
我用的是4.6 sdk,win8 64位
@leesren, 使用android SDK的一款9-patch工具对每一个9.png文件处理一下.
你好,我现在遇到的问题是使用自己封好的ane打包出APK,可以监听到init回调回来的信息,从这之后到login期间(login trace出来的信息在scout中也没有显示出来)APK会自动停止运行。我做的是金山的SDK,不知道Rect你有没有做过,给我参考参考。。
@lonic, 打开eclipse查看LogCat 看看打什么Log
其实还有一个解决办法:将AIRSDK/lib/android/bin/下的aapt重命名为aapt_bin,然后写一个简单的脚本,命名为aapt,再去调用aapt_bin,调用过程中,将参数-z去掉就OK了:
#!/bin/sh
argc=0
for curarg in “$@”
do
newargs[$argc]=”${curarg}”
if [ “${curarg}” == “-z” ];then
continue;
fi
echo ${curarg}
argc=$(expr $argc + 1)
done
echo $@
echo ${newargs[@]}
“${0}_bin” “${newargs[@]}”
如果是windows下的话,做法差不多,不要要用vs写一个可执行程序了。