Android obtains local album images and photos to obtain images,
Requirements:Find an image from a local album or call the System camera to take a photo.
Errors:
1. When we specify the uri path of the photo, we cannot use data. getData (); to get the uri. Instead, you should get the uri directly (using global variables or other methods) and set it to imageView.
ImageView. setImageURI (uri );
2. I found that the photo taken by the front camera of the mobile phone is only several hundred KB and the Image view is used directly. setImageURI (uri); there is no big problem, but the photo taken by the rear camera is relatively large. In this case, use imageView. setImageURI (uri); is prone to out of memory (oom) errors. We need to convert the URI to Bitmap first, compress the bitmap, and then use imageView. setImageBitmap (bitmap); to display images.
3. After storing the photo in the SD card, the photo cannot appear in the system album immediately. Therefore, we need to send a broadcast to remind the album to update the photo.
4. sharepreference is used here. Note that the cache will be removed after use.
Code:
MainActivity:
Package com.sctu.edu. test;
Import android. content. Intent;
Import android. graphics. Bitmap;
Import android. graphics. BitmapFactory;
Import android.net. Uri;
Import android. OS. Bundle;
Import android. OS. Environment;
Import android. provider. MediaStore;
Import android. support. v7.app. AppCompatActivity;
Import android. util. Log;
Import android. view. View;
Import android. widget. ImageView;
Import com.sctu.edu. test. tools. ImageTools;
Import java. io. File;
Import java. io. IOException;
Import java. text. SimpleDateFormat;
Import java. util. Date;
Public class MainActivity extends AppCompatActivity {
Private static final int PHOTO_FROM_GALLERY = 1;
Private static final int PHOTO_FROM_CAMERA = 2;
Private ImageView imageView;
Private File appDir;
Private Uri uriForCamera;
Private Date date;
Private String str = "";
Private SharePreference sharePreference;
@ Override
Protected void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. activity_main );
// Global variables are not recommended for Android. I use sharePreference here.
SharePreference = SharePreference. getInstance (this );
ImageView = (ImageView) findViewById (R. id. imageView );
}
// Retrieve the image from the album
Public void gallery (View view ){
Intent intent = new Intent ();
Intent. setType ("image /*");
Intent. setAction (Intent. ACTION_GET_CONTENT );
StartActivityForResult (intent, PHOTO_FROM_GALLERY );
}
// Take a picture
Public void camera (View view ){
Intent intent = new Intent (MediaStore. ACTION_IMAGE_CAPTURE );
UriForCamera = Uri. fromFile (createImageStoragePath ());
SharePreference. setCache ("uri", String. valueOf (uriForCamera ));
/**
* If the uri path is specified, startActivityForResult does not return intent,
* Therefore, the uri cannot be obtained through data. getData () in onActivityResult;
*/
Intent. putExtra (MediaStore. EXTRA_OUTPUT, uriForCamera );
StartActivityForResult (intent, PHOTO_FROM_CAMERA );
}
@ Override
Protected void onActivityResult (int requestCode, int resultCode, Intent data ){
Super. onActivityResult (requestCode, resultCode, data );
// The first layer switch
Switch (requestCode ){
Case PHOTO_FROM_GALLERY:
// Layer 2 switch
Switch (resultCode ){
Case RESULT_ OK:
If (data! = Null ){
Uri uri = data. getData ();
ImageView. setImageURI (uri );
}
Break;
Case RESULT_CANCELED:
Break;
}
Break;
Case PHOTO_FROM_CAMERA:
If (resultCode = RESULT_ OK ){
Uri uri = Uri. parse (sharePreference. getString ("uri "));
UpdateDCIM (uri );
Try {
// Convert URI to Bitmap and compress bitmap to prevent OOM (out of memory)
Bitmap bitmap = ImageTools. getBitmapFromUri (uri, this );
ImageView. setImageBitmap (bitmap );
} Catch (IOException e ){
E. printStackTrace ();
}
RemoveCache ("uri ");
} Else {
Log. e ("result", "is not OK" + resultCode );
}
Break;
Default:
Break;
}
}
/**
* Set the photo storage path, store the photo in the SD card, and then operate
*
* @ Return
*/
Private File createImageStoragePath (){
If (hasSdcard ()){
AppDir = new File ("/sdcard/testImage /");
If (! AppDir. exists ()){
AppDir. mkdirs ();
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyyMMddHHmmss ");
Date = new Date ();
Str = simpleDateFormat. format (date );
String fileName = str + ". jpg ";
File file = new File (appDir, fileName );
Return file;
} Else {
Log. e ("sd", "is not load ");
Return null;
}
}
/**
* Insert the photo into the system album to remind you to update the album.
*
* @ Param uri
*/
Private void updateDCIM (Uri uri ){
Intent intent = new Intent (Intent. ACTION_MEDIA_SCANNER_SCAN_FILE );
Intent. setData (uri );
This. sendBroadcast (intent );
Bitmap bitmap = BitmapFactory. decodeFile (uri. getPath ());
MediaStore. Images. Media. insertImage (getContentResolver (), bitmap ,"","");
}
/**
* Determine whether the SD card is available
*
* @ Return
*/
Private boolean hasSdcard (){
If (Environment. getExternalStorageState (). equals (Environment. MEDIA_MOUNTED )){
Return true;
} Else {
Return false;
}
}
/**
* Remove cache
*
* @ Param cache
*/
Private void removeCache (String cache ){
If (sharePreference. ifHaveShare (cache )){
SharePreference. removeOneCache (cache );
} Else {
Log. e ("this cache", "is not exist .");
}
}
}
ImageTools:
Package com.sctu.edu. test. tools;
Import android. app. Activity;
Import android. graphics. Bitmap;
Import android. graphics. BitmapFactory;
Import android.net. Uri;
Import java. io. ByteArrayInputStream;
Import java. io. ByteArrayOutputStream;
Import java. io. FileNotFoundException;
Import java. io. IOException;
Import java. io. InputStream;
Public class ImageTools {
/**
* Retrieve and compress images using Uris
*
* @ Param uri
* @ Param activity
* @ Return
* @ Throws IOException
*/
Public static Bitmap getBitmapFromUri (Uri uri, Activity activity) throws IOException {
InputStream inputStream = activity. getContentResolver (). openInputStream (uri );
BitmapFactory. Options options = new BitmapFactory. Options ();
Options. inJustDecodeBounds = true;
Options. inDither = true;
Options. inPreferredConfig = Bitmap. Config. ARGB_8888;
BitmapFactory. decodeStream (inputStream, null, options );
InputStream. close ();
Int originalWidth = options. outWidth;
Int originalHeight = options. outHeight;
If (originalWidth =-1 | originalHeight =-1 ){
Return null;
}
Float height = 800f;
Float width = 480f;
Int be = 1; // be = 1 indicates no Scaling
If (originalWidth> originalHeight & originalWidth> width ){
Be = (int) (originalWidth/width );
} Else if (originalWidth <originalHeight & originalHeight> height ){
Be = (int) (originalHeight/height );
}
If (be <= 0 ){
Be = 1;
}
BitmapFactory. Options bitmapOptinos = new BitmapFactory. Options ();
BitmapOptinos. inSampleSize = be;
BitmapOptinos. inDither = true;
BitmapOptinos. inPreferredConfig = Bitmap. Config. ARGB_8888;
InputStream = activity. getContentResolver (). openInputStream (uri );
Bitmap bitmap = BitmapFactory. decodeStream (inputStream, null, bitmapOptinos );
InputStream. close ();
Return compressImage (bitmap );
}
/**
* Quality compression method
*
* @ Param bitmap
* @ Return
*/
Public static Bitmap compressImage (Bitmap bitmap ){
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ();
Bitmap. compress (Bitmap. CompressFormat. JPEG, 100, byteArrayOutputStream );
Int options = 100;
While (byteArrayOutputStream. toByteArray (). length/1024> 100 ){
ByteArrayOutputStream. reset ();
// The first parameter: image format. The second parameter: image quality. The value 100 indicates the highest, the value 0 indicates the worst, and the third parameter indicates the stream that stores the compressed data.
Bitmap. compress (Bitmap. CompressFormat. JPEG, options, byteArrayOutputStream );
Options-= 10;
}
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (byteArrayOutputStream. toByteArray ());
Bitmap bitmapImage = BitmapFactory. decodeStream (byteArrayInputStream, null, null );
Return bitmapImage;
}
}
AndroidMainfest. xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.sctu.edu.test"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature
android:name="android.hardware.camera"
android:required="true"
/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="com.miui.whetstone.permission.ACCESS_PROVIDER"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml:
<? Xml version = "1.0" encoding = "UTF-8"?>
<LinearLayout
Xmlns: android = "http://schemas.android.com/apk/res/android"
Xmlns: tools = "http://schemas.android.com/tools"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent"
Android: background = "# fff"
Android: orientation = "vertical"
Tools: context = "com.sctu.edu. test. MainActivity">
<Button
Android: layout_width = "wrap_content"
Android: layout_height = "wrap_content"
Android: text = "retrieving images from the image library"
Android: id = "@ + id/gallery"
Android: onClick = "gallery"
Android: background = "# ccc"
Android: textSize = "20sp"
Android: padding = "10dp"
Android: layout_marginLeft = "30dp"
Android: layout_marginTop = "40dp"
/>
<Button
Android: layout_width = "wrap_content"
Android: layout_height = "wrap_content"
Android: text = "getting pictures"
Android: id = "@ + id/camera"
Android: onClick = "camera"
Android: background = "# ccc"
Android: textSize = "20sp"
Android: padding = "10dp"
Android: layout_marginLeft = "30dp"
Android: layout_marginTop = "40dp"
/>
<ImageView
Android: layout_width = "300dp"
Android: layout_height = "300dp"
Android: id = "@ + id/imageView"
Android: scaleType = "fitXY"
Android: background = "@ mipmap/ic_launcher"
Android: layout_marginTop = "40dp"
Android: layout_marginLeft = "30dp"
/>
</LinearLayout>
:
Someone may ask how to click a photo on Android6.0 and the photo will crash, because the SDK version I set is higher than 23, and I have not processed the runtime permission yet, maybe I will solve this problem in the next blog. Thank you for browsing. I hope it will help you!