本想用Silverlight让IP摄像头支持IE,结果做出来后发现很卡顿,不流畅,按理说Silverlight性能应该比Flash好才对,找不出原因,果断用Flash插件代替,而且Flash在Win8的Modern版的IE也支持。编写后本地测试没问题,编译进IP摄像头后就不行了,一直报Error #2048安全沙箱冲突,所以就有了这篇文章以下的故事……

首先以下的内容是可以完完全全解决问题的,感谢这篇文章《完全解决AS3 中使用Socket的安全问题.》,我是网上搜了好久才找到这篇有用的,最后还看这篇《flash跨域策略文件crossdomain.xml配置详解》。依次看完这两篇就能解决这个问题。

IP摄像头里开辟了一个端口专门用于发送跨域策略文件,然后就解决这个问题了。不懂为什么在网站根目录下放策略文件不行(网络监控显示文件被Flash正常获取了),真觉得Adobe闲得蛋疼~~。所以如果你想要用IE通过外网访问IP摄像头,除了开辟IP摄像头的端口外,还要开辟IP摄像头的策略文件发送端口 8430(If you want to use IE to access IP Camera through external network, you must open up the  port 8430 to send policy file.) 。

完成以上步骤,就能用IE正常访问IP摄像头了!

View IP Camera from Modern IE

正准备对IE加入mjpg视频流的播放支持,考虑用Silverlight实现。调试程序时候发现总是出现SecurityException异常,谷歌后发现是Silverlight不能跨域访问导致的。网上有说在加入crossdomain.xml和clientaccesspolicy.xml这两个文件就可以了(文件内容参照网上)。但是没说加在哪里,所以就加入网站根目录,发现还是抱错,然后又去网上搜,耗了一个网上找到的都是同样的文章,最后找到了一篇文章说要放在被访问站点的根域下才行,试了一下,果然不报错了,图像正常显示!

那篇文章地址 http://blog.163.com/zhaojunl_i@yeah/blog/static/1653946002011211115616826/

最后附上IE上显示mjpg视频流的截图!

MJPG_on_IE

要让Android在锁屏下继续运行,用如下的代码即可实现。

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
wl.acquire();
   ..screen will stay on during this section..
wl.release();

在实现IP摄像头锁屏下运行时,发现这个代码没效果,锁屏后程序还是会断开连接。程序是在onCreate中调用acquire()获得WakeLock的,而在onDestory中Release()掉,并且在xml中加入了相应权限,运行也没报错,按理说有效果才对。

跟踪程序后发现,每次锁屏onDestory都会被调用,所以WakeLock就给Release了。用onDestory和锁屏两个作为关键词谷歌了一下,发现这个是由于程序在横屏下锁屏后会被“竖屏”,然后如果Activity不加android:configChanges=”orientation”就会经历一次销毁再创建的过程……

参考如下  blog.csdn.net/terrantian/article/details/18670381

解决方法如下:

在对应的Activity加入android:configChanges=”orientation|screenSize”即可。最后实现了IP摄像头在锁屏下继续工作!

发现《蓝牙串口》《TCP连接》的十六进制编辑框在输入时还要自己注意添加空格太不智能了,又容易出错。所以就想着在每输入两个字符后自动加入一个空格(两个字符代表一个十六进制数,刚好可以转成一个BYTE),然后删除字符时,可以自动删除空格(不懂怎么表述,运行一下代码就知道了)。

方法:使用EditText的addTextChangedListener接口,并实现TextWatcher。具体实现代码如下:

TextWatcher autoAddSpaceTextWatcher = new TextWatcher() {
	@Override
	public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {}
 
	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		if (count == 1) {
			if ((s.length() + 1) % 3 == 0) {
				setText(s + " ");
				setSelection(s.length() + 1);
			}
		}  else if (count == 0) {
			if (s.length() > 0 && s.length() % 3 == 0) {
				setText(s.subSequence(0, s.length() - 1));
				setSelection(s.length() - 1);
			}
		}
	}
 
	@Override
	public void afterTextChanged(Editable editable) {}
};

最后调用addTextChangedListener传入autoAddSpaceTextWatcher即可!赶紧去体验新版《蓝牙串口》和《TCP连接》的十六进制输入吧!

最近在更新《轻松编辑》《IP摄像头》的网页服务器部分时,遇到了两个String的问题。

第一个是获取String占用的内存字节数,自己想当然直接用length()函数取得了长度了,可到了socket发送数据的时候总是发送不完整(字符串中包含中文),后面Debug之后才发现length得到的是字符数,而不是内存中的字节数,一个中文在UTF8编码下要占用3个字节,自然得到的长度变短了,所以发送不完整。正确做法是getBytes(),再在返回的数组中取length。

第二个是截取String指定区间的子字符串,函数substring (int start, int end)。比如要取索引2到5这4个字符,直接substring (2, 5)……然后得到的是索引2到4三个字符组成的字符串,索引5的那个字符并没有出现,后面查了一下谷歌,才发现substring (int start, int end)返回的字符串不包含索引end的字符!!!所以正确的应该是substring (2, 6)。

发现了这两个特别注意的地方,就是不知道先前的代码有没出现过这两个错误。