android影象儲存之使用MediaStore
阿新 • • 發佈:2019-02-02
學習過ContentProvider,對於影象(以及音訊和視訊)的標準內容提供器是MediaStore,MediaStore是在裝置上的一個標準位置存放檔案的設定,並且為儲存和檢索該檔案的元資料提供便利。我們使用MediaStore來儲存,而不需要在SDCard的某位置上來建立,這樣是利於系統管理的。
activity_main.xml佈局檔案:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/titleTView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/title" /> <EditText android:id="@+id/titleEView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/titleTView" android:inputType="text" /> </RelativeLayout> <ImageView android:id="@+id/imgView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/contentDescription" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/descriptionTView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/description" /> <EditText android:id="@+id/descriptionEView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/descriptionTView" android:inputType="text" /> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:id="@+id/take_pictureBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="30dp" android:text="@string/take_picture" /> <Button android:id="@+id/saveBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignTop="@id/take_pictureBtn" android:layout_marginRight="30dp" android:text="@string/save" /> </RelativeLayout> </LinearLayout>
strings.xml檔案:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">MediaStore</string> <string name="action_settings">Settings</string> <string name="hello_world">Hello world!</string> <string name="title">Title:</string> <string name="description">Description:</string> <string name="save">Save</string> <string name="take_picture">Take Picture</string> <string name="contentDescription">contentDescription</string> <string name="success">儲存成功!</string> </resources>
MainActivity.java檔案:
package cn.yh.mediastore; import java.io.FileNotFoundException; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore.Images.Media; import android.view.Display; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private final static int CAMERA_RESULT = 0; private TextView titleTView, descriptionTView; private EditText titleEView, descriptionEView; private ImageView imgView; private Button takePictureBtn, saveBtn; private Uri imageFileUri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //從佈局檔案獲取物件 titleTView = (TextView) findViewById(R.id.titleTView); titleEView = (EditText) findViewById(R.id.titleEView); descriptionTView = (TextView) findViewById(R.id.descriptionTView); descriptionEView = (EditText) findViewById(R.id.descriptionEView); imgView = (ImageView) findViewById(R.id.imgView); takePictureBtn = (Button) findViewById(R.id.take_pictureBtn); saveBtn = (Button) findViewById(R.id.saveBtn); //剛開始,除去takePictureBtn(Button)為可見之外,其他都設為不可見。 titleTView.setVisibility(View.GONE); titleEView.setVisibility(View.GONE); descriptionTView.setVisibility(View.GONE); descriptionEView.setVisibility(View.GONE); imgView.setVisibility(View.GONE); saveBtn.setVisibility(View.GONE); //給takePictureBtn設定點選事件,負責啟動android.provider.MediaStore.ACTION_IMAGE_CAPTURE也就是Camera takePictureBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.take_pictureBtn: //獲取內容解析器,由於是新建一副影象,所以使用insert方法, //Media.EXTERNAL_CONTENT_URI主要表明是放在外儲存裝置,也就是SDCard而不是記憶體 imageFileUri = getContentResolver().insert( Media.EXTERNAL_CONTENT_URI, new ContentValues()); Intent intent = new Intent( android.provider.MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri); startActivityForResult(intent, CAMERA_RESULT); break; } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { //設定拍照不可用 takePictureBtn.setEnabled(false); //設定其他操作可見 titleTView.setVisibility(View.VISIBLE); titleEView.setVisibility(View.VISIBLE); descriptionTView.setVisibility(View.VISIBLE); descriptionEView.setVisibility(View.VISIBLE); imgView.setVisibility(View.VISIBLE); saveBtn.setVisibility(View.VISIBLE); //獲取DefaultDisplay Display display = getWindowManager().getDefaultDisplay(); int eh = titleEView.getHeight() + descriptionEView.getHeight(); int bh = takePictureBtn.getHeight(); int dh = display.getHeight() - eh - bh; int dw = display.getWidth(); try { // 載入影象的尺寸,而不是影象本身。 BitmapFactory.Options bmFactoryOptions = new Options(); bmFactoryOptions.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imageFileUri), null, bmFactoryOptions); int hRatio = (int) Math.ceil(bmFactoryOptions.outHeight / (float) dh); int wRatio = (int) Math.ceil(bmFactoryOptions.outWidth / (float) dw); // 判斷是按高比率縮放還是寬比例縮放 if (hRatio > 1 || wRatio > 1) { if (hRatio > wRatio) { bmFactoryOptions.inSampleSize = hRatio; } else { bmFactoryOptions.inSampleSize = wRatio; } } // 對影象進行真正的解碼 bmFactoryOptions.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imageFileUri), null, bmFactoryOptions); imgView.setImageBitmap(bitmap); saveBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //更新MediaStore中記錄的標題和描述 ContentValues contentValues = new ContentValues(); contentValues.put(Media.DISPLAY_NAME, titleEView.getText().toString()); contentValues.put(Media.DESCRIPTION, descriptionEView.getText().toString()); getContentResolver().update(imageFileUri, contentValues, null, null); //通知使用者 Toast.makeText(MainActivity.this, R.string.success, Toast.LENGTH_LONG).show(); Intent intent = new Intent(MainActivity.this, MainActivity.class); startActivity(intent); } }); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }