需求:一个Android的地图应用,当在地图上点击某一建筑物(例如:逸夫楼)时将进入该建筑物的详情界面,此界面有一个按钮拍照,点击后启动系统自带的拍照功能,拍照后将图片保存在某一固定文件夹下,同一建筑物的图片文件名只有文件名末尾的数字不同。例如我之前已经在建筑物“逸夫楼”拍了两张图片,则命名分别为:“逸夫楼1”,““逸夫楼2””。那么之后我再拍逸夫楼的照片则命名为“逸夫楼3”.详情界面会显示该建筑物的所有图片。部分代码如下:
<!--布局文件相关控件-->
<Button
android:id="@+id/takePhotoBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拍照" />
<Gallery
android:id="@+id/viewGallery"
android:layout_width="200dip"
android:layout_height="200dip"
android:layout_weight="1" />
viewGallery.setAdapter(new ImageAdapter(SpotDetail2Activity.this,"/sdcard/VMapImage",spotInfo.get("Display")));
//spotInfo.get("Display"):获得当前建筑物的名称
takePhotoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
//返回外部存储卡(SD)的状态
String sdStatus = Environment.getExternalStorageState();
if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
Log.v("TestFile",
"SD card is not avaiable/writeable right now.");
return;
}
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式
FileOutputStream b = null;
String dir="/sdcard/VMapImage/";
File file = new File(dir);
if(file.exists()==false)
file.mkdirs();
dir=dir+spotInfo.get("Display"); //获得当前建筑物的名称
String fileName=dir;
int i=0;
while(true)
{
i++;
fileName=dir+i+".jpg";
file = new File(fileName);
try {
if(file.exists()==false)
{
file.createNewFile();
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
Log.v("TestFile",
"create file" +fileName+"failed!");
e.printStackTrace();
}
}
try {
b = new FileOutputStream(fileName);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
b.flush();
b.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class ImageAdapter extends BaseAdapter {
private Context mContext=null;
public String picpath=null;
private String[] myImageNames=null;
public String positionName=null;
public ImageAdapter(Context c, String path,String position) {
mContext = c;
picpath = path;
this.positionName=position;
myImageNames =getImageNames(picpath,position);
}
//获取某一目录下以某一名称开头的图片
public static String[] getImageNames(String folderPath,String positionName) {
File file01 = new File(folderPath);
int imageFileNums=0;
String[] files01 = file01.list();
ArrayList<String> nameList=new ArrayList<String>();
for (int i = 0; i < files01.length; i++) {
File file02 = new File(folderPath + "/" + files01[i]);
if (!file02.isDirectory()) {
if (isMyImageFile(file02.getName(),positionName)) {
imageFileNums++;
nameList.add(file02.getName());
}
}
}
// return (String[])nameList.toArray();
String[] files02 = new String[imageFileNums];
int j = 0;
for (int i = 0; i < files01.length; i++) {
File file02 = new File(folderPath + "/" + files01[i]);
if (!file02.isDirectory()) {
if (isMyImageFile(file02.getName(),positionName)) {
files02[j] = file02.getName();
j++;
}
}
}
return files02;
}
private static boolean isMyImageFile(String fileName,String pre) {
String fileStart=fileName.substring(0, pre.length());
if(false==fileStart.equalsIgnoreCase(pre))
return false;
String fileEnd = fileName.substring(fileName.lastIndexOf(".") + 1,
fileName.length());
if (fileEnd.equalsIgnoreCase("jpg")) {
return true;
} else if (fileEnd.equalsIgnoreCase("png")) {
return true;
} else if (fileEnd.equalsIgnoreCase("bmp")) {
return true;
} else {
return false;
}
}
public int getCount() {
return myImageNames.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView.setImageURI(Uri.parse(picpath + "/" + myImageNames[position]));
imageView.setLayoutParams(new Gallery.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
return imageView;
}
}
上面的保存的图片的方法存在的问题是图片不清晰。主要原因是图片使压缩存储的,自然就不清楚了。下面用另一种方法将,此方法保存的图片和与手机拍照的照片原形清晰度是一样的。关键代码如下:
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
String filePathString=generateNewImageFileName();
Uri mUri = Uri.fromFile(new File(filePathString));
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mUri);
try {
cameraIntent.putExtra("return-data", true);
startActivityForResult(cameraIntent, 1);
} catch (Exception e) {
e.printStackTrace();
}
}
protected String generateNewImageFileName()
{
String imagesDir=Environment.getExternalStorageDirectory()
+ "/VMapImage";
File fileDir = new File(imagesDir);
if (!fileDir.exists()) {
fileDir.mkdir();
}
imagesDir=imagesDir+"/";
String filePath="";
int i=0;
while(true)
{
i++;
filePath=imagesDir+spotInfo.get("Display")+i+".jpg";
File file = new File(filePath);
if(file.exists()==false)
break;
}
return filePath;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
//返回外部存储卡(SD)的状态
String sdStatus = Environment.getExternalStorageState();
if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
Log.v("TestFile",
"SD card is not avaiable/writeable right now.");
return;
}
imageAdapter=new ImageAdapter(SpotDetail2Activity.this,Environment.getExternalStorageDirectory()
+ "/VMapImage",spotInfo.get("Display"));
gallery.setAdapter(imageAdapter);
}
}
之后又发现一个问题:因为Gallery中显示的图片是直接获取的拍照图片。当手机像素较高时会出现内存溢出的情况。解决方法是Gallery中显示缩略图。只需将上面代码中ImageAdapter中的getView方法改写一下:
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(getBitmap(picpath + "/" + myImageNames[position]));
imageView.setLayoutParams(new Gallery.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
return imageView;
}
public Bitmap getBitmap(String path)
{
BitmapFactory.Options option = new BitmapFactory.Options();
option.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(path,option);
option.inSampleSize = option.outWidth/100;
option.inJustDecodeBounds = false;
option.inPreferredConfig = Bitmap.Config.ARGB_8888;
option.inPurgeable = true;
option.inInputShareable = true;
try {
bitmap = BitmapFactory.decodeFile(path,option);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
return bitmap;
}