bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


android_multimedia

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
android_multimedia [2025/12/04 15:07]
enric_mieza_sanchez [Exercicis]
android_multimedia [2025/12/10 20:16] (actual)
enric_mieza_sanchez [Exercicis]
Línia 2: Línia 2:
  
 Per multimèdia s'entenen els diferents mitjans que permeten a la persona humana percebre l'entorn. Els més destacats son la visió i la oïda, però també podrien incloure's el tacte, el gust i l'olfacte. I també la orientació, sabem si estem cap per avall mercès als canals semicirculars de la oïda (no és ni una brúixola ni un GPS però algo és algo). Per multimèdia s'entenen els diferents mitjans que permeten a la persona humana percebre l'entorn. Els més destacats son la visió i la oïda, però també podrien incloure's el tacte, el gust i l'olfacte. I també la orientació, sabem si estem cap per avall mercès als canals semicirculars de la oïda (no és ni una brúixola ni un GPS però algo és algo).
 +
 +{{ android:sunset-camera-musica.png?450 }}
  
 Tot el relacionat amb sensors és susceptible d'entrar en aquesta categoria, però per raons d'extensió ens centrarem en: Tot el relacionat amb sensors és susceptible d'entrar en aquesta categoria, però per raons d'extensió ens centrarem en:
Línia 66: Línia 68:
  
 <WRAP todo> <WRAP todo>
-**Captura de imatge amb la càmera (versió //thubnail//)**+**Captura de imatge en miniatura amb la càmera (versió //thumbnail//)**
  
 El mateix mecanisme que heu emprat per demanar la càrrega d'imatge des de la galeria multimèdia es pot aplicar per a capturar imatges en versió //thumbnail//. El mateix mecanisme que heu emprat per demanar la càrrega d'imatge des de la galeria multimèdia es pot aplicar per a capturar imatges en versió //thumbnail//.
Línia 73: Línia 75:
  
 Afegeix un botó a l'aplicació anterior amb el què capturis el //thumbnail// directament de l'aplicació càmera del sistema operatiu. Afegeix un botó a l'aplicació anterior amb el què capturis el //thumbnail// directament de l'aplicació càmera del sistema operatiu.
 +</WRAP>
 +
 +\\
 +
 +===== Foto full-size i FileProvider : donant accés a l'espai privat =====
 +
 +Demanar una miniatura (//thumbnail//) a una altra ''Activity'' és senzill perquè no son gaires dades que s'han de passar d'una a l'altra a través del ''Intent''. En canvi, demanar que facin una foto d'alta resolució o un vídeo ja és més complicat, ja que el ''Intent'' no permet transferir tanta informació.
 +
 +Un mètode força segur per a fer la foto en alta resolució és obrir els permisos temporalment d'un arxiu privat de l'aplicació que demana la foto perquè l'App Càmera externa la pugui escriure. Això es fa a través del [[https://developer.android.com/reference/androidx/core/content/FileProvider|FileProvider]].
 +
 +{{ android:external-camera-app.png }}
 +
 +Per a realitzar la foto //full-size// i guardar-la a l'espai privat caldrà:
 +  - Afegir un arxiu ''res/xml/file_paths.xml'' on s'indiquen carpetes i arxius compartibles.
 +  - Declarar el ''FileProvider'' al ''AndroidManifest.xml''.
 +  - Al codi de l'''Activity'' transformar el ''File'' estàndard a ''Uri'' (recurs compartible) amb el ''FileProvider''.
 +  - Engegar l'App Camera amb la ''Activity Result API'' (similar al fet fins ara per la galeria i el //thumbnail//).
 +
 +
 +==== Arxius XML ====
 +
 +<code xml res/xml/file_paths.xml>
 +<?xml version="1.0" encoding="utf-8"?>
 +<paths xmlns:android="http://schemas.android.com/apk/res/android">
 +    <files-path name="my_images" path="fotos" />
 +    <!-- si volguessim una carpeta de l'espai compartit seria external-files-path -->
 +</paths>
 +</code>
 +
 +
 +<code xml AndroidManifest.xml>
 +<application ...>
 +
 +    <provider
 +        android:name="androidx.core.content.FileProvider"
 +        android:authorities="${applicationId}.fileprovider"
 +        android:exported="false"
 +        android:grantUriPermissions="true">
 +        <meta-data
 +            android:name="android.support.FILE_PROVIDER_PATHS"
 +            android:resource="@xml/file_paths"></meta-data>
 +    </provider>
 +</application>
 +</code>
 +
 +==== Codi MainActivity.kt ====
 +
 +Preparació del recurs compartit i inici de l'App Camera:
 +
 +<code kotlin MainActivity.kt>
 +val photoButton = findViewById<Button>(R.id.photoButton)
 +photoButton.setOnClickListener {
 +    // Assegurem que existeix la carpeta de fotos (igual que al FileProvider)
 +    val carpeta = File(filesDir.toString(),"fotos")
 +    carpeta.mkdirs()
 +    
 +    // Preparem l'arxiu pq hi pugui escriure l'App Camera
 +    val file = File(filesDir.toString(),"fotos/tmpimage.jpg")
 +    fotoUri = FileProvider.getUriForFile(this,
 +              "com.enric.galleryk2.fileprovider",file)
 +    
 +    // engeguem l'App Camera
 +    takeFullPic.launch(fotoUri)
 +}
 +</code>
 +
 +I la //callback// implementada amb la Results Activity API:
 +
 +<code kotlin MainActivity.kt>
 +val takeFullPic = registerForActivityResult(
 +    ActivityResultContracts.TakePicture()) { success ->
 +    if (success) {
 +        // netejar imatge i pintar nova
 +        imageView.setImageDrawable(null)
 +        imageView.setImageURI(fotoUri)
 +    } else {
 +        // notifiquem error
 +        Toast.makeText(this, "Error al guardar la foto", Toast.LENGTH_SHORT).show()
 +    }
 +}
 +</code>
 +
 +\\
 +
 +===== Àrea privada i àrea compartida =====
 +
 +L'exemple anterior s'ha fet compartint un arxiu a la carpeta "fotos" de l'**espai privat de l'aplicació**, que està a ''/data/data/{AppId}/files''.
 +
 +L'**àrea compartida** d'arxius està a ''/storage/emulated/0'' on trobarem carpetes conegudes com:
 +  * Pictures
 +  * Music
 +  * Movies
 +  * **Android/data/{AppId}** : aquesta és l'**àrea compartida d'aplicació** (Android 10+)
 +
 +On ''{AppId}'' és l'identificador d'aplicació corresponent al //package//, per exemple ''com.ieti.multimedia''
 +
 +Els directoris on s'emmagatzema la info son diferents:
 +
 +^  ^ Funció d'accés ^ Directori ^ XML ^
 +| Arxius privats de l'app    | filesDir | /data/data/{AppId}/files | files-path |
 +| Arxius compartits de l'app | getExternalFilesDir( null ) | /storage/emulated/0/Android/data/{AppId}/files | external-files-path |
 +| Arxius compartits de fotos | Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES ) | /storage/emulated/0/Pictures/ | external-path |
 +
 +
 +\\
 +
 +==== Àrea compartida d'aplicació ====
 +
 +Si volem fer servir l'àrea compartida de l'aplicació, caldrà fer algunes modificacions.
 +
 +Al ''file_paths.xml'' caldrà emprar ''external-files-path'' enlloc de ''files-path'':
 +<code xml file_paths.xml>
 +<external-files-path name="my_images" path="fotos" />
 +</code>
 +
 +A ''MainActivity.kt'' caldrà emprar ''getExternalFilesDir(...)'' enlloc de ''filesDir''. Amb el paràmetre //null// ens escriurà en la carpeta compartida d'aplicacions.
 +<code kotlin MainActivity.kt>
 +val carpeta = File(getExternalFilesDir(null).toString(),"fotos")
 +...
 +val file = File(getExternalFilesDir(null).toString(),"fotos/tmpimage.jpg")
 +</code>
 +
 +Utilitzeu el **Device Explorer** del Android Studio per visualitzar les carpetes i arxius.
 +
 +\\
 +
 +==== Carpetes compartides generals públiques ====
 +
 +Si volem fer servir l'àrea compartida de l'aplicació, caldrà fer algunes modificacions.
 +
 +Al ''file_paths.xml'' caldrà emprar ''external-path'' enlloc de ''files-path'' o ''external-files-path'' que hem emprat anteriorment:
 +<code xml file_paths.xml>
 +<external-path name="my_images" path="Pictures" />
 +</code>
 +
 +A ''MainActivity.kt'' caldrà emprar ''Environment.getExternalStoragePublicDirectory(
 +                Environment.DIRECTORY_PICTURES))'' :
 +<code kotlin MainActivity.kt>
 +val carpeta = File(Environment.getExternalStoragePublicDirectory(
 +    Environment.DIRECTORY_PICTURES).toString(),"fotos")
 +...
 +val file = File(Environment.getExternalStoragePublicDirectory(
 +    Environment.DIRECTORY_PICTURES).toString(),"fotos/tmpimage.jpg")
 +</code>
 +
 +\\
 +
 +===== Exercicis =====
 +
 +<WRAP todo>
 +**Captura de fotos //full-size//**
 +
 +Implementa la captura de fotos //full-size// en l'app de la galeria i el thumb, afegint un nou botó per la captura actual.
 +</WRAP>
 +
 +<WRAP todo>
 +**Exercici MyGallery**
 +
 +Implementa una app de captura de fotos i conserva tots els arxius amb un nom que eviti col·lisions, com afegir un //timestamp//.
 +
 +Visualització les fotos que anem prenent en l'àrea compartida de l'aplicació i visualitza-les en una nova ''Activity''. Segueix les instruccions a l'article [[Android RecyclerView]] per visualitzar les fotos amb una //preview// en format //grid//.
 +
 </WRAP> </WRAP>
  
android_multimedia.1764860863.txt.gz · Darrera modificació: 2025/12/04 15:07 per enric_mieza_sanchez