看了几个教程,学会 了两种方法实现Gallery相册,第一种是直接在res文件夹下放图片进行读取,第二种是读取sd卡的图片。
首先,写好布局main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Gallery android:id="@+id/gallery" android:layout_height="143px" android:layout_width="fill_parent" /> <ImageView android:layout_width="239px" android:layout_height="218px" android:layout_x="38px" android:layout_y="184px" android:id="@+id/ImageView_photo" > </ImageView> </LinearLayout>
其二,在values文件夹下新建一个attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources> <declare-styleable name="Gallery"> <attr name="android:galleryItemBackground" /> </declare-styleable> </resources>
其三,写一个类,ImageAdapter.java
package com.chaowen;
import java.io.File; import java.util.ArrayList; import java.util.List; import android.R.color; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.text.AndroidCharacter; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.BaseAdapter; import android.widget.Gallery; import android.widget.ImageView; public class ImageAdapter extends BaseAdapter { private Context ctx; int mGalleryItemBackground; private List<String> lis; //这是第一种方法,直接用res文件夹下的图片 /*public int[] images = { R.drawable.img01,R.drawable.img02, R.drawable.img03,R.drawable.img04 };*/ public ImageAdapter(Context ctx,List<String> li){ try { this.ctx = ctx; lis = li ; //使用res/values/attr.xml中的<declare-styleable>定义的Gallery属性 TypedArray a = ctx.obtainStyledAttributes(R.styleable.Gallery); //取得Gallery属性的Index id mGalleryItemBackground = a.getResourceId(R.styleable.Gallery_android_galleryItemBackground, Color.GREEN); //让对象的styleable属性能够反复使用 a.recycle(); } catch (Exception e) { e.printStackTrace(); } } @Override public int getCount() { return lis.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View converView, ViewGroup parent) { try { ImageView v = new ImageView(this.ctx); //设定图片给ImageView对象 Bitmap bm = BitmapFactory.decodeFile(lis.get(position).toString()); v.setImageBitmap(bm); /*v.setImageResource(this.images[position]);*/ //重新设定图片的宽高 v.setScaleType(ImageView.ScaleType.FIT_XY); //重新设定layout的宽高 v.setLayoutParams(new Gallery.LayoutParams(128,128)); v.setBackgroundResource(mGalleryItemBackground); return v; } catch (Exception e) { e.printStackTrace(); } return null; } }
最后,在主Activity类的代码如下
package com.chaowen; import java.io.File; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.Gallery; import android.widget.ImageView; import android.widget.Toast; public class GalleryDemo extends Activity { /** Called when the activity is first created. */ private Gallery mGallery; private ImageView imageView; private ImageAdapter imageAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mGallery =(Gallery) findViewById(R.id.gallery); imageView = (ImageView)findViewById(R.id.ImageView_photo); imageAdapter = new ImageAdapter(this,getSD()); mGallery.setAdapter(imageAdapter); mGallery.setOnItemClickListener(new Gallery.OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { //显示该图片是几号 Toast.makeText(GalleryDemo.this, "这是图片:"+position+"号", Toast.LENGTH_SHORT).show(); //设置大图片 String photoURL = getSD().get(position); // imageView.setBackgroundResource(imageAdapter.images[position]); 这是用res资源下的图片的方法进行放大 imageView.setImageURI(Uri.parse(photoURL)); } }); } /** * 获取sd卡的图片 * @return */ private List<String> getSD() { /* 设定目前所在路径 */ List<String> it=new ArrayList<String>(); File f=new File("/sdcard/dcim/Camera/"); File[] files=f.listFiles(); /* 将所有文件存入ArrayList中 */ for(int i=0;i<files.length;i++) { File file=files[i]; if(getImageFile(file.getPath())) it.add(file.getPath()); } return it; } //获得文件的类型 private boolean getImageFile(String fName) { boolean re; /* 取得扩展名 */ String end=fName.substring(fName.lastIndexOf(".")+1, fName.length()).toLowerCase(); /* 按扩展名的类型决定MimeType */ if(end.equals("jpg")||end.equals("gif")||end.equals("png") ||end.equals("jpeg")||end.equals("bmp")) { re=true; } else { re=false; } return re; } }
1.进入cmd,
2.进入makekeys所在目录,
3.输入命令:makekeys -cert -password yourpassword -len 2048 -dname "CN=Your Name OU=Development OR=Your Company Ltd CO=GB EM=your@email.com" mykey.key mycert.cer
注解:makekeys -cert //确认命令 z7t!}3E$l
-password yourpassword // -password <私钥证书的密码>
-len 2048 // -len <密钥长度(是一个素数,显然越长越好):可以为1024bit或者2048bit>
-dname "CN=Vesslan CO=CN OR=None OU=None [email=EM=Azurevesslan@gmail.com]EM=Azurevesslan@gmail.com[/email]" // -dname <引号中的注解请看下文>
CN=Vesslan //颁发者名称
CO=CN // 国家
OR=None // 组织
OU=None // 组织单位
EM=Azurevesslan@gmail.com // E-Mail
mykey.key // 私钥名称
mycert.cer // 公钥证书名称
p.s:-password命令可以不加,这个是用来设置密码的,如果没加,之后程序会问你是否设置密码,请输入N;另外,注意了,国家名称貌似只能输入2个字母。
公钥和私钥都可以用工具MakeKeys.exe生成.格式如下:% W8 u/ R& A# [9 z t' q
4 `) k- c7 H3 {7 K3 b# |
makekeys -cert -password yourpassword -len 2048 -dname "CN=Joe Bloggs OU=Development OR=Symbian Software Ltd CO=GB EM=joe.bloggs@Symbian.com" mykey.key mycert.cer: f* `
4.程序要收集随机数据,请伸出贵手,不停地在程序框里晃动鼠标,也可以在键盘上一顿乱按……
http://hi.baidu.com/%D6%C7%B4%EF%B8%DF%D4%B6lee/blog/item/b4ecabff0b5e9257d6887df0.html
第一,在应用程序中有三个线程存在:主线程(随activity的声明周期启动销毁)、feed初始化线程(进入程序时只运行一次,用于加载相册初始信息)、feed监听线程(一直在跑,监听相册和相片的变更)。
第二,不考虑CacheService 启动的主要流程归纳如下:
1.首次进入程序Gallery调用onCreate,此时发送初始化消息进入消息队列;然后Gallery调用onResume,向下进入 GridLayer的onResume,如果此时Mediafeed对象没有进行初始化则什么也不干(第一次一般都是这样),否则调用Mediafeed 的onResume;
2.处理消息队列中的HANDLE_INTENT消息,Gallery处理这个消息会初始化数据源,从而调用GridLayer的 setDataSource方法,这个方法会触发底层MediaFeed的启动方法start,执行完后启动feed监听线程继续执行MediaFeed的run方法。
start方法会作两件事:调用自己底层的重新开始方法onResume,onResume中会为图像和视频这两个媒体源分别增加“内容变化监听器”,并请求马上刷新这两个媒体源(加入全局的刷新请求列表);启动feed初始化线程mAlbumSourceThread。
3.其中MediaFeed初始化线程的工作是:调用MediaFeed的loadMediaSets加载相册,它又调用了下层 LocalDataSource中的refresh方法(查询数据库是否有相册变化,新增或修改feed中相应的MediaSet相册的名字)和 loadMediaSets方法(调用下层CacheService.loadMediaSets方法,这个方法下面会重点展开)加载所有相册和相册中的所有相片信息。
4.MediaFeed监听线程MediaFeed.run()的工作是:根据“内容变化监听器“返回的媒体变动消息(增删改),持续不断的更新MediaFeed中的相册和相片变量。
具体机制是这样的,如果全局的刷新请求列表中有内容,则调用LocalDataSource.refresh进行相册信息的更新(其中 LocalDataSource.refresh调用了CacheService的computeDirtySets),然后run遍历每个相册并调用 dataSource.loadItemsForSet()方法为相册加载相片记录。
第三,不考虑CacheService 新增和删除相片文件夹的主要流程归纳如下:
1.对应【用相机照相后退回主程序,生成camera文件夹】部分,首先GridLayer判断mMediaFeed非空即已经初始化过,则直接调用 MediaFeed.onResume方法,上面提到它会为图像和视频这两个媒体源分别增加“内容变化监听器”,并将其加入全局的刷新请求列表。
2.可别忘了MediaFeed监听线程MediaFeed.run()方法,它一直在默默无闻的等待者全局的刷新请求列表有所变化。这时第二中的4这个步骤又被激活了,这之后更新相册和相片信息就是自然的了。
3.对应【删除这个camera文件夹】,也是走的第2步这个过程