1 /*
<lambda>null2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.activity.integration.testapp
18 
19 import android.Manifest.permission.ACCESS_FINE_LOCATION
20 import android.app.Activity
21 import android.app.PendingIntent
22 import android.content.Context
23 import android.content.Intent
24 import android.net.Uri
25 import android.os.Build
26 import android.os.Bundle
27 import android.provider.MediaStore
28 import android.view.View
29 import android.view.ViewGroup
30 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
31 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
32 import android.view.ViewManager
33 import android.widget.Button
34 import android.widget.LinearLayout
35 import android.widget.LinearLayout.VERTICAL
36 import android.widget.Toast
37 import androidx.activity.ComponentActivity
38 import androidx.activity.result.ActivityResultLauncher
39 import androidx.activity.result.IntentSenderRequest
40 import androidx.activity.result.PickVisualMediaRequest
41 import androidx.activity.result.contract.ActivityResultContracts
42 import androidx.activity.result.contract.ActivityResultContracts.CaptureVideo
43 import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
44 import androidx.activity.result.contract.ActivityResultContracts.GetContent
45 import androidx.activity.result.contract.ActivityResultContracts.OpenMultipleDocuments
46 import androidx.activity.result.contract.ActivityResultContracts.PickMultipleVisualMedia
47 import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
48 import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.MediaCapabilities
49 import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
50 import androidx.activity.result.contract.ActivityResultContracts.TakePicture
51 import androidx.activity.result.contract.ActivityResultContracts.TakePicturePreview
52 import androidx.activity.result.launch
53 import androidx.activity.result.registerForActivityResult
54 import androidx.core.content.FileProvider
55 import java.io.File
56 
57 class MainActivity : ComponentActivity() {
58 
59     val requestLocation =
60         registerForActivityResult(RequestPermission(), ACCESS_FINE_LOCATION) { isGranted ->
61             toast("Location granted: $isGranted")
62         }
63 
64     val takePicturePreview =
65         registerForActivityResult(TakePicturePreview()) { bitmap -> toast("Got picture: $bitmap") }
66 
67     val takePicture =
68         registerForActivityResult(TakePicture()) { success -> toast("Got picture: $success") }
69 
70     val captureVideo: ActivityResultLauncher<Uri> =
71         registerForActivityResult(CaptureVideo()) { success -> toast("Got video: $success") }
72 
73     val getContent: ActivityResultLauncher<String> =
74         registerForActivityResult(GetContent()) { uri -> toast("Got image: $uri") }
75 
76     lateinit var pickVisualMedia: ActivityResultLauncher<PickVisualMediaRequest>
77 
78     lateinit var pickMultipleVisualMedia: ActivityResultLauncher<PickVisualMediaRequest>
79 
80     lateinit var createDocument: ActivityResultLauncher<String>
81 
82     lateinit var openDocuments: ActivityResultLauncher<Array<String>>
83 
84     private val intentSender =
85         registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
86             toast("Received intent sender callback")
87         }
88 
89     override fun onCreate(savedInstanceState: Bundle?) {
90         super.onCreate(savedInstanceState)
91 
92         pickVisualMedia =
93             registerForActivityResult(PickVisualMedia()) { uri -> toast("Got image: $uri") }
94         pickMultipleVisualMedia =
95             registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
96                 var media = ""
97                 uris.forEach { media += "uri: $it \n" }
98                 toast("Got media files: $media")
99             }
100         createDocument =
101             registerForActivityResult(CreateDocument("image/png")) { uri ->
102                 toast("Created document: $uri")
103             }
104         openDocuments =
105             registerForActivityResult(OpenMultipleDocuments()) { uris ->
106                 var docs = ""
107                 uris.forEach { docs += "uri: $it \n" }
108                 toast("Got documents: $docs")
109             }
110 
111         setContentView {
112             add(::LinearLayout) {
113                 orientation = VERTICAL
114 
115                 button("Request location permission") { requestLocation.launch() }
116                 button("Get picture thumbnail") { takePicturePreview.launch() }
117                 button("Take pic") {
118                     val file = File(filesDir, "image")
119                     val uri = FileProvider.getUriForFile(this@MainActivity, packageName, file)
120                     takePicture.launch(uri)
121                 }
122                 button("Capture video") {
123                     val file = File(filesDir, "video")
124                     val uri = FileProvider.getUriForFile(this@MainActivity, packageName, file)
125                     captureVideo.launch(uri)
126                 }
127                 button("Pick an image (w/ GET_CONTENT)") { getContent.launch("image/*") }
128                 button("Pick an image (w/ photo picker)") {
129                     pickVisualMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))
130                 }
131                 button("Pick a GIF (w/ photo picker)") {
132                     pickVisualMedia.launch(
133                         PickVisualMediaRequest(PickVisualMedia.SingleMimeType("image/gif"))
134                     )
135                 }
136                 button("Pick an image & show albums tab (w/ photo picker)") {
137                     pickVisualMedia.launch(
138                         PickVisualMediaRequest(
139                             mediaType = PickVisualMedia.ImageOnly,
140                             defaultTab = PickVisualMedia.DefaultTab.AlbumsTab
141                         )
142                     )
143                 }
144                 button("Pick an image & green accent color (w/ photo picker)") {
145                     pickVisualMedia.launch(
146                         PickVisualMediaRequest(
147                             mediaType = PickVisualMedia.ImageOnly,
148                             accentColor = 0xFF123456
149                         )
150                     )
151                 }
152                 button("Pick 5 visual media max (w/ photo picker)") {
153                     pickMultipleVisualMedia.launch(
154                         PickVisualMediaRequest(PickVisualMedia.ImageAndVideo)
155                     )
156                 }
157                 button("Pick 3 visual media max (w/ photo picker)") {
158                     pickMultipleVisualMedia.launch(
159                         PickVisualMediaRequest(
160                             mediaType = PickVisualMedia.ImageAndVideo,
161                             maxItems = 3
162                         )
163                     )
164                 }
165                 button("Pick 5 visual media max (w/ photo picker) & selection order") {
166                     pickMultipleVisualMedia.launch(
167                         PickVisualMediaRequest(isOrderedSelection = true)
168                     )
169                 }
170                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
171                     button("Pick 5 videos max (w/ photo picker) & transcoding HDR to SDR") {
172                         pickMultipleVisualMedia.launch(
173                             PickVisualMediaRequest(
174                                 mediaType = PickVisualMedia.VideoOnly,
175                                 mediaCapabilitiesForTranscoding =
176                                     MediaCapabilities.Builder().build()
177                             )
178                         )
179                     }
180                 }
181                 button("Create document") { createDocument.launch("Temp") }
182                 button("Open documents") { openDocuments.launch(arrayOf("*/*")) }
183                 button("Start IntentSender") {
184                     val request =
185                         IntentSenderRequest.Builder(
186                                 PendingIntent.getActivity(
187                                     context,
188                                     0,
189                                     Intent(MediaStore.ACTION_IMAGE_CAPTURE),
190                                     PendingIntent.FLAG_IMMUTABLE
191                                 )
192                             )
193                             .setFlags(
194                                 Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP,
195                                 1
196                             )
197                             .build()
198                     intentSender.launch(request)
199                 }
200             }
201         }
202     }
203 }
204 
Contextnull205 fun Context.toast(msg: String) {
206     Toast.makeText(this, msg, Toast.LENGTH_LONG).show()
207 }
208 
setContentViewnull209 inline fun Activity.setContentView(ui: ViewManager.() -> Unit) = ActivityViewManager(this).apply(ui)
210 
211 class ActivityViewManager(val activity: Activity) : ViewManager {
212     override fun addView(p0: View?, p1: ViewGroup.LayoutParams?) {
213         activity.setContentView(p0)
214     }
215 
216     override fun updateViewLayout(p0: View?, p1: ViewGroup.LayoutParams?) {
217         TODO("not implemented")
218     }
219 
220     override fun removeView(p0: View?) {
221         TODO("not implemented")
222     }
223 }
224 
225 val ViewManager.context
226     get() =
227         when (this) {
228             is View -> context
229             is ActivityViewManager -> activity
230             else -> TODO()
231         }
232 
addnull233 fun <VM : ViewManager, V : View> VM.add(construct: (Context) -> V, init: V.() -> Unit) {
234     construct(context).apply(init).also {
235         addView(it, ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
236     }
237 }
238 
buttonnull239 fun ViewManager.button(txt: String, listener: (View) -> Unit) {
240     add(::Button) {
241         text = txt
242         setOnClickListener(listener)
243     }
244 }
245