看了几个教程,学会 了两种方法实现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步这个过程