Android Call System Album to Select Photos
- 2021-12-11 08:53:48
- OfStack
Preface
Choosing pictures to upload in photo albums is also a very common function, such as WeChat friends circle and so on. But they are custom selectors, which can select multiple pictures and modify them. Here we talk about the simplest one: call the photo album of the system, select a picture and show it. In addition, some readers also think of the function of choosing pictures by taking pictures with cameras. You can also refer to my other article Android under 1 to take pictures with system cameras
Use steps
Here, I explain how to realize this function through a simple demo. First look at the layout:
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginEnd="52dp"
android:layout_marginRight="52dp"
android:text="choose"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="29dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button"
app:srcCompat="@mipmap/ic_launcher_round" />
It's very simple, that is, one button and one imageView. Then let's think about how to implement this function:
If you open the album first, you must start the album activity implicitly; Then the photo album returns to a path, and we will take this path to show the corresponding photos on the path. The idea is quite simple, let's write about it:
Look at the code first:
private Uri imageUri;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
Button button1 = findViewById(R.id.button2);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Dynamic application authority
if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission
.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}else{
// Execute the method of starting the album
openAlbum();
}
}
});
}
// Get the result of the permission
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 1){
if (grantResults.length>0&&grantResults[0] == PackageManager.PERMISSION_GRANTED) openAlbum();
else Toast.makeText(MainActivity.this," You refused ",Toast.LENGTH_SHORT).show();
}
}
// How to start an album
private void openAlbum(){
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent,2);
}
Here first initialize the control, and then dynamically apply for permissions, because we must read photos to read memory permissions, remember to write permissions in AndroidManifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
After obtaining permission, open album selection. action corresponding to the photo album is android. intent. action. GET_CONTENT, setType ("image/*") This method means to display all the photos and then start the activity. After starting the activity to select the photo, it will return 1 intent to onActivityResult method, so the next main job is to get the return path.
We know that after Android 4.4, we can't directly give the real path of the file to other applications, so the returned uri is encapsulated, so we need to parse and take out the path inside. So here we have to judge the Android version for different logic, first look at the code:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == 2){
// Judge Android version
if (resultCode == RESULT_OK&&data!=null){
if (Build.VERSION.SDK_INT>=19)
handImage(data);
else handImageLow(data);
}
}
}
// Android version is greater than 4.4 The processing method of
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void handImage(Intent data){
String path =null;
Uri uri = data.getData();
// According to different uri Perform different parsing
if (DocumentsContract.isDocumentUri(this,uri)){
String docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())){
String id = docId.split(":")[1];
String selection = MediaStore.Images.Media._ID+"="+id;
path = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
}else if("com.android.providers.downloads.documents".equals(uri.getAuthority())){
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));
path = getImagePath(contentUri,null);
}
}else if ("content".equalsIgnoreCase(uri.getScheme())){
path = getImagePath(uri,null);
}else if ("file".equalsIgnoreCase(uri.getScheme())){
path = uri.getPath();
}
// Show pictures
displayImage(path);
}
// Android is less than 4.4 The processing method of
private void handImageLow(Intent data){
Uri uri = data.getData();
String path = getImagePath(uri,null);
displayImage(path);
}
//content Type of uri Method of getting picture path
private String getImagePath(Uri uri,String selection) {
String path = null;
Cursor cursor = getContentResolver().query(uri,null,selection,null,null);
if (cursor!=null){
if (cursor.moveToFirst()){
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
// Method of showing pictures according to paths
private void displayImage(String imagePath){
if (imagePath != null){
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
imageView.setImageBitmap(bitmap);
}else{
Toast.makeText(this,"fail to set image",Toast.LENGTH_SHORT).show();
}
}
There are many codes above, but don't panic. Let's come one by one, which is not difficult to understand. First of all, we know that different versions have two different ways to display pictures, namely handImage and handImageLow. content type uri gets the real path through getImagePath, and the real path can be displayed through displayImage. So the main job is how to get the real path. Now that the train of thought is clear, let's look at it one by one:
First, look at the next two tool methods: getImagePath and displayImage.
getImagePath learned that the content provider will know that this is to get data through the content provider. An Cursor object is obtained through this uri and selection. What is Cursor? Readers who don't know can check Cursor in this blog Android. The real path is then obtained through the MediaStore. Images. Media. DATA parameter of the Cursor object. displayImage this method receives 1 real path string, obtains Bitmap directly through BitmapFactory. decodeFile this method and then displays it
With the tool approach, our purpose is clear: uri of content type or String of real path.
First of all, the version is lower than 4.4, because the return is the real uri, that is, the one at the beginning of content, so get the real path directly through getImagePath and then show it through displayImage.
The next one may seem a bit of a headache, because you have to parse different types of Uri. Let's look at it one by one:
The first is uri of document type. As for what is document type uri, it is not in depth here, as long as you know that there is this type of uri, how to deal with it. First, we need to get an DocumentId, and then deal with it in two cases:
The first one is in media format, and then we have to take out the second half of the string before we can get the real id. Here, the real id refers to id in the corresponding database table, which is used for selection. MediaStore.Images.Media.EXTERNAL_CONTENT_URI is the content type of this photo, and then put selection in it.
In the second way, uri of content type can be obtained by ContentUris. withAppendedId, which is responsible for connecting id and contentUri into a new Uri. This method is not explained in detail here.
Well, all our questions will be solved by this time.
Summary
After reading it, do you find that the idea is very simple but there are many blind spots in knowledge? That's true. But when we work out all these details, we will learn a lot, which is equivalent to taking points and areas. There are still many things that have not been explained in detail:
ContentUris, BitmapFactory, Cursor, DocumentsContract, etc. Because this is another big piece of content, if you want to talk about it, it will involve a lot of content, so it is easy to deviate from our theme, so just know what it is.
References
[Line 1 Code] Guo Lin
The above is the Android call system photo album selection details, more information about Android call system photo album please pay attention to other related articles on this site!