﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-amp@java-随笔分类-Android</title><link>http://www.blogjava.net/amplifier/category/50825.html</link><description>amplifier's java blog
&lt;br&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "ca-pub-5575070670019942";
/* blogjava */
google_ad_slot = "7055672771";
google_ad_width = 728;
google_ad_height = 90;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;</description><language>zh-cn</language><lastBuildDate>Fri, 17 Nov 2017 07:38:01 GMT</lastBuildDate><pubDate>Fri, 17 Nov 2017 07:38:01 GMT</pubDate><ttl>60</ttl><item><title>利用jmtp库读取手机文件</title><link>http://www.blogjava.net/amplifier/archive/2017/11/17/432903.html</link><dc:creator>amp@java</dc:creator><author>amp@java</author><pubDate>Fri, 17 Nov 2017 06:54:00 GMT</pubDate><guid>http://www.blogjava.net/amplifier/archive/2017/11/17/432903.html</guid><wfw:comment>http://www.blogjava.net/amplifier/comments/432903.html</wfw:comment><comments>http://www.blogjava.net/amplifier/archive/2017/11/17/432903.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amplifier/comments/commentRss/432903.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amplifier/services/trackbacks/432903.html</trackback:ping><description><![CDATA[&nbsp;每次换手机，把旧手机的数据迁移到新手机就是个很麻烦的事情，幸好最近华为的&#8220;手机克隆&#8221;APP越来越强大，居然能够把微信的聊天记录包括图片原封不动地迁移到新手机上，以前用微信自带的聊天记录转移功能只能转移文字信息，图片视频全部丢失，不知道现在的怎么样。手机克隆还能把SD卡的内容也转移过来，基本满足了需要。<br />
但是要把手机上的东西传到电脑就没那么简单了，现在已经没有了以前的大容量存储模式，只能选择MTP模式，这种模式其实不是一个完整的文件系统，有很多限制，所以一些传统的软件读取不到，例如FastCopy是用不了的，用Windows自带的文件管理器来复制，开始计算时间就要等很久，中间出了个错就前功尽弃；还有通过手机上的APP访问电脑共享的方式，在手机上复制也可以，但是同样会莫名其妙卡死，FTP同理，折腾了好久，还是觉得自己动手比较好。<br />
MTP协议在维基百科里解释得比较清楚：<a href="https://en.wikipedia.org/wiki/Media_Transfer_Protocol">https://en.wikipedia.org/wiki/Media_Transfer_Protocol</a> ，简单点说就是：<br />
1、不是以块设备的形式访问，跟U盘不同；<br />
2、只能单线程访问，不能同时进行多个操作，只能一个接一个；<br />
3、控制权在设备上，对外展示的内容由设备决定；<br />
4、默认不能直接对文件进行部分修改，只能复制过来修改完再复制回去，但Android对协议做了扩展，能够修改部分文件内容；<br />
5、在Linux上有些软件能够把它挂载为文件系统，这样其他软件就能像访问普通文件系统一样访问了，但是Windows下似乎没有。<br />
<br />
不过有人开发了一个在Windows下通过JNI实现的Java库jmtp，项目托管在Google Code，被墙了，但是GitHub有人fork了一个，可以下载下来，我下载的是<a href="https://github.com/reindahl/jmtp">https://github.com/reindahl/jmtp</a><br />
里面包含了C++的代码和Java的代码，以及两个已经编译好的dll文件，分别用于Win32和Win64，把其中一个dll文件放在工程目录下，再把Java源代码加入工程中即可使用，文档比较简陋，但是看test目录下的MtpTest.java，基本可以摸到如何使用了，这个协议比较简单，其实没什么功能，我要的只是把文件复制到电脑上。<br />
根据MtpTest.java，稍微修改一下，做个递归复制即可把手机上的所有文件复制到电脑上：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">package</span><span style="color: #000000; ">&nbsp;test;<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.io.File;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.io.FileWriter;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.io.IOException;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.math.BigInteger;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.nio.file.Files;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.nio.file.Path;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.nio.file.Paths;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.rmi.server.SocketSecurityException;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;java.util.ArrayList;<br />
<br />
<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;jmtp.PortableDevice;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;jmtp.PortableDeviceFolderObject;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;jmtp.PortableDeviceManager;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;jmtp.PortableDeviceObject;<br />
</span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;jmtp.PortableDeviceStorageObject;<br />
<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;TestApp&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp; </span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayList</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">PortableDeviceStorageObject</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;devices&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;ArrayList</span><span style="color: #000000; ">&lt;&gt;</span><span style="color: #000000; ">();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PortableDeviceManager&nbsp;manager&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;PortableDeviceManager();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(PortableDevice&nbsp;device&nbsp;:&nbsp;manager)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(device);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.open();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Iterate&nbsp;over&nbsp;deviceObjects</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(PortableDeviceObject&nbsp;object&nbsp;:&nbsp;device.getRootObjects())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;storageName</span><span style="color: #000000; ">=</span><span style="color: #000000; ">object.getName();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(storageName);<br />
</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;If&nbsp;the&nbsp;object&nbsp;is&nbsp;a&nbsp;storage&nbsp;object</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(object&nbsp;</span><span style="color: #0000FF; ">instanceof</span><span style="color: #000000; ">&nbsp;PortableDeviceStorageObject)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PortableDeviceStorageObject&nbsp;storage&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(PortableDeviceStorageObject)&nbsp;object;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(storage.getChildObjects().length);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(PortableDeviceObject&nbsp;child&nbsp;:&nbsp;storage.getChildObjects())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copyall(child,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">E:\\手机备份\\</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">object.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;</span><span style="color: #000000; ">&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;copyall(PortableDeviceObject&nbsp;obj,String&nbsp;path)&nbsp;{<br />
</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(obj&nbsp;</span><span style="color: #0000FF; ">instanceof</span><span style="color: #000000; ">&nbsp;PortableDeviceFolderObject)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;objName</span><span style="color: #000000; ">=</span><span style="color: #000000; ">obj.getName();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(objName.contains(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objName</span><span style="color: #000000; ">=</span><span style="color: #000000; ">objName.replace(</span><span style="color: #000000; ">'</span><span style="color: #000000; ">:</span><span style="color: #000000; ">'</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">：</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;newPath&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;path</span><span style="color: #000000; ">+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">\\</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">objName;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">创建文件夹：</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">newPath);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008000; "></span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span> File&nbsp;file&nbsp;=&nbsp;new&nbsp;File(newPath);<br />
</span><span style="color: #008000; "></span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!file.exists())&nbsp;{<br />
</span><span style="color: #008000; "></span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.mkdirs();<br />
</span><span style="color: #008000; "></span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(PortableDeviceObject&nbsp;subObj:((PortableDeviceFolderObject)&nbsp;obj).getChildObjects())&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copyall(subObj,newPath);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">&nbsp;{</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(obj.getName().contains(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">开始复制文件到：</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">path</span><span style="color: #000000; ">+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">\\</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">obj.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;file&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;File(path);<br />
</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000; "></span><span>obj.copy(file.toPath());</span><span style="color: #008000; "></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">文件复制完成！</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #000000; "><br />
}</span></div>
其中发现有点问题：<br />1、Android设备文件名里是可以包含冒号（:）的，但Windows是不可以的，所以复制到这些文件的时候会有问题，于是遇到目录名这样就把它改为中文的冒号（：），但是遇到文件名这样就不行了，因为这个库的copy函数只需要指定目标目录，不需要指定目标文件名，所以这些文件只能放弃；<br />2、Android手机的MTP协议是由&#8220;媒体存储&#8221;这个系统APP控制的，有时候手机上可以看到的文件，通过MTP访问却怎么也看不到，重启手机也不行，应该就是这个APP没有更新数据，需要把它的系统数据清除掉，等它重建完重新访问就可以看到了，不过这个重建时间非常长，可以查看它数据占用的空间，刚清除之后会发现它占用的空间会不断增长，到了不增长的时候就是重建完了，就可以正常访问了；<br />3、这个库有时候还有点bug，有一次发现它读取到的文件和文件夹都没有了最后一个.后面的部分，所以总是卡住，重新插拔一下手机数据线又没问题了；<br />4、为了避免复制了半天结果发现不完整，又要重来，最好在复制前先统计一下文件大小，看看跟手机上看到的占用存储空间是不是一致，对于MTP设备上的文件，可以通过getSize函数得到大小，把上面复制操作改为大小累加即可，速度比复制快一些，不过由于小文件太多，也不会快很多。<br /><br />把手机里的文件复制到电脑后，通过一些简单的分析，发现有很多其实是垃圾来的，也可以为手机空间清理提供参考，因为在电脑上分析起来比在手机上方便一些。例如一些视频APP的缓存，居然超过1G，占用了宝贵的内部存储空间，之前一直都没发现，通过电脑里的按文件大小搜索才发现。<img src ="http://www.blogjava.net/amplifier/aggbug/432903.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amplifier/" target="_blank">amp@java</a> 2017-11-17 14:54 <a href="http://www.blogjava.net/amplifier/archive/2017/11/17/432903.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android手机用来做电脑摄像头</title><link>http://www.blogjava.net/amplifier/archive/2014/06/05/414431.html</link><dc:creator>amp@java</dc:creator><author>amp@java</author><pubDate>Thu, 05 Jun 2014 07:35:00 GMT</pubDate><guid>http://www.blogjava.net/amplifier/archive/2014/06/05/414431.html</guid><wfw:comment>http://www.blogjava.net/amplifier/comments/414431.html</wfw:comment><comments>http://www.blogjava.net/amplifier/archive/2014/06/05/414431.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/amplifier/comments/commentRss/414431.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amplifier/services/trackbacks/414431.html</trackback:ping><description><![CDATA[现在的手机摄像头动辄几百万上千万像素，如果电脑需要用到摄像头又没有的话，不妨用手机的摄像头代替。<br /><br />我是在做一个电脑二维码识别器的时候，因为原来的摄像头太差，从而想到用一台淘汰的Android手机来代替。<br /><br />这类应用应该不少，我首先找到的是一个叫DraoidCam的应用，装好之后发现免费版没法调整分辨率，于是放弃之。<br /><br />然后又找到了一个国内做的免费软件，叫魅色，非常简单，支持USB和WiFi连接方式，如果是USB连接的话，打开USB调试模式之后，运行电脑的客户端，手机上就自动装上了App并且自动运行，可以调整分辨率，不过最高只有640*480，帧率不到10，不过已经能够满足我的需求了。<br /><br />然后就可以像普通PC摄像头一样使用了，在JMF里面也能找到，于是就可以被Java调用了。经测试，效果比原来的PC摄像头好多了。<br /><br />软件主页：<a target="_blank" href="http://www.libfetion.org/meise/ ">http://www.libfetion.org/meise/ </a><img src ="http://www.blogjava.net/amplifier/aggbug/414431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amplifier/" target="_blank">amp@java</a> 2014-06-05 15:35 <a href="http://www.blogjava.net/amplifier/archive/2014/06/05/414431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android开发：使用Fragment改造TabActivity</title><link>http://www.blogjava.net/amplifier/archive/2012/12/27/393409.html</link><dc:creator>amp@java</dc:creator><author>amp@java</author><pubDate>Thu, 27 Dec 2012 11:07:00 GMT</pubDate><guid>http://www.blogjava.net/amplifier/archive/2012/12/27/393409.html</guid><wfw:comment>http://www.blogjava.net/amplifier/comments/393409.html</wfw:comment><comments>http://www.blogjava.net/amplifier/archive/2012/12/27/393409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amplifier/comments/commentRss/393409.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amplifier/services/trackbacks/393409.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: TabActivity在API 13（Android 3.2）被标记为过期，需要使用Fragment来实现，Fragment是Android 3.0引入的一个概念，主要就是为了适应各种不同的屏幕大小（手机、平板电脑）。Android 4.1发布时，google还发布了一个Android Support v4的包，用于Android 1.6以上的系统兼容新的特性，其中包括Fragment。为了在低于...&nbsp;&nbsp;<a href='http://www.blogjava.net/amplifier/archive/2012/12/27/393409.html'>阅读全文</a><img src ="http://www.blogjava.net/amplifier/aggbug/393409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amplifier/" target="_blank">amp@java</a> 2012-12-27 19:07 <a href="http://www.blogjava.net/amplifier/archive/2012/12/27/393409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2012年3月最新版的ADT 17.0和Google AdMob Ads Sdk Android-4.3.1添加广告的方法</title><link>http://www.blogjava.net/amplifier/archive/2012/03/25/372652.html</link><dc:creator>amp@java</dc:creator><author>amp@java</author><pubDate>Sun, 25 Mar 2012 11:23:00 GMT</pubDate><guid>http://www.blogjava.net/amplifier/archive/2012/03/25/372652.html</guid><wfw:comment>http://www.blogjava.net/amplifier/comments/372652.html</wfw:comment><comments>http://www.blogjava.net/amplifier/archive/2012/03/25/372652.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/amplifier/comments/commentRss/372652.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amplifier/services/trackbacks/372652.html</trackback:ping><description><![CDATA[AdMob是往手机应用程序里添加广告的最流行的方式，Android程序基本都是靠这个赚钱。看文档似乎很简单，但是操作起来却不是那么回事，今天搞了一上午才弄明白怎么正确添加，网上搜索到的资料都不适合最新的SDK。<br /><br />按照AdMob的官方文档，很简单，只要把AdMob的开发包jar放到Build Path的Libraries里面就行了，这样做编译是没问题的，但是一运行就会出错，提示<br /><div>java.lang.NoClassDefFoundError:com.google.ads.AdView<br /></div>这是因为Google最近更新了ADT到17.0，改变了项目依赖的检测方式，官方的说明在<a target="_blank" href="http://tools.android.com/recent/dealingwithdependenciesinandroidprojects">这里</a>，不过看得不是很懂。有人用图形的方式标了出来，容易理解一些，看<a target="_blank" href="http://android.foxykeep.com/dev/how-to-fix-the-classdefnotfounderror-with-adt-17">这里</a>。如果不求甚解，就把刚才放到Build Path里面的jar移除，直接在项目目录下建立一个libs目录，然后把那个jar文件放进去就行了。<br /><br /><div>AdMob SDK也更新到了4.3.1，网上搜索到的在XML文件里面设置AdView属性的方法也已过时，现在不需要建立attrs.xml文件，直接增加一个<div>xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"<br />就可以在AdView标签里面设置ads开头的属性了，关于xml设置AdView属性的官方文档隐藏得比较深，没有在目录中列出来，只能在其他文档里面的链接里进去，在<a target="_blank" href="https://developers.google.com/mobile-ads-sdk/docs/android/banner_xml">这里</a>。<br /></div></div>另外，按照官方说明，要在AndroidManifest.xml里面添加一个Activity的声明：<br /><div>&nbsp;&nbsp;&nbsp; &lt;activity android:name="com.google.ads.AdActivity"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/&gt;</div>后面那个属性android:configChanges的最后两个值screenSize|smallestScreenSize是在Android 3.2后面才增加的，这两个值必须填上去，否则运行的时候会报错。如果你使用的SDK是3.2以下的，识别不了这两个值，编译也不会报错。因此你的项目必须使用Android 3.2以上的SDK，也就是项目根目录下的project.properties文件里面的属性target的值必须是android-13以上，例如<br /><div><div><div>target=android-15</div></div></div>但是可以在AndroidManifest.xml里面设置android:minSdkVersion和android:targetSdkVersion为比13低的值，这样就不需要安装Android 3.2以上的手机或平板来运行这个程序，实际上AdMob支持Android 1.5以上的系统，只是开发需要更高版本的SDK而已。<br /><div><br /><br />这次折腾让我真正体会到Android更新得实在太快了，连官方的文档都来不及更新，开发人员只能自己摸索总结，幸好有强大的搜索工具，只要你遇到的问题不是第一个，就会有人找到解决方案。</div><br /><br /><br /><img src ="http://www.blogjava.net/amplifier/aggbug/372652.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amplifier/" target="_blank">amp@java</a> 2012-03-25 19:23 <a href="http://www.blogjava.net/amplifier/archive/2012/03/25/372652.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过Android模拟器运行网络通信程序</title><link>http://www.blogjava.net/amplifier/archive/2012/02/24/370655.html</link><dc:creator>amp@java</dc:creator><author>amp@java</author><pubDate>Fri, 24 Feb 2012 02:37:00 GMT</pubDate><guid>http://www.blogjava.net/amplifier/archive/2012/02/24/370655.html</guid><wfw:comment>http://www.blogjava.net/amplifier/comments/370655.html</wfw:comment><comments>http://www.blogjava.net/amplifier/archive/2012/02/24/370655.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amplifier/comments/commentRss/370655.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amplifier/services/trackbacks/370655.html</trackback:ping><description><![CDATA[mars课程里关于Socket通信那一课说那些程序只能在真机上运行，模拟器模拟不了，实际上是可以的。<br />Android模拟器是通过一个类似路由器的虚拟网络层与电脑相连，可以看作模拟器是处于&#8220;内网&#8221;当中，每个模拟器都有自己的虚拟路由器，而且虚拟路由器的地址总是10.0.2.1，在模拟器看来，电脑的地址是10.0.2.2，模拟器自己的地址是10.0.2.15，无论你启动多少个模拟器，对于模拟器来说都是这样的地址，模拟器之间不能直接通信。<br />启动模拟器的时候，电脑会给模拟器分配两个端口，通过这两个端口，电脑就能操作模拟器。第一个启动的模拟器的端口是5554和5555，第二个是5556和5557，以此类推，最多可以同时启动32个模拟器。第一个端口（偶数端口）可以接受telnet连接，对模拟器进行设置，第二个端口（奇数端口）则接受adb连接，可以用来调试。第一个端口可以在模拟器窗口的标题栏看到，如下图所示：<br /><img alt="" src="http://www.blogjava.net/images/blogjava_net/amplifier/port.JPG" width="314" height="210" /><br />5554表示端口号，t表示模拟器名称。<br />实际上，这些端口也是电脑监听的端口，在电脑上通过netstat可以看到本机正在监听这些端口，因此通过telnet localhost 5554就能连上第一台模拟器，连上之后通过help命令可以查看操作帮助。<br />为了实现电脑和模拟器上的android程序进行socket通信，需要把程序开启的端口通过端口映射设置到电脑上，这跟家里的路由器端口映射概念是一样的。telnet到模拟器之后，通过<br />redir add tcp:1234:1234<br />就能把模拟器上的1234端口映射到电脑上，第一个表示电脑端口，第二个表示模拟器程序要使用端口，这两个数字可以相同也可以不同，要映射udp端口就把tcp改为udp即可<br />redir add udp:1234:1234<br />这样一来，当模拟器的程序打开1234端口时，在电脑上也打开了对应的端口，只要通过电脑连接127.0.0.1的对应端口，就连上了模拟器的程序端口，就可以通过电脑上的client向模拟器的server发送数据，不需要通过真机运行。<br />如果要让第一个模拟器向第二个模拟器发送数据，也可以把第二个模拟器的端口映射到电脑上，然后在第一个模拟器程序中向10.0.2.2的对应端口发送数据即可。<br /><br /><br />模拟器还有一个很有意思的功能，每个模拟器默认的电话号码就是它的第一个端口号，例如开了两个模拟器，第一个拨打5556，第二个就会显示5554来电，还能接通，发短信也可以，这样就能模拟电话和短信功能。<br /><br />详细的信息可以看Dev Guide的模拟器部分：<a target="_blank" href="http://developer.android.com/guide/developing/devices/emulator.html">http://developer.android.com/guide/developing/devices/emulator.html</a><img src ="http://www.blogjava.net/amplifier/aggbug/370655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amplifier/" target="_blank">amp@java</a> 2012-02-24 10:37 <a href="http://www.blogjava.net/amplifier/archive/2012/02/24/370655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>送给老婆的情人节礼物——一个Android程序</title><link>http://www.blogjava.net/amplifier/archive/2012/02/16/370080.html</link><dc:creator>amp@java</dc:creator><author>amp@java</author><pubDate>Thu, 16 Feb 2012 03:06:00 GMT</pubDate><guid>http://www.blogjava.net/amplifier/archive/2012/02/16/370080.html</guid><wfw:comment>http://www.blogjava.net/amplifier/comments/370080.html</wfw:comment><comments>http://www.blogjava.net/amplifier/archive/2012/02/16/370080.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/amplifier/comments/commentRss/370080.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amplifier/services/trackbacks/370080.html</trackback:ping><description><![CDATA[前天是情人节，虽然结婚好多年了，但是老婆一直都喜欢惊喜的浪漫，可惜我却是个木讷的呆子，做不出那些轰动的事情。那天下午马上就要下班回家了，突然在微博上看到有人谈到geek的情人节礼物，虽然我不是geek，但是最近在学Android，老婆的手机也是Android系统的，何不专门做个程序给她？<br /><br />想法可嘉，但是动起手来却不是那么回事。学了那么多天，真正派上用场的还没学到。时间只剩下不到一个小时了，我会的只是在屏幕上显示几个大字：XXX，我爱你！<br /><br />后来想想似乎太单调，如果能够加上点背景音乐可能好点，但是还没学会怎么使用，上网搜了一下，幸好很简单，用MediaPlayer就可以了，几条语句就能搞定。音乐文件怎么来呢？通过网络在线播放是最简单的，于是就到百度MP3搜了一下&#8220;情人节快乐&#8221;，我记得有一首歌里面一直在喊&#8220;情人节快乐&#8221;的，结果最后发现那首歌名字叫《没有情人的情人节》&#8230;&#8230;<br /><br />算了，管它呢，有老婆就行了，没有情人照样过情人节，打开发现链接居然是百度的，以前百度不是说它只负责搜索，不负责存放吗，怎么现在的MP3都放在百度的服务器了？把链接复制下来，在模拟器上运行还是挺好的，因为它用的是电脑的宽带，呵呵。不过过了一会提示下载失败，把那个地址往浏览器一贴，果然打不开了，原来百度这种下载链接是有有效期的，只能让你试听一下，然后下载，不是长期有效的。这就麻烦了，到时候装在手机上没声音岂不是很糗？<br /><br />再搜索一下，还好，可以把MP3文件放在assets里面，发布程序的时候把它包含在apk里面就行了，不用联网了。<br /><br />现在可以在显示大字的同时播放《没有情人的情人节》了。看了一下效果，还是有点怪异，手机的状态栏和程序的标题跟黑色的背景，红色的大字似乎不太搭配，于是继续搜索全屏代码，哈哈，两句搞定，这样炫多了。<br /><br />不过一直看着那几个字没任何反应，似乎太单调了，于是就想让它们不断变色，或者动一下也好，但是无论怎么弄都搞不定，下班时间到了，要去接老婆了，就这样吧。<br /><br />之前都是在模拟器上运行，或者接个USB在手机上运行，还不知道怎么打包成apk呢，这下居然没搜索到，可能太简单了，大家都没说。于是在项目上点右键，果然看到导出apk的菜单，我选择了unsigned方式导出，在手机上居然安装不了。再搜索一下，哦，原来是要导出成signed apk才能装的，但是我没有证书，怎么signed呢？没想到ADT还可以生成证书，一下就搞定了，这比Symbian那种签名简单多了，但是可能也是导致Android恶意软件泛滥的原因之一。<br /><br />去接老婆的时候通过蓝牙把apk发到她手机上，装上，运行，从她表情上看出，我的努力没有白费。不过最后还是发现了个严重的bug，那首歌还没放完，另外一个声音已经重新开始了，形成了&#8220;二重唱&#8221;的效果，而且程序退出之后还在唱，赶工造成的悲剧啊。<br /><br />下面是代码：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;LoveActivity&nbsp;</span><span style="color: #0000FF; ">extends</span><span style="color: #000000; ">&nbsp;Activity&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;TextView&nbsp;text;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/**</span><span style="color: #008000; ">&nbsp;Called&nbsp;when&nbsp;the&nbsp;activity&nbsp;is&nbsp;first&nbsp;created.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;onCreate(Bundle&nbsp;savedInstanceState)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">super</span><span style="color: #000000; ">.onCreate(savedInstanceState);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WindowManager.LayoutParams.FLAG_FULLSCREEN);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;requestWindowFeature(Window.FEATURE_NO_TITLE);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setContentView(R.layout.main);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MediaPlayer&nbsp;mp&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;MediaPlayer();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">try</span><span style="color: #000000; ">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AssetManager&nbsp;assetManager&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;getAssets();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AssetFileDescriptor&nbsp;afd&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;assetManager.openFd(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">a.mp3</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mp.setDataSource(afd.getFileDescriptor(),&nbsp;afd.getStartOffset(),&nbsp;afd.getLength());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mp.prepare();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mp.start();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">catch</span><span style="color: #000000; ">&nbsp;(Exception&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>main.xml:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">&lt;?</span><span style="color: #FF00FF; ">xml&nbsp;version="1.0"&nbsp;encoding="utf-8"</span><span style="color: #0000FF; ">?&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">LinearLayout&nbsp;</span><span style="color: #FF0000; ">xmlns:android</span><span style="color: #0000FF; ">="http://schemas.android.com/apk/res/android"</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;android:orientation</span><span style="color: #0000FF; ">="vertical"</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;android:layout_width</span><span style="color: #0000FF; ">="fill_parent"</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;android:layout_height</span><span style="color: #0000FF; ">="fill_parent"</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">TextView&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF0000; ">android:id</span><span style="color: #0000FF; ">="@+id/textView1"</span><span style="color: #FF0000; ">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;android:text</span><span style="color: #0000FF; ">="@string/loveyou"</span><span style="color: #FF0000; ">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;android:layout_width</span><span style="color: #0000FF; ">="match_parent"</span><span style="color: #FF0000; ">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;android:layout_height</span><span style="color: #0000FF; ">="match_parent"</span><span style="color: #FF0000; ">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;android:gravity</span><span style="color: #0000FF; ">="center"</span><span style="color: #FF0000; ">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;android:textColor</span><span style="color: #0000FF; ">="#ff0000"</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;android:textStyle</span><span style="color: #0000FF; ">="bold"</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;android:textSize</span><span style="color: #0000FF; ">="50dip"</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">/&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">LinearLayout</span><span style="color: #0000FF; ">&gt;</span></div>strings.xml：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">&lt;?</span><span style="color: #FF00FF; ">xml&nbsp;version="1.0"&nbsp;encoding="utf-8"</span><span style="color: #0000FF; ">?&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">resources</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">string&nbsp;</span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="hello"</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Hello&nbsp;World,&nbsp;LoveActivity!</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">string</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">string&nbsp;</span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="app_name"</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Love</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">string</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">string&nbsp;</span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="loveyou"</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">XXX\n我爱你</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">string</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">resources</span><span style="color: #0000ff;">&gt;</span></div>再把那首mp3放到assets里，改名为a.mp3即可。<br /><br /><br /><br /><br />希望明年能做出个更好的。<img src ="http://www.blogjava.net/amplifier/aggbug/370080.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amplifier/" target="_blank">amp@java</a> 2012-02-16 11:06 <a href="http://www.blogjava.net/amplifier/archive/2012/02/16/370080.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android和JavaSE对打印空字符串的区别</title><link>http://www.blogjava.net/amplifier/archive/2012/02/13/369867.html</link><dc:creator>amp@java</dc:creator><author>amp@java</author><pubDate>Mon, 13 Feb 2012 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/amplifier/archive/2012/02/13/369867.html</guid><wfw:comment>http://www.blogjava.net/amplifier/comments/369867.html</wfw:comment><comments>http://www.blogjava.net/amplifier/archive/2012/02/13/369867.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/amplifier/comments/commentRss/369867.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amplifier/services/trackbacks/369867.html</trackback:ping><description><![CDATA[昨天在调试一段Android程序的时候发现总是出现NullPointerException，是来自一句System.out.println()，但是把里面的内容分拆了几次都找不到哪里有null，最后发现居然是因为最终输出的字符串是null！<br /><br />一直以来，在JavaSE里，如果字符串本身是null，System.out.println()打印该字符串，会在终端输出&#8220;null&#8221;，而在Android里却是直接抛出NullPointerException，整个程序都会被终止。<br /><br />大家可以测试一下下面的语句在两种环境下的运行结果：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #000000; ">String&nbsp;s&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; ">System.out.println(s);</span></div><img src ="http://www.blogjava.net/amplifier/aggbug/369867.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amplifier/" target="_blank">amp@java</a> 2012-02-13 14:49 <a href="http://www.blogjava.net/amplifier/archive/2012/02/13/369867.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>