Java, JavaScript

Android百度地图SDK文字覆盖物的换行和旋转中心点问题

百度地图的Android SDK中支持在地图上添加各种覆盖物,其中包括文字覆盖物TextOptions,但目前版本4.1.0中此功能不支持文字换行,且不可设置文字中心点,导致如果想要和其它覆盖物混合使用时,如在图标上显示一些文字时,效果很不好,由于只能通过对文字覆盖物的经纬度坐标添加一定的偏移来实现,例如下面这样:

                        // 定位坐标偏移
                        point = new LatLng(lat+0.0001, lng);
                        OverlayOptions textOption = new TextOptions()
                                .bgColor(0xAAFFFF00)
                                .fontSize(24)
                                .fontColor(0xFFFF00FF)
                                .text("test "+formatter.format(date))
                                .position(point);
                        // 在地图上添加该文字对象并显示
                        mBaiduMap.addOverlay(textOption);

Continue reading…

百度鹰眼SDK Android版后台服务的重绑定问题

Android版百度鹰眼SDK(测试版本2.1.15)在开启定位追踪时会开启com.baidu.trace.LBSTraceService的服务来完成后台的定位和上传数据功能,此时如果应用主Activity退出(用户自行关闭,或者被系统kill等情况)时,则需要在重启时检测是否已经开启了追踪服务并可以正确停止服务。按照官方文档的说明,这种情况下应该先通过startTrace()重新进行后台服务的绑定,可以收到“onTraceCallback: 10006, 服务已开启”的结果回调,但我的实际测试结果则是,后台服务运行的情况下,应用重启startTrace()不会收到任何回调!同时又做了几种其它情况下的服务开启关闭测试,结果如下:
在应用不退出重启的情况下,不管是用同样的Trace对象,还是每次都创建同样参数的新Trace对象,都可以顺利连续开启、关闭追踪服务。而在重启应用的状态下,检测到服务正在运行后,用新创建的同样参数的Trace对象尝试startTrace时会出现收不到任何回调的情况,而如果先在应用管理器中手动停止后台服务再startTrace就没问题。
在应用重启的情况下,重新new一样参数的Trace对象,然后调用stopTrace,这样得到的回调结果是“onStopTraceFailed: 11002, 服务未开启”,但此时getRunningServices确实能够查到正在运行的后台服务。又试了通过stopService的方式直接请求停止com.baidu.trace.LBSTraceService服务,此时返回的是true,但getRunningServices依然可以检测到服务正在运行。
附上测试用的检测后台服务运行状态的方法:

    public boolean isTraceServiceRunning() {
        ActivityManager manager = (ActivityManager) getActivity().getSystemService(ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if ("com.baidu.trace.LBSTraceService".equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

最后,在联系了官方后,得到了问题的解决方法:
Continue reading…

Android Studio创建Xposed模块项目时BridgeApi的正确添加方式

使用Android Studio创建的空项目作为Xposed Module App,对于Api Jar包的引用方式,一开始是按照傻瓜式Jar Lib的处理方式,复制XposedBridgeApi-54.jar到app/lib中,然后直接右键Add As Library,也就是在build.gradle中生成了

compile files(‘lib/XposedBridgeApi-54.jar’)

这样的代码,结果写完IXposedHookLoadPackage实现类,加入assets/xposed_init,修改manifest中的meta后打包安装,Xposed Installer中也顺利检测出了新安装的模块,开启后重启系统,再看Log中出现了:

java.lang.IllegalAccessError class ref in preverified class resolved to unexpected implementation

这样的异常提示,结果当然是hook的代码也没有正确执行,研究后发现原来是jar包的引入方式不对,不能以compile方式加入,而应以provided方式,具体如下:
Continue reading…

Android中ObjectAnimator为Activity、Fragment设置过渡动画效果的方法

在iOS应用开发过程中,视图切换时的过渡动画是一个不可缺少的部分,简单的在Storyboard中托几个VC后连接上segue就可以实现,并可以选择几种如push,popover之类的动画效果,复杂的可以通过编码实现自定义的酷炫过渡动画效果(Github上有许多开源项目可以参考)。

最近一直在参研Android L的UI新特性,看到了更多注重UX的设计理解(当然也包括许多酷炫的效果,如OverScroll的新EdgeEffect、大部分控件的触摸效果,Reveal Effect等),其实从4.0 ICS开始,Android UI部分就有了很大的改进,当然也包括本篇要记录的过渡动画效果。4.0之前的UI动画主要是以Animation框架实现的,而4.0后加入了新的ObjectAnimator框架(貌似是3.0就有了,不过3.x是在没有存在感…),可以提供更多的动画控制从而实现更多的动画效果,这里记录下ObjectAnimator XML动画资源用于Activity和Fragment切换过渡动画的基本方法。

Continue reading…

Android ListView在ActionMode时改变项目View背景颜色的处理方式

Android中的ListView与iOS的UITableView提供了实现类似功能的方法,但在iOS中,表格控件的编辑状态一般都是通过菜单项触发的,而在Android中,则可以使用叫做ActionMode的行为(一般是长按列表项触发)进入表格项编辑状态,然后可以进行一些如多选批量删除之类的操作,方便快捷。进入ActionMode后,需要对列表项的选中状态进行图形上的表示,如加入选中标记,改变选中项背景颜色等,实现此操作需要配合AbsListView.MultiChoiceModeListener的事件通知及ListAdapter的getView操作:
Continue reading…

Android中GLSurfaceView在横竖屏切换时重新创建表面缓冲导致的问题

在做Android的OpenGL ES应用时,经常会遇到接入各种支付SDK等弹出UI导致当前横竖屏状态切换的问题,比如游戏是横屏landscape的,而支付SDK弹出的View是竖屏portrait的,这时如果不插手处理的话,系统会对GL的表面缓冲进行重新创建的处理,比如横屏的800×480会被重新创建为480×800,这样就会导致绘图错误,效果可以参考下面stackoverflow上贴出的图片。

解决这个问题的方法是:
Continue reading…

关于Javascript闭包closure的应用

最近在研究百度地图API的应用,试验了iOS SDK后又开始试验Web端的JS版应用,做到在地图上通过Ajax异步调用方式从后端取得数据后,添加标注并给标注添加对应的点击时间alert出此位置的信息时遇到了一个Javascript问题,最开始的code是这样写的:

		$.ajax({
			type : "get",
			url : urlStr,
			async : true,
			dataType : "json",
			error : function() {
				alert('No valid location record!');
			},
			success : function(json) {
				for(var i=0;i<json.length;i++)
				{
					var point = new BMap.Point(json[i].longtitude, json[i].latitude); 
					var marker = new BMap.Marker(point);        // 创建标注  
                                        // 添加点击事件侦听
					mark.addEventListener("click", function()
			                {
				            alert('记录时间: '+json[i].logTime+' 定位时间: '+json[i].gpsTime);
				            return;
			                });
					map.addOverlay(marker);                     // 将标注添加到地图中 
				}
		        var point = new BMap.Point(json[0].longtitude, json[0].latitude);  
        		map.centerAndZoom(point, 15);
			}
			});

这样运行时,点击任意一个标注后就会收到浏览器的js脚本错误,提示json[i].logTime还有后面同样的gpsTime部分有问题,检查了一下,发现Ajax请求成功后的函数内循环遍历数据时的i是局部变量,而每一个mark的click侦听函数内的i都为对同一个变量的引用,也就是说循环遍历后每次点击触发执行这段响应代码时的i都是同一个数,而不是认为的对应每一个mark时的i,也自然就取不到所期望的数据了!
Continue reading…

开启Gson的缩进格式Json输出

最近研究GAE上的Java支持,接触到了不少J2EE的技术,先记录一些基础小问题吧,短期内没遇到GAE硬伤导致放弃的话应该会继续丰富这方面的内容。

这次记录的是关于Java JsonGson的缩进格式输出方法。

这个库默认情况下会输出格式紧凑没有缩进的Json字符串,像这样:

{"data1":100,"data2":"hello","list":["String 1","String 2","String 3"]}

这样虽然能减少一些字节,但是开发调试时量大了的话看着会很不舒服,开启缩进格式化的方法是不要直接new Gson对象,而是使用GsonBuilder创建Gson对象,像这样:

Continue reading…

[译]Android冰淇淋三明治ICS(4.0+)JNI局部引用的变化

译序:

这篇文章的内容实际是在我发现一个项目bug后寻找解决方案时找到的,当时项目原有target为8(ICS 4.0之前的2.X版本),在4.0+的S3上运行一切正常,而后target升级到14时再在S3上运行时就会出现类似如下的native crash:

05-13 14:07:13.139: E/dalvikvm(22265): JNI ERROR (app bug): attempt to use stale local reference 0x20d00001
05-13 14:07:13.139: E/dalvikvm(22265): VM aborting
05-13 14:07:13.139: A/libc(22265): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 22457 (Thread-1276)
05-13 14:07:13.239: I/DEBUG(1894): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-13 14:07:13.249: I/DEBUG(1894): Build fingerprint: ‘samsung/m0zc/m0chn:4.1.2/JZO54K/I9300ZCEMB1:user/release-keys’
05-13 14:07:13.249: I/DEBUG(1894): pid: 22265, tid: 22457, name: Thread-1276 >>> cn.android.app <<<
05-13 14:07:13.249: I/DEBUG(1894): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
05-13 14:07:13.489: I/DEBUG(1894): r0 00000000 r1 00000000 r2 deadd00d r3 00000000
05-13 14:07:13.489: I/DEBUG(1894): r4 408cb1a8 r5 0000020c r6 20d00001 r7 fffff86c
05-13 14:07:13.489: I/DEBUG(1894): r8 5ee308dc r9 00004e58 sl fffff870 fp 5ee307b8
05-13 14:07:13.489: I/DEBUG(1894): ip 00004000 sp 5ee30540 lr 400f7c95 pc 40866e50 cpsr 60000030
05-13 14:07:13.489: I/DEBUG(1894): d0 3ff000003f800000 d1 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d2 0000000000000000 d3 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d4 0000000000000000 d5 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d6 0000000000000000 d7 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d8 0000000000000000 d9 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d10 0000000000000000 d11 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d12 0000000000000000 d13 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d14 0000000000000000 d15 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d16 0000000000000000 d17 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d18 0000000000000000 d19 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d20 0000000000000000 d21 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d22 0000000000000000 d23 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d24 0000000000000000 d25 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d26 0000000000000000 d27 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d28 0000000000000000 d29 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): d30 0000000000000000 d31 0000000000000000
05-13 14:07:13.489: I/DEBUG(1894): scr 60000010
05-13 14:07:13.499: I/DEBUG(1894): backtrace:
05-13 14:07:13.499: I/DEBUG(1894): #00 pc 00045e50 /system/lib/libdvm.so (dvmAbort+75)
05-13 14:07:13.499: I/DEBUG(1894): #01 pc 00028c3c /system/lib/libdvm.so (IndirectRefTable::get(void*) const+336)
05-13 14:07:13.499: I/DEBUG(1894): #02 pc 00049eeb /system/lib/libdvm.so (dvmDecodeIndirectRef(Thread*, _jobject*)+30)
05-13 14:07:13.499: I/DEBUG(1894): #03 pc 0004ca77 /system/lib/libdvm.so
05-13 14:07:13.499: I/DEBUG(1894): #04 pc 00653480 /data/data/cn.android.app/lib/libgameapp.so (CKSoundManager::LoadBGM(char const*)+56)

05-13 14:07:13.509: I/DEBUG(1894): memory map around fault addr deadd00d:
05-13 14:07:13.509: I/DEBUG(1894): be9ae000-be9cf000 [stack]
05-13 14:07:13.509: I/DEBUG(1894): (no map for address)
05-13 14:07:13.509: I/DEBUG(1894): ffff0000-ffff1000 [vectors]
05-13 14:07:13.674: I/DEBUG(1894): !@dumpstate -k -t -z -d -o /data/log/dumpstate_app_native -m 22265

Continue reading…

cocos2d-x创建android项目后NDK编译警告被当作错误的处理方法

问题为编译cocos2d-x创建的android项目时,原生代码部分编译脚本build_native.sh触发的NDK编译警告被当作错误处理,项目实际编译生成成功了但是Eclipse不能运行!

开发环境:

Mac OSX ML 10.8.3

Android Developer Tools Build: v21.1.0-569685 (developer.android.com下载的整合ADT SDK的Eclipse)

android-ndk-r8e 64bit

cocos2d-2.1rc0-x-2.1.2-hotfix

Continue reading…