当前位置: 编程技术>移动开发
本页文章导读:
▪MP3播放器项目-编撰代码-4 MP3播放器项目---编写代码---4
MP3播放器项目---编写代码---4
1.代码结构图
2.HttpDownload
package hui.download;
import hui.utils.FileUtils;
import java.io.Buff.........
▪ 关于Context,Window,LayoutInflater的兑现类 关于Context,Window,LayoutInflater的实现类
1.Context的实现类:android.app.ContextImpl2.Window的实现类:com.android.internal.policy.implMidWindow3.LayoutInflater的实现类:com.android.internal.policy.impl.MidLayoutInflater
......
▪ Unicode跟UTF-8 Unicode和UTF-8
Unicode和UTF-8 为了统一全世界各国语言文字和专业领域符号(例如数学符号、乐谱符号)的编码,ISO制定了ISO 10646标准,也称为UCS(Universal Character Set)。UCS编码的长度是31位,.........
[1]MP3播放器项目-编撰代码-4
来源: 互联网 发布时间: 2014-02-18
MP3播放器项目---编写代码---4
MP3播放器项目---编写代码---4
1.代码结构图
2.HttpDownload
package hui.download; import hui.utils.FileUtils; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class HttpDownloader { private URL url = null; /** * 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容 * 1.创建一个URL对象 * 2.通过URL对象,创建一个HttpURLConnection对象 * 3.得到InputStram * 4.从InputStream当中读取数据 * @param urlStr * @return */ public String download(String urlStr) { StringBuffer sb = new StringBuffer(); String line = null; BufferedReader buffer = null; try { // 创建一个URL对象 url = new URL(/blog_article/urlStr/index.html); // 创建一个Http连接 HttpURLConnection urlConn = (HttpURLConnection) url .openConnection(); // 使用IO流读取数据 buffer = new BufferedReader(new InputStreamReader(urlConn .getInputStream())); while ((line = buffer.readLine()) != null) { sb.append(line); } } catch (Exception e) { e.printStackTrace(); } finally { try { buffer.close(); } catch (Exception e) { e.printStackTrace(); } } return sb.toString(); } /** * 该函数返回整形 -1:代表下载文件出错 0:代表下载文件成功 1:代表文件已经存在 */ public int downFile(String urlStr, String path, String fileName) { InputStream inputStream = null; try { FileUtils fileUtils = new FileUtils(); if (fileUtils.isFileExist(fileName,path)) { return 1; } else { inputStream = getInputStreamFromUrl(urlStr); File resultFile = fileUtils.write2SDFromInput(path,fileName, inputStream); if (resultFile == null) { return -1; } } } catch (Exception e) { e.printStackTrace(); return -1; } finally { try { inputStream.close(); } catch (Exception e) { e.printStackTrace(); } } return 0; } /** * 根据URL得到输入流 * * @param urlStr * @return * @throws MalformedURLException * @throws IOException */ public InputStream getInputStreamFromUrl(/blog_article/String urlStr/index.html) throws MalformedURLException, IOException { url = new URL(/blog_article/urlStr/index.html); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); InputStream inputStream = urlConn.getInputStream(); return inputStream; } }
3.LrcProcessor
package hui.lrc; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; import java.util.regex.Matcher; import java.util.regex.Pattern; public class LrcProcessor { public ArrayList<Queue> process(InputStream inputStream) { //存放时间点数据 Queue<Long> timeMills = new LinkedList<Long>(); //存放时间点所对应的歌词 Queue<String> messages = new LinkedList<String>(); ArrayList<Queue> queues = new ArrayList<Queue>(); try { //创建BufferedReader对象 InputStreamReader inputReader = new InputStreamReader(inputStream,"UTF-8"); BufferedReader bufferedReader = new BufferedReader(inputReader); String temp = null; int i = 0; //创建一个正则表达式对象 Pattern p = Pattern.compile("\\[([^\\]]+)\\]"); String result = null; boolean b = true; while ((temp = bufferedReader.readLine()) != null) { i++; Matcher m = p.matcher(temp); if (m.find()) { if (result != null) { messages.add(result); } String timeStr = m.group(); Long timeMill = time2Long(timeStr.substring(1, timeStr .length() - 1)); if (b) { timeMills.offer(timeMill); } String msg = temp.substring(10); result = "" + msg + "\n"; } else { result = result + temp + "\n"; } } messages.add(result); queues.add(timeMills); queues.add(messages); } catch (Exception e) { e.printStackTrace(); } return queues; } /** * 将分钟,秒全部转换成毫秒 * @param timeStr * @return */ public Long time2Long(String timeStr) { String s[] = timeStr.split(":"); int min = Integer.parseInt(s[0]); String ss[] = s[1].split("\\."); int sec = Integer.parseInt(ss[0]); int mill = Integer.parseInt(ss[1]); return min * 60 * 1000 + sec * 1000 + mill * 10L; } }
4. Mp3Info
package hui.model; import java.io.Serializable; public class Mp3Info implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String id; private String mp3Name; private String mp3Size; public String getId() { return id; } public void setId(String id) { this.id = id; } public Mp3Info() { super(); } @Override public String toString() { return "Mp3Info [id=" + id + ", lrcName=" + lrcName + ", lrcSize=" + lrcSize + ", mp3Name=" + mp3Name + ", mp3Size=" + mp3Size + "]"; } public String getMp3Name() { return mp3Name; } public Mp3Info(String id, String mp3Name, String mp3Size, String lrcName, String lrcSize) { super(); this.id = id; this.mp3Name = mp3Name; this.mp3Size = mp3Size; this.lrcName = lrcName; this.lrcSize = lrcSize; } public void setMp3Name(String mp3Name) { this.mp3Name = mp3Name; } public String getMp3Size() { return mp3Size; } public void setMp3Size(String mp3Size) { this.mp3Size = mp3Size; } public String getLrcName() { return lrcName; } public void setLrcName(String lrcName) { this.lrcName = lrcName; } public String getLrcSize() { return lrcSize; } public void setLrcSize(String lrcSize) { this.lrcSize = lrcSize; } private String lrcName; private String lrcSize; }
5.FileUtils
package hui.utils; import hui.model.Mp3Info; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import android.os.Environment; public class FileUtils { private String SDCardRoot; public FileUtils() { // 得到当前外部存储设备的目录 SDCardRoot = Environment.getExternalStorageDirectory() .getAbsolutePath() + File.separator; } /** * 在SD卡上创建文件 * * @throws IOException */ public File createFileInSDCard(String fileName, String dir) throws IOException { File file = new File(SDCardRoot + dir + File.separator + fileName); System.out.println("file---->" + file); file.createNewFile(); return file; } /** * 在SD卡上创建目录 * * @param dirName */ public File creatSDDir(String dir) { File dirFile = new File(SDCardRoot + dir + File.separator); System.out.println(dirFile.mkdirs()); return dirFile; } /** * 判断SD卡上的文件夹是否存在 */ public boolean isFileExist(String fileName, String path) { File file = new File(SDCardRoot + path + File.separator + fileName); return file.exists(); } /** * 将一个InputStream里面的数据写入到SD卡中 */ public File write2SDFromInput(String path, String fileName, InputStream input) { File file = null; OutputStream output = null; try { creatSDDir(path); file = createFileInSDCard(fileName, path); output = new FileOutputStream(file); byte buffer[] = new byte[4 * 1024]; int temp; while ((temp = input.read(buffer)) != -1) { output.write(buffer, 0, temp); } output.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { output.close(); } catch (Exception e) { e.printStackTrace(); } } return file; } /** * 读取目录中的Mp3文件的名字和大小 */ public List<Mp3Info> getMp3Files(String path) { List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>(); File file = new File(SDCardRoot + File.separator + path); File[] files = file.listFiles(); FileUtils fileUtils = new FileUtils(); for (int i = 0; i < files.length; i++) { if (files[i].getName().endsWith("mp3")) { Mp3Info mp3Info = new Mp3Info(); mp3Info.setMp3Name(files[i].getName()); mp3Info.setMp3Size(files[i].length() + ""); String temp [] = mp3Info.getMp3Name().split("\\."); String eLrcName = temp[0] + ".lrc"; if(fileUtils.isFileExist(eLrcName, "/mp3")){ mp3Info.setLrcName(eLrcName); } mp3Infos.add(mp3Info); } } return mp3Infos; } }
[2] 关于Context,Window,LayoutInflater的兑现类
来源: 互联网 发布时间: 2014-02-18
关于Context,Window,LayoutInflater的实现类
1.Context的实现类:android.app.ContextImpl
2.Window的实现类:com.android.internal.policy.implMidWindow
3.LayoutInflater的实现类:com.android.internal.policy.impl.MidLayoutInflater
1.Context的实现类:android.app.ContextImpl
2.Window的实现类:com.android.internal.policy.implMidWindow
3.LayoutInflater的实现类:com.android.internal.policy.impl.MidLayoutInflater
[3] Unicode跟UTF-8
来源: 互联网 发布时间: 2014-02-18
Unicode和UTF-8
Unicode和UTF-8
为了统一全世界各国语言文字和专业领域符号(例如数学符号、乐谱符号)的编码,ISO制定了ISO 10646标准,也称为UCS(Universal Character Set)。UCS编码的长度是31位,可以表示231个字符。如果两个字符编码的高位相同,只有低16位不同,则它们属于一个平面(Plane),所以一个平面由216个字符组成。目前常用的大部分字符都位于第一个平面(编码范围是U-00000000~U-0000FFFD),称为BMP(Basic Multilingual Plane)或Plane 0,为了向后兼容,其中编号为0~256的字符和Latin-1相同。UCS编码通常用U-xxxxxxxx这种形式表示,而BMP的编码通常用U+xxxx这种形式表示,其中x是十六进制数字。在ISO制定UCS的同时,另一个由厂商联合组织也在着手制定这样的编码,称为Unicode,后来两家联手制定统一的编码,但各自发布各自的标准文档,所以UCS编码和Unicode码是相同的。
有了字符编码,另一个问题就是这样的编码在计算机中怎么表示。现在已经不可能用一个字节表示一个字符了,最直接的想法就是用四个字节表示一个字符,这种表示方法称为UCS-4或UTF-32,UTF是Unicode Transformation Format的缩写。一方面这样比较浪费存储空间,由于常用字符都集中在BMP,高位的两个字节通常是0,如果只用ASCII码或Latin-1,高位的三个字节都是0。另一种比较节省存储空间的办法是用两个字节表示一个字符,称为UCS-2或utf-8,这样只能表示BMP中的字符,但BMP中有一些扩展字符,可以用两个这样的扩展字符表示其它平面的字符,称为Surrogate Pair。无论是UTF-32还是utf-8都有一个更严重的问题是和C语言不兼容,在C语言中0字节表示字符串结尾,库函数strlen、strcpy等等都依赖于这一点,如果字符串用UTF-32存储,其中有很多0字节并不表示字符串结尾,这就乱套了。
UNIX之父Ken Thompson提出的UTF-8编码很好地解决了这些问题,现在得到广泛应用。UTF-8具有以下性质:
编码为U+0000~U+007F的字符只占一个字节,就是0x00~0x7F,和ASCII码兼容。
编码大于U+007F的字符用2~6个字节表示,每个字节的最高位都是1,而ASCII码的最高位都是0,因此非ASCII码字符的表示中不会出现ASCII码字节(也就不会出现0字节)。
用于表示非ASCII码字符的多字节序列中,第一个字节的取值范围是0xC0~0xFD,根据它可以判断后面有多少个字节也属于当前字符的编码。后面每个字节的取值范围都是0x80~0xBF,见下面的详细说明。
UCS定义的所有231个字符都可以用UTF-8编码表示出来。
UTF-8编码最长6个字节,BMP字符的UTF-8编码最长三个字节。
0xFE和0xFF这两个字节在UTF-8编码中不会出现。
具体来说,UTF-8编码有以下几种格式:
U-00000000 – U-0000007F: 0xxxxxxx
U-00000080 – U-000007FF: 110xxxxx 10xxxxxx
U-00000800 – U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 – U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 – U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 – U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
第一个字节要么最高位是0(ASCII字节),要么最高两位都是1,最高位之后1的个数决定后面有多少个字节也属于当前字符编码,例如111110xx,最高位之后还有四个1,表示后面有四个字节也属于当前字符的编码。后面每个字节的最高两位都是10,可以和第一个字节区分开。这样的设计有利于误码同步,例如在网络传输过程中丢失了几个字节,很容易判断当前字符是不完整的,也很容易找到下一个字符从哪里开始,结果顶多丢掉一两个字符,而不会导致后面的编码解释全部混乱了。上面的格式中标为x的位就是UCS编码,最后一种6字节的格式中x位有31个,可以表示31位的UCS编码,UTF-8就像一列火车,第一个字节是车头,后面每个字节是车厢,其中承载的货物是UCS编码。UTF-8规定承载的UCS编码以大端表示,也就是说第一个字节中的x是UCS编码的高位,后面字节中的x是UCS编码的低位。
例如U+00A9(©字符)的二进制是10101001,编码成UTF-8是11000010 10101001(0xC2 0xA9),但不能编码成11100000 10000010 10101001,UTF-8规定每个字符只能用尽可能少的字节来编码。
Unicode和UTF-8
为了统一全世界各国语言文字和专业领域符号(例如数学符号、乐谱符号)的编码,ISO制定了ISO 10646标准,也称为UCS(Universal Character Set)。UCS编码的长度是31位,可以表示231个字符。如果两个字符编码的高位相同,只有低16位不同,则它们属于一个平面(Plane),所以一个平面由216个字符组成。目前常用的大部分字符都位于第一个平面(编码范围是U-00000000~U-0000FFFD),称为BMP(Basic Multilingual Plane)或Plane 0,为了向后兼容,其中编号为0~256的字符和Latin-1相同。UCS编码通常用U-xxxxxxxx这种形式表示,而BMP的编码通常用U+xxxx这种形式表示,其中x是十六进制数字。在ISO制定UCS的同时,另一个由厂商联合组织也在着手制定这样的编码,称为Unicode,后来两家联手制定统一的编码,但各自发布各自的标准文档,所以UCS编码和Unicode码是相同的。
有了字符编码,另一个问题就是这样的编码在计算机中怎么表示。现在已经不可能用一个字节表示一个字符了,最直接的想法就是用四个字节表示一个字符,这种表示方法称为UCS-4或UTF-32,UTF是Unicode Transformation Format的缩写。一方面这样比较浪费存储空间,由于常用字符都集中在BMP,高位的两个字节通常是0,如果只用ASCII码或Latin-1,高位的三个字节都是0。另一种比较节省存储空间的办法是用两个字节表示一个字符,称为UCS-2或utf-8,这样只能表示BMP中的字符,但BMP中有一些扩展字符,可以用两个这样的扩展字符表示其它平面的字符,称为Surrogate Pair。无论是UTF-32还是utf-8都有一个更严重的问题是和C语言不兼容,在C语言中0字节表示字符串结尾,库函数strlen、strcpy等等都依赖于这一点,如果字符串用UTF-32存储,其中有很多0字节并不表示字符串结尾,这就乱套了。
UNIX之父Ken Thompson提出的UTF-8编码很好地解决了这些问题,现在得到广泛应用。UTF-8具有以下性质:
编码为U+0000~U+007F的字符只占一个字节,就是0x00~0x7F,和ASCII码兼容。
编码大于U+007F的字符用2~6个字节表示,每个字节的最高位都是1,而ASCII码的最高位都是0,因此非ASCII码字符的表示中不会出现ASCII码字节(也就不会出现0字节)。
用于表示非ASCII码字符的多字节序列中,第一个字节的取值范围是0xC0~0xFD,根据它可以判断后面有多少个字节也属于当前字符的编码。后面每个字节的取值范围都是0x80~0xBF,见下面的详细说明。
UCS定义的所有231个字符都可以用UTF-8编码表示出来。
UTF-8编码最长6个字节,BMP字符的UTF-8编码最长三个字节。
0xFE和0xFF这两个字节在UTF-8编码中不会出现。
具体来说,UTF-8编码有以下几种格式:
U-00000000 – U-0000007F: 0xxxxxxx
U-00000080 – U-000007FF: 110xxxxx 10xxxxxx
U-00000800 – U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 – U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 – U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 – U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
第一个字节要么最高位是0(ASCII字节),要么最高两位都是1,最高位之后1的个数决定后面有多少个字节也属于当前字符编码,例如111110xx,最高位之后还有四个1,表示后面有四个字节也属于当前字符的编码。后面每个字节的最高两位都是10,可以和第一个字节区分开。这样的设计有利于误码同步,例如在网络传输过程中丢失了几个字节,很容易判断当前字符是不完整的,也很容易找到下一个字符从哪里开始,结果顶多丢掉一两个字符,而不会导致后面的编码解释全部混乱了。上面的格式中标为x的位就是UCS编码,最后一种6字节的格式中x位有31个,可以表示31位的UCS编码,UTF-8就像一列火车,第一个字节是车头,后面每个字节是车厢,其中承载的货物是UCS编码。UTF-8规定承载的UCS编码以大端表示,也就是说第一个字节中的x是UCS编码的高位,后面字节中的x是UCS编码的低位。
例如U+00A9(©字符)的二进制是10101001,编码成UTF-8是11000010 10101001(0xC2 0xA9),但不能编码成11100000 10000010 10101001,UTF-8规定每个字符只能用尽可能少的字节来编码。
最新技术文章: