今天看了一道题,现在总结一下里面使用到的知识点;
1.assets文件的访问:
原文出处:http://blog.csdn.net/fengyuzhengfan/article/details/38360017
public class ImgTestActivity extends Activity implements OnClickListener{ ImageView left_arrow; ImageView iv_content; ImageView right_arrow; InputStream is = null; ArrayList<String> imgFileNameStr=new ArrayList<String>(); //存储是图片的文件名集合 int currentIndex=0;//表示当前选择中的图片 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.imgtest_activity); initView(); try { String[] fileName = getAssets().list("");//获取到assets文件夹下的所有目录; //获取内容[images, lz01.jpg, lz02bl.jpg, lz03lyou.jpg, lz04lyuan.jpg, sounds, webkit] //遍历所有的文件; for(String fString:fileName){ File fFile=new File(fString); if(!fFile.isDirectory()){ //调用该方法判断是否是图片 if(isPict(fString)){ //如果是图片就将文件名保存到集合中 imgFileNameStr.add(fString); } } } } catch (IOException e1) { e1.printStackTrace(); } setImageContent(currentIndex); } private void setImageContent(int currentIndex) { //先将第一张图片获取出来 try { //该方法将集合中的文件名取出;转换为InputStream; is = getAssets().open(imgFileNameStr.get(currentIndex)); } catch (IOException e) { e.printStackTrace(); } //设置给ImageView Bitmap bitmap=BitmapFactory.decodeStream(is); iv_content.setImageBitmap(bitmap); }
/** * @Title: isPict * @Description: 判断给出的文件名是不是一张图片 * @param @param fString */ private boolean isPict(String fString) { try { is = getAssets().open(fString); byte[] buffer = new byte[2]; //文件类型代码 String filecode = ""; //文件类型 String fileType = ""; //通过读取出来的前两个字节来判断文件类型 if (is.read(buffer) != -1) { for (int i = 0; i < buffer.length; i++) { //获取每个字节与0xFF进行与运算来获取高位, // 这个读取出来的数据不是出现负数 //并转换成字符串 filecode+=Integer.toString((buffer[i]&0xFF)); } // 把字符串再转换成Integer进行类型判断 switch (Integer.parseInt(filecode)) { case 7790: fileType = "exe"; break; case 7784: fileType = "midi"; break; case 8297: fileType = "rar"; break; case 8075: fileType = "zip"; break; case 255216: fileType = "jpg"; break; case 7173: fileType = "gif"; break; case 6677: fileType = "bmp"; break; case 13780: fileType = "png"; break; default: fileType = "unknown type: " + filecode; } } System.out.println(fileType); if (fileType.equals("png") || fileType.equals("gif") || fileType.equals("jpg")) { return true; } else { return false; } } catch (FileNotFoundException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } finally { if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } private void initView() { left_arrow = (ImageView) findViewById(R.id.left_arrow); iv_content = (ImageView) findViewById(R.id.iv_content); right_arrow = (ImageView) findViewById(R.id.right_arrow); left_arrow.setOnClickListener(this); right_arrow.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { //TODO 点击按钮切换图片 case R.id.left_arrow: currentIndex++; if(currentIndex>imgFileNameStr.size()-1){ currentIndex=0; setImageContent(currentIndex); }else { setImageContent(currentIndex); } break; case R.id.right_arrow: currentIndex--; if (currentIndex < 0) { currentIndex = imgFileNameStr.size() - 1; setImageContent(currentIndex); } else { setImageContent(currentIndex); } break; default: break; } } }
public static String createFilename() {
File file = new File(ImageUtils.UPLOAD_IMAGE_PATH);
if (!file.exists()) {
file.mkdirs();// 创建文件夹
}
@SuppressWarnings("static-access")
String fileName =ImageUtils.UPLOAD_IMAGE_PATH + new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
return fileName;
}
Uri uri=Uri.fromFile(new File(createFilename()));
bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri), null, opts);
预前知识:
Android资源文件分类:
Android资源文件大致可以分为两种:
第一种是res目录下存放的可编译的资源文件:
这种资源文件系统会在R.java里面自动生成该资源文件的ID,所以访问这种资源文件比较简单,通过R.XXX.ID即可;
第二种是assets目录下存放的原生资源文件:
因为系统在编译的时候不会编译assets下的资源文件,所以我们不能通过R.XXX.ID的方式访问它们。那我么能不能通过该资源的绝对路径去访问它们呢?因为apk安装之后会放在/data/app/**.apk目录下,以apk形式存在,asset/res和被绑定在apk里,并不会解压到/data/data/YourApp目录下去,所以我们无法直接获取到assets的绝对路径,因为它们根本就没有。
还好Android系统为我们提供了一个AssetManager工具类。
查看官方API可知,AssetManager提供对应用程序的原始资源文件进行访问;这个类提供了一个低级别的API,它允许你以简单的字节流的形式打开和读取和应用程序绑定在一起的原始资源文件。
问题一:中间有个方法可以直接返回对应drawable对象;然后设置给ImageView,回去再看一下API对象;
iv_contanct_photo.setImageBitmap(BitmapFactory.decodeResource(context.getResources(), R.mipmap.tianjia));
AssetManager类
概述:
提供对应用程序的原始资源文件进行访问;这个类提供了一个低级别的API,它允许你以简单的字节流的形式打开和读取和应用程序绑定在一起的原始资源文件。通过getAssets()方法获取AssetManager对象。
AssetManager类常用方法:
Public Methods |
|
final String[] |
list(String path) 返回指定路径下的所有文件及目录名。 |
final InputStream |
open(String fileName) 使用 ACCESS_STREAMING模式打开assets下的指定文件。. |
final InputStream |
open(String fileName, int accessMode) 使用显示的访问模式打开assets下的指定文件. |
应用实例
1.加载assets目录下的网页:
//加载assets/win8_Demo/目录下的index.html网页
webView.loadUrl("file:///android_asset/win8_Demo/index.html");
说明:这种方式可以加载assets目录下的网页,并且与网页有关的css,js,图片等文件也会的加载。
2.访问assets目录下的资源文件:
AssetManager.open(String filename),返回的是一个InputSteam类型的字节流,这里的filename必须是文件比如
(aa.txt;img/semll.jpg),而不能是文件夹。
3.获取assets的文件及目录名:
//获取assets目录下的所有文件及目录名,content(当前的上下文如Activity,Service等ContextWrapper的子类的
都可以)
String fileNames[] =context.getAssets().list(path);
4.将assets下的文件复制到SD卡:
- /**
- * 从assets目录中复制整个文件夹内容
- * @param context Context 使用CopyFiles类的Activity
- * @param oldPath String 原文件路径 如:/aa
- * @param newPath String 复制后路径 如:xx:/bb/cc
- */
- public void copyFilesFassets(Context context,String oldPath,String newPath) {
- try {
- String fileNames[] = context.getAssets().list(oldPath);//获取assets目录下的所有文件及目录名
- if (fileNames.length > 0) {//如果是目录
- File file = new File(newPath);
- file.mkdirs();//如果文件夹不存在,则递归
- for (String fileName : fileNames) {
- copyFilesFassets(context,oldPath + "/" + fileName,newPath+"/"+fileName);
- }
- } else {//如果是文件
- InputStream is = context.getAssets().open(oldPath);
- FileOutputStream fos = new FileOutputStream(new File(newPath));
- byte[] buffer = new byte[1024];
- int byteCount=0;
- while((byteCount=is.read(buffer))!=-1) {//循环从输入流读取 buffer字节
- fos.write(buffer, 0, byteCount);//将读取的输入流写入到输出流
- }
- fos.flush();//刷新缓冲区
- is.close();
- fos.close();
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- //如果捕捉到错误则通知UI线程
- MainActivity.handler.sendEmptyMessage(COPY_FALSE);
- }
- }
// 测试三:遍历asset下某个文件夹中的所有图片资源 try { InputStream is=null; Bitmap bitmap=null; String dirPath="ml_lszn_Fresh"; String photoName=null; AssetManager assetManager = getAssets(); //使用list()方法获取某文件夹下所有文件的名字 String [] photos=assetManager.list(dirPath); for (int i = 0; i < photos.length; i++) { photoName=photos[i]; //利用dirPath+"/"+photoName组拼某文件完整路径 is = assetManager.open(dirPath+"/"+photoName); bitmap = BitmapFactory.decodeStream(is); System.out.println("测试三: i="+i+" ,width=" + bitmap.getWidth() + " ,height="+ bitmap.getHeight()); } } catch (Exception e) { System.out.println("异常信息:" + e.toString()); } }
5.使用assets目录下的图片资源:
- InputStream is=getAssets().open("wpics/0ZR424L-0.jpg");
- Bitmap bitmap=BitmapFactory.decodeStream(is);
- imgShow.setImageBitmap(bitmap);
6.播放assets目录下的音乐
首先,获取通过openFd()的方法获取asset目录下指定文件的AssetFileDescriptor对象。
其次,通过MediaPlayer对象的setDataSource (FileDescriptorfd, longoffset, long length)方法加载音乐文件。最后,调用prepare方法准备音乐,start方法开始播放音乐。
预备知识:
AssetFileDescriptor简介:
在AssetManager中一项的文件描述符。这提供你自己打开的FileDescriptor可用于读取的数据,以及在文件中的
偏移量和长度的该项的数据。
可以通过AssetManager的openFd()的方法获取asset目录下指定文件的AssetFileDescriptor对象。
常用方法:
Public Methods |
|
FileInputStream |
createInputStream() 为asset创建并返回一个自动关闭的输入流。 |
FileOutputStream |
createOutputStream() 为asset创建并返回一个自动关闭的输出流。 |
FileDescriptor |
getFileDescriptor() 返回可用于读取文件中的数据的FileDescriptor对象。 |
long |
getLength() 返回该asset中项的数据的总字节数。 |
long |
getStartOffset() 返回asset中项的数据字节开始偏移。 |
具体代码:
- // 打开指定音乐文件,获取assets目录下指定文件的AssetFileDescriptor对象
- AssetFileDescriptor afd = am.openFd(music);
- mPlayer.reset();
- // 使用MediaPlayer加载指定的声音文件。
- mPlayer.setDataSource(afd.getFileDescriptor(),
- afd.getStartOffset(), afd.getLength());
- // 准备声音
- mPlayer.prepare();
- // 播放
- mPlayer.start();