以下的代码是上述示例的更新,它将在MediaStore中保存图像,然后允许添加标题和描述。此外该版本包含几个UI元素,我们将基于用户在该应用程序的操作进程对这些元素的可见性进行管理。
1 package com.bluemobi.nthm.showversion; 2 3 import java.io.FileNotFoundException; 4 import android.app.Activity; 5 import android.content.ContentValues; 6 import android.content.Intent; 7 import android.graphics.Bitmap; 8 import android.graphics.BitmapFactory; 9 import android.net.Uri; 10 import android.os.Bundle; 11 import android.provider.MediaStore; 12 import android.provider.MediaStore.Images.Media; 13 import android.view.View; 14 import android.view.View.OnClickListener; 15 import android.widget.Button; 16 import android.widget.EditText; 17 import android.widget.ImageView; 18 import android.widget.TextView; 19 20 public class MediaStoreCameraIntent extends Activity { 21 private static int CAMERA_RESULT=0; 22 private Uri imageFileUri; 23 //在res/layout/mediastorecameraintent.xml中指定的用户界面元素 24 private ImageView returnedImageView; 25 private Button takePictureButton; 26 private Button saveDataButton; 27 private TextView titleTextView; 28 private TextView descriptionTextView; 29 private EditText titleEditText; 30 private EditText descriptionEditText;
我们包括了几个用户界面元素。在res/layout/mediastorecameraintent.xml中将他们指定为正常显示,并且在上述代码中声明了他们的对象。
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 //将内容视图设置为在res/layout/mediastorecameraintent.xml文件中定义的视图 5 setContentView(R.layout.cameraintentactivity); 6 //获取UI元素的引用 7 returnedImageView=(ImageView) findViewById(R.id.ReturnedImageView); 8 takePictureButton=(Button) findViewById(R.id.TakePictureButton); 9 saveDataButton=(Button) findViewById(R.id.SaveDataButton); 10 titleTextView=(TextView) findViewById(R.id.TitleTextView); 11 descriptionTextView=(TextView) findViewById(R.id.DescriptionTextView); 12 titleEditText=(EditText) findViewById(R.id.TitleEditView); 13 descriptionEditText=(EditText) findViewById(R.id.DescriptionEditView);
在标准活动onCreate方法中,调用setContentView之后将会实例化用户元素界面,然后需要在代码中对他们进行控制。在通过findViewById方法获得这些元素之后,必须将他们转化成合适的类型。
1 //除takePictureButton之外,将其他所有的元素都设置成初始时不可见 2 returnedImageView.setVisibility(View.GONE); 3 saveDataButton.setVisibility(View.GONE); 4 titleTextView.setVisibility(View.GONE); 5 descriptionTextView.setVisibility(View.GONE); 6 titleEditText.setVisibility(View.GONE); 7 descriptionEditText.setVisibility(View.GONE);
接下来,将所有的用户界面元素都设置为不可见,且不占用布局上的空间。可以在setVisibility方法中设置View.GONE常量来达到这个目的。另一个选项是View.INVISIBLE——将隐藏元素,但他们仍占用布局空间。
1 //单击拍照按钮时 2 takePictureButton.setOnClickListener(new OnClickListener() { 3 4 @Override 5 public void onClick(View v) { 6 //添加一条不带位图的新纪录 7 //返回新纪录的Uri 8 imageFileUri=getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues()); 9 //启动Camera应用程序 10 Intent i=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 11 i.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri); 12 startActivityForResult(i, CAMERA_RESULT); 13 } 14 });
在takePictureButton的OnClickListener中,创建了用于内置摄像头的标准意图,并且调用了startActivityForResult方法。在这里(而非直接在onCreate方法中)做这些工作将产生稍微好一点的用户体验。
1 saveDataButton.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 //更新MediaStore中记录的标题和描述 6 ContentValues contentValues=new ContentValues(); 7 contentValues.put(Media.DISPLAY_NAME, titleEditText.getText().toString()); 8 contentValues.put(Media.DESCRIPTION, descriptionEditText.getText().toString()); 9 getContentResolver().update(imageFileUri, contentValues, null, null); 10 //回到初始状态,设置拍照按钮为可见 11 //隐藏其他的UI元素 12 takePictureButton.setVisibility(View.VISIBLE); 13 returnedImageView.setVisibility(View.GONE); 14 saveDataButton.setVisibility(View.GONE); 15 titleTextView.setVisibility(View.GONE); 16 descriptionTextView.setVisibility(View.GONE); 17 titleEditText.setVisibility(View.GONE); 18 descriptionEditText.setVisibility(View.GONE); 19 } 20 }); 21 }
当Camera应用程序返回一幅图像时,saveDataButton按钮变得可见,其OnClickListener事件完成将图像与元数据相关联的工作。它获得用户输入到各个EditView元素中的值,并创建了一个ContentValues对象,该对象用于更新MediaStore中关于该图像的记录。
1 @Override 2 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3 super.onActivityResult(requestCode, resultCode, data); 4 if(resultCode==RESULT_OK){ 5 //Camera应用程序已经返回 6 //隐藏拍照按钮 7 takePictureButton.setVisibility(View.GONE); 8 //显示其他的UI元素 9 returnedImageView.setVisibility(View.VISIBLE); 10 saveDataButton.setVisibility(View.VISIBLE); 11 titleTextView.setVisibility(View.VISIBLE); 12 descriptionTextView.setVisibility(View.VISIBLE); 13 titleEditText.setVisibility(View.VISIBLE); 14 descriptionEditText.setVisibility(View.VISIBLE); 15 //缩放图像 16 int dw=200;//使他最多宽200个像素 17 int dh=200;//使他最多高200个像素 18 try{ 19 BitmapFactory.Options bmpBitmapFactoryOptions=new BitmapFactory.Options(); 20 bmpBitmapFactoryOptions.inJustDecodeBounds=true; 21 Bitmap bmp=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpBitmapFactoryOptions); 22 int heightRatio=(int) Math.ceil(bmpBitmapFactoryOptions.outHeight/(float)dh); 23 int widthRatio=(int) Math.ceil(bmpBitmapFactoryOptions.outWidth/(float)dw); 24 //如果两个比率都大于1, 25 //那么图像的一条边将大于屏幕 26 if(heightRatio>1&&widthRatio>1){ 27 if(heightRatio>widthRatio){ 28 //若高度比率较大,则根据它进行缩放 29 bmpBitmapFactoryOptions.inSampleSize=heightRatio; 30 }else{ 31 //若宽度比率较大,则根据它进行缩放 32 bmpBitmapFactoryOptions.inSampleSize=widthRatio; 33 } 34 } 35 //对他进行真正的解码 36 bmpBitmapFactoryOptions.inJustDecodeBounds=false; 37 bmp=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpBitmapFactoryOptions); 38 //显示图像 39 returnedImageView.setImageBitmap(bmp); 40 }catch(FileNotFoundException e){ 41 e.printStackTrace(); 42 } 43 } 44 } 45 }
下面是布局XML文件,即在上述示例中使用的"mediastorecameraintent.xml"。
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <ImageView 8 android:id="@+id/ReturnedImageView" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:contentDescription="@string/about_us"/> 12 <TextView 13 android:id="@+id/TitleTextView" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:text="Title:" 17 /> 18 <EditText 19 android:id="@+id/TitleEditView" 20 android:layout_width="fill_parent" 21 android:layout_height="wrap_content" 22 /> 23 <TextView 24 android:id="@+id/DescriptionTextView" 25 android:layout_width="wrap_content" 26 android:layout_height="wrap_content" 27 android:text="Description:" 28 /> 29 <EditText 30 android:id="@+id/DescriptionEditView" 31 android:layout_width="fill_parent" 32 android:layout_height="wrap_content" 33 /> 34 <Button 35 android:id="@+id/TakePictureButton" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:text="Take Picture" 39 /> 40 <Button 41 android:id="@+id/SaveDataButton" 42 android:layout_width="wrap_content" 43 android:layout_height="wrap_content" 44 android:text="Save Data" 45 /> 46 </LinearLayout>
与前面的示例一样,当Camera应用程序返回时触发onActivityResult方法。将新创建的图像解码成Bitmap形式并显示。在此版本中,对相关的用户界面元素进行了管理。