This example shows how can user go to phones gallery, select a image and after that display it on screen. This example can be used in variety of scenarios, from setting profile pictures to setting backgrounds. This example is very similar to Take picture with camera and make a preview with the difference of handling the returned data as image.
ButterKnife library
First we add our favorite ButterKnife library in our build.gradle app file and sync the project:
1 2 3 4 |
dependencies { implementation 'com.jakewharton:butterknife:10.1.0' annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0' } |
AndroidManifest XML:
We must add write permissions to our AndroidManifest in order to call the gallery in our app:
1 |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
The Main Activity XML:
In this Activity, there is nothing more than to show the selected image on screen. Because of that we use only one defined ImageView, one descriptive TextView and one Button for calling the gallery:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:id="@+id/image" android:layout_width="0dip" android:layout_height="250dp" android:background="@color/colorPrimaryLight" android:contentDescription="@string/image_view_content_description" android:elevation="5dp" android:paddingTop="10dp" android:paddingBottom="10dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/overlayText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:elevation="7.1dp" android:text="@string/your_image" android:textAllCaps="true" android:textColor="@color/white" android:textSize="22sp" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="@id/image" app:layout_constraintEnd_toEndOf="@id/image" app:layout_constraintStart_toStartOf="@id/image" app:layout_constraintTop_toTopOf="@id/image" /> <TextView android:id="@+id/text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="25dp" android:layout_marginEnd="16dp" android:text="@string/click_to_select_image" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/image" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="100dp" android:paddingStart="15dp" android:paddingEnd="15dp" android:text="@string/go_to_gallery" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <TextView android:id="@+id/info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:elevation="7dp" android:text="@string/by_viktor" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> |
The Main Activity Java:
Also in the Main Activity we call the gallery on button click by starting an activity by intent for result. The app is starting the gallery and receive the selected image as a result. Whit this kind of intent you can choose from where ever you like in your device.
1 2 3 4 5 6 7 8 9 |
// Create random int number for identifying the result request by calling the camera private static final int GET_PICTURE = 1111; private void startGalleryIntent() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), GET_PICTURE); } |
In on activity result we compare if our request code (TAKE_PICTURE) is used, and by that we get the data as result for taking the photo with our camera:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == GET_PICTURE && resultCode == Activity.RESULT_OK) { Uri imageUri = Objects.requireNonNull(data).getData(); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri); } catch (IOException e) { e.printStackTrace(); } if (bitmap != null) { image.setImageBitmap(bitmap); } overlayTest.setVisibility(View.INVISIBLE); } } |
Of course here we have some run-time permissions for the choosing image (used from Android API 23) and that will be covered in later examples. In other code there is still same as Take picture with camera and make a preview example.
Here is the whole MainActivity:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
public class MainActivity extends AppCompatActivity { @BindView(R.id.image) ImageView image; @BindView(R.id.overlayText) TextView overlayTest; private static final int GET_PICTURE = 1111; private static final int GALLERY_REQUEST_PERMISSION_CODE = 1112; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); } @OnClick(R.id.button) public void onGoToCameraClick() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestWriteExternalStoragePermission(); } else { startGalleryIntent(); } } private void startGalleryIntent() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), GET_PICTURE); } @TargetApi(Build.VERSION_CODES.M) private void requestWriteExternalStoragePermission() { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, GALLERY_REQUEST_PERMISSION_CODE); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == GALLERY_REQUEST_PERMISSION_CODE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { startGalleryIntent(); } } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == GET_PICTURE && resultCode == Activity.RESULT_OK) { Uri imageUri = Objects.requireNonNull(data).getData(); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri); } catch (IOException e) { e.printStackTrace(); } if (bitmap != null) { image.setImageBitmap(bitmap); } overlayTest.setVisibility(View.INVISIBLE); } } } |
NOTE: This project is done using AndroidX
You can get the whole project on GitHub /SelectFromGallery