1515 */
1616package com.samples.storage.mediastore
1717
18+ import android.Manifest.permission.READ_EXTERNAL_STORAGE
19+ import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
1820import android.os.Bundle
1921import android.util.Log
2022import android.view.LayoutInflater
2123import android.view.View
2224import android.view.ViewGroup
25+ import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
2326import androidx.activity.result.contract.ActivityResultContracts.TakePicture
2427import androidx.fragment.app.Fragment
2528import androidx.fragment.app.viewModels
26- import coil.load
29+ import androidx.lifecycle.lifecycleScope
30+ import com.bumptech.glide.Glide
2731import com.samples.storage.databinding.FragmentAddMediaBinding
32+ import kotlinx.coroutines.launch
2833
29- // TODO(yrezgui): Add media from camera (video), from internet and generated one
3034class AddMediaFragment : Fragment () {
3135 private var _binding : FragmentAddMediaBinding ? = null
3236 private val binding get() = _binding !!
3337 private val viewModel: AddMediaViewModel by viewModels()
3438
35- private val actionTakePicture = registerForActivityResult(TakePicture ()) { success ->
36- if (! success) {
37- Log .d(tag, " Image taken FAIL: ${viewModel.temporaryMediaUri} " )
38- return @registerForActivityResult
39- }
40-
41- Log .d(tag, " Image taken SUCCESS: ${viewModel.temporaryMediaUri} " )
42- viewModel.loadMedia()
43- }
44-
4539 override fun onCreateView (inflater : LayoutInflater , container : ViewGroup ? , savedInstanceState : Bundle ? ): View {
4640 _binding = FragmentAddMediaBinding .inflate(inflater, container, false )
4741
48- // Once we've added a media, we set its URI to the currentMediaUri property.
49- // Every time
42+ // Every time currentMediaUri is changed, we update the ImageView
5043 viewModel.currentMediaUri.observe(viewLifecycleOwner) { uri ->
51- binding.mediaThumbnail.load(uri) {
52- crossfade(true )
53- }
44+ Glide .with (this ).load(uri).into(binding.mediaThumbnail)
45+ }
46+
47+ binding.requestPermissionButton.setOnClickListener {
48+ actionRequestPermission.launch(arrayOf(READ_EXTERNAL_STORAGE , WRITE_EXTERNAL_STORAGE ))
5449 }
5550
5651 binding.takePictureButton.setOnClickListener {
57- viewModel.createPhotoUri(Source .CAMERA )?.let { uri ->
58- actionTakePicture.launch(uri)
52+ viewLifecycleOwner.lifecycleScope.launch {
53+
54+ if (viewModel.canWriteInMediaStore) {
55+ viewModel.createPhotoUri(Source .CAMERA )?.let { uri ->
56+ viewModel.saveTemporarilyPhotoUri(uri)
57+ actionTakePicture.launch(uri)
58+ }
59+ } else {
60+ showPermissionSection()
61+ }
62+ }
63+ }
64+
65+ binding.takeVideoButton.setOnClickListener {
66+ viewLifecycleOwner.lifecycleScope.launch {
67+
68+
69+ if (viewModel.canWriteInMediaStore) {
70+ viewModel.createVideoUri(Source .CAMERA )?.let { uri ->
71+ actionTakeVideo.launch(uri)
72+ }
73+ } else {
74+ showPermissionSection()
75+ }
76+ }
77+ }
78+
79+ binding.downloadImageFromInternetButton.setOnClickListener {
80+
81+ if (viewModel.canWriteInMediaStore) {
82+ binding.downloadImageFromInternetButton.isEnabled = false
83+ viewModel.saveRandomImageFromInternet {
84+ // We re-enable the button once the download is done
85+ // Keep in mind the logic is basic as it doesn't handle errors
86+ binding.downloadImageFromInternetButton.isEnabled = true
87+ }
88+ } else {
89+ showPermissionSection()
5990 }
6091 }
6192
@@ -66,4 +97,56 @@ class AddMediaFragment : Fragment() {
6697 super .onDestroyView()
6798 _binding = null
6899 }
100+
101+ override fun onResume () {
102+ super .onResume()
103+
104+ handlePermissionSectionVisibility()
105+ }
106+
107+ private fun handlePermissionSectionVisibility () {
108+ if (viewModel.canWriteInMediaStore) {
109+ hidePermissionSection()
110+ } else {
111+ showPermissionSection()
112+ }
113+ }
114+
115+ private fun hidePermissionSection () {
116+ binding.permissionSection.visibility = View .GONE
117+ binding.actions.visibility = View .VISIBLE
118+ }
119+
120+ private fun showPermissionSection () {
121+ binding.permissionSection.visibility = View .VISIBLE
122+ binding.actions.visibility = View .GONE
123+ }
124+
125+ private val actionRequestPermission = registerForActivityResult(RequestMultiplePermissions ()) {
126+ handlePermissionSectionVisibility()
127+ }
128+
129+ private val actionTakePicture = registerForActivityResult(TakePicture ()) { success ->
130+ if (! success) {
131+ Log .d(tag, " Image taken FAIL" )
132+ return @registerForActivityResult
133+ }
134+
135+ Log .d(tag, " Image taken SUCCESS" )
136+
137+ viewModel.temporaryPhotoUri?.let {
138+ viewModel.loadCameraMedia(it)
139+ viewModel.saveTemporarilyPhotoUri(null )
140+ }
141+ }
142+
143+ private val actionTakeVideo = registerForActivityResult(CustomTakeVideo ()) { uri ->
144+ if (uri == null ) {
145+ Log .d(tag, " Video taken FAIL" )
146+ return @registerForActivityResult
147+ }
148+
149+ Log .d(tag, " Video taken SUCCESS" )
150+ viewModel.loadCameraMedia(uri)
151+ }
69152}
0 commit comments