Leafsnap实现(3)-Android端实现

前面两篇文章已经把整个Leafsnap论文里面的算法和流程基本跑通了。但是既然人家把Leafsnap做成了一个app,达到了可以直接商用的效果,所以接下来我要做的就是仿照它的效果做了一个简易的Andorid下面的Application。

Android环境搭建

搭建环境的过程中基本没有碰到什么问题,只是最后在eclipse的Android SDK Manager里安装API的时候碰壁了。由于被墙的原因,导致了API无法下载的情况,后来发现Android SDK Manager安装API的时候可以使用代理虽然有国内的一些镜像站,但是速度仍然不是非常快。最后使用shadowsock + privoxy做全局代理才把API下载下来了。注意这里下载的时候由于我的电脑是在X86 windows上,image只需要下载Intel x86 Atom System Image就好了。因为镜像都比较大,全部下载会花费不少时间。
最后我使用的是5.1.1的版本,每次新建一个空项目都运行不了,出现了如下问题:

appcompat\res\values-v21\styles_base.xml:75: error: Error retrieving parent for item: No resource found that matches the given name ‘android:Widget.Material.ActionButton’.

最后的解决办法在这里,注意这里修改的是appcompat_v7的版本,而不是你自己创建的项目的版本!

Android 使用Camera

这里开发文档中提供了两种方法,一种是使用内置的应用程序,另外一种是自己创建Camera Application。为了简单起见,我使用了第一种方案。在熟悉了多个Activity之间切换和Intent的相关概念之后,使用官方提供的sample竟然出错了!拍照返回到原来的Activity的时候,Intent里面没有我想还要的图片的data。
搜了一下,找到了下面这个解决方案
最后我用文件的方式重新打开图片文件,就可以得到拍照之后的图片了。
最后不要忘记加SD卡的读写权限:

1
< uses-permission android:name ="android.permission.WRITE_EXTERNAL_STORAGE" />

Andorid socket

这里看的是Mars的视频,可以从百度网盘上,第一季中有socket的视频和code。在Android的socket其实很简单,JAVA都已经封装好了,但是我的Server是C接收,需要注意几个问题:

  1. socket接收端有接收的buffer缓冲区,一般在几K左右,但是一张图片的大小可能在1MB左右,所以需要分多次接收。
  2. 对于图片文件,有两种解决办法:一是首先接收文件长度,再分次接收文件,直到累加接收到的长度达到了图片文件的长度;二是使用自己定义的标记作为结束符来判断图片接收完毕。这里我使用的是第一种方案,大致代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int nRecvLen =0; 
while ( nRecvLen < Length ) //这里Length为文件总长度
{
int len;
if(Length - nRecvLen >= 1024)
len = recv(sockConn, buf + nRecvLen, 1024, 0);
else
{
len = recv(sockConn, buf + nRecvLen, Length - nRecvLen, 0);
nRecvLen += len;
break;
}
nRecvLen += len;
}

Android Listview

这个控件的使用也是从Mars的视频里面看到的,在第一季的13集中简单讲了Listview的使用方式。这里我直接把他的样例代码拿来修改了一下用起来了。具体就不多说了。

总结

在Android开发上由于对JAVA和eclipse平台不熟练,开发的时候碰到了不少问题。但是基本最后也都能够解决。Andorid开发的时候调试主要有两种方式,第一种是使用log输出,第二种是直接调试,F6往下走。然后注意看Log里面的error输出,基本也可以排除错误,写出一个简单的例子。
至此整个Leafsnap项目的流程已经能够跑通。这是一个练手的项目,代码有很多地方不够完善,提供了一个具体实现的思路。
Github : miibotree/Leafsnap