<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Bloque 4 on Documentación</title>
    <link>https://documentation.javiercarrasco.es/pmdm/B4/</link>
    <description>Recent content in Bloque 4 on Documentación</description>
    <generator>Hugo</generator>
    <language>es-es</language>
    <atom:link href="https://documentation.javiercarrasco.es/pmdm/B4/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Tema 7. Multimedia: Cámara, Galería, Audio y Vídeo</title>
      <link>https://documentation.javiercarrasco.es/pmdm/B4/B4-T7_Multimedia/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://documentation.javiercarrasco.es/pmdm/B4/B4-T7_Multimedia/</guid>
      <description>&lt;h1 id=&#34;tema-7-multimedia-cámara-galería-audio-y-vídeo&#34;&gt;Tema 7. Multimedia: Cámara, Galería, Audio y Vídeo&lt;a class=&#34;anchor&#34; href=&#34;#tema-7-multimedia-c%c3%a1mara-galer%c3%ada-audio-y-v%c3%addeo&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;div class=&#34;book-tabs&#34;&gt;&#xA;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-0&#34; checked=&#34;checked&#34; /&gt;&lt;label for=&#34;tabs-0-0&#34;&gt;Información del tema&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Bloque:&lt;/strong&gt; B4 — Multimedia en Android&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Duración aproximada:&lt;/strong&gt; 9 horas&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-1&#34;  /&gt;&lt;label for=&#34;tabs-0-1&#34;&gt;Resultados de Aprendizaje&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;RA3 — Desarrolla programas que integran contenidos multimedia analizando y empleando las tecnologías y librerías específicas.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-2&#34;  /&gt;&lt;label for=&#34;tabs-0-2&#34;&gt;Criterios de Evaluación&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;Código&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;Criterio&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-a&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han utilizado las herramientas y entornos de desarrollo para aplicaciones multimedia.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-b&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han analizado las herramientas disponibles para el tratamiento de imágenes y vídeo.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-c&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han incorporado procedimientos para la captura de imágenes y grabación de vídeo.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-d&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han utilizado clases para la reproducción de audio y vídeo.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-e&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han gestionado los permisos de acceso al hardware multimedia del dispositivo.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;dependencias-necesarias&#34;&gt;Dependencias necesarias&lt;a class=&#34;anchor&#34; href=&#34;#dependencias-necesarias&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34; title=&#34;Gradle&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-gradle&#34; data-lang=&#34;gradle&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// build.gradle.kts (módulo app)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&lt;/span&gt;&lt;span&gt;dependencies &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// ── CameraX ───────────────────────────────────────────────────────────────&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&lt;/span&gt;&lt;span&gt;    val cameraxVersion &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;1.4.2&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.camera:camera-core:$cameraxVersion&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.camera:camera-camera2:$cameraxVersion&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// backend Camera2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.camera:camera-lifecycle:$cameraxVersion&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;  &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// integración con Lifecycle&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.camera:camera-view:$cameraxVersion&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;       &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// PreviewView&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.camera:camera-extensions:$cameraxVersion&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// HDR, Bokeh, etc. (opcional)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&lt;/span&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// ── Media3 / ExoPlayer (reproducción de audio y vídeo) ───────────────────&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&lt;/span&gt;&lt;span&gt;    val media3Version &lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;1.5.1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.media3:media3-exoplayer:$media3Version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.media3:media3-ui:$media3Version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;          &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// PlayerView&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&lt;/span&gt;&lt;span&gt;    implementation&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.media3:media3-common:$media3Version&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&lt;/span&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// ── Coil (ya incluido en B3, necesario para mostrar imágenes de la galería) ──&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// io.coil-kt.coil3:coil-compose:3.2.0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#04a5e5;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Permisos en &lt;code&gt;AndroidManifest.xml&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tema 8. Sensores, GPS y Notificaciones</title>
      <link>https://documentation.javiercarrasco.es/pmdm/B4/B4-T8_Sensores_Notificaciones/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://documentation.javiercarrasco.es/pmdm/B4/B4-T8_Sensores_Notificaciones/</guid>
      <description>&lt;h1 id=&#34;tema-8-sensores-gps-y-notificaciones&#34;&gt;Tema 8. Sensores, GPS y Notificaciones&lt;a class=&#34;anchor&#34; href=&#34;#tema-8-sensores-gps-y-notificaciones&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;div class=&#34;book-tabs&#34;&gt;&#xA;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-0&#34; checked=&#34;checked&#34; /&gt;&lt;label for=&#34;tabs-0-0&#34;&gt;Información del tema&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Bloque:&lt;/strong&gt; B4 — Multimedia en Android&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Duración aproximada:&lt;/strong&gt; 6 horas&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-1&#34;  /&gt;&lt;label for=&#34;tabs-0-1&#34;&gt;Resultados de Aprendizaje&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;RA3 — Desarrolla programas que integran contenidos multimedia analizando y empleando las tecnologías y librerías específicas.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-2&#34;  /&gt;&lt;label for=&#34;tabs-0-2&#34;&gt;Criterios de Evaluación&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;Código&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;Criterio&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-a&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han utilizado las herramientas y entornos de desarrollo para aplicaciones multimedia.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-e&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han gestionado los permisos de acceso al hardware multimedia del dispositivo.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-f&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han utilizado los servicios de localización del dispositivo.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;RA3-g&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Se han incorporado mecanismos de notificación y comunicación con el usuario.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;dependencias-necesarias&#34;&gt;Dependencias necesarias&lt;a class=&#34;anchor&#34; href=&#34;#dependencias-necesarias&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34; title=&#34;Kotlin&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-kotlin&#34; data-lang=&#34;kotlin&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// build.gradle.kts (módulo app)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&lt;/span&gt;&lt;span&gt;dependencies {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// Localización con FusedLocationProviderClient&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// (Requiere Google Play Services — presente en la mayoría de dispositivos Android)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&lt;/span&gt;&lt;span&gt;    implementation(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;com.google.android.gms:play-services-location:21.3.0&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&lt;/span&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// WorkManager — tareas en segundo plano y notificaciones programadas&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&lt;/span&gt;&lt;span&gt;    implementation(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.work:work-runtime-ktx:2.10.1&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&lt;/span&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// Core KTX — NotificationCompat y utilidades de compatibilidad&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// (Ya incluido transitivamente, pero conviene declararlo explícitamente)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&lt;/span&gt;&lt;span&gt;    implementation(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;androidx.core:core-ktx:1.16.0&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Permisos en &lt;code&gt;AndroidManifest.xml&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Anexo 5. Referencia: Permisos en Android moderno, FileProvider y WorkManager avanzado</title>
      <link>https://documentation.javiercarrasco.es/pmdm/B4/B4-A5_Referencia_Permisos_FileProvider/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://documentation.javiercarrasco.es/pmdm/B4/B4-A5_Referencia_Permisos_FileProvider/</guid>
      <description>&lt;h1 id=&#34;anexo-5-referencia-permisos-en-android-moderno-fileprovider-y-workmanager-avanzado&#34;&gt;Anexo 5. Referencia: Permisos en Android moderno, FileProvider y WorkManager avanzado&lt;a class=&#34;anchor&#34; href=&#34;#anexo-5-referencia-permisos-en-android-moderno-fileprovider-y-workmanager-avanzado&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;div class=&#34;book-tabs&#34;&gt;&#xA;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-0&#34; checked=&#34;checked&#34; /&gt;&lt;label for=&#34;tabs-0-0&#34;&gt;Información del anexo&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Tipo:&lt;/strong&gt; Anexo de apoyo — material de consulta y profundización&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Bloque:&lt;/strong&gt; B4 — Multimedia en Android&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;input type=&#34;radio&#34; class=&#34;toggle&#34; name=&#34;tabs-0&#34; id=&#34;tabs-0-1&#34;  /&gt;&lt;label for=&#34;tabs-0-1&#34;&gt;Resultados de Aprendizaje&lt;/label&gt;&lt;div class=&#34;book-tabs-content markdown-inner&#34;&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;RA3 — Desarrolla programas que integran contenidos multimedia analizando y empleando las tecnologías y librerías específicas.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;1-mapa-completo-de-permisos-en-android&#34;&gt;1. Mapa completo de permisos en Android&lt;a class=&#34;anchor&#34; href=&#34;#1-mapa-completo-de-permisos-en-android&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;permisos-peligrosos-más-habituales-solicitar-en-tiempo-de-ejecución&#34;&gt;Permisos peligrosos más habituales (solicitar en tiempo de ejecución)&lt;a class=&#34;anchor&#34; href=&#34;#permisos-peligrosos-m%c3%a1s-habituales-solicitar-en-tiempo-de-ejecuci%c3%b3n&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;Grupo&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;Permiso&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;API&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;Cuándo es necesario&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Cámara&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;CAMERA&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Todos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Usar CameraX / Camera2&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Almacenamiento&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;READ_MEDIA_IMAGES&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;33+&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Leer imágenes sin Photo Picker&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Almacenamiento&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;READ_MEDIA_VIDEO&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;33+&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Leer vídeos sin Photo Picker&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Almacenamiento&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;READ_EXTERNAL_STORAGE&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;≤32&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Leer medios en API ≤ 32&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Almacenamiento&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;WRITE_EXTERNAL_STORAGE&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;≤28&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Escribir fuera de MediaStore&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Micrófono&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;RECORD_AUDIO&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Todos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Grabar audio / vídeo con sonido&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Localización&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;ACCESS_COARSE_LOCATION&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Todos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Red (~300m)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Localización&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;ACCESS_FINE_LOCATION&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Todos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;GPS (~10m)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Localización&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;ACCESS_BACKGROUND_LOCATION&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;29+&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;GPS con app en segundo plano&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Notificaciones&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;POST_NOTIFICATIONS&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;33+&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Publicar cualquier notificación&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Actividad física&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;ACTIVITY_RECOGNITION&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;29+&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Contador de pasos (&lt;code&gt;TYPE_STEP_COUNTER&lt;/code&gt;)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Sensores corporales&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;BODY_SENSORS&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Todos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Frecuencia cardíaca&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Teléfono&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;READ_PHONE_STATE&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Todos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Estado de la llamada&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Contactos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;READ_CONTACTS&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Todos&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;Leer la agenda&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;permisos-normales-solo-declarar-en-manifest-no-solicitar-en-runtime&#34;&gt;Permisos normales (solo declarar en Manifest, no solicitar en runtime)&lt;a class=&#34;anchor&#34; href=&#34;#permisos-normales-solo-declarar-en-manifest-no-solicitar-en-runtime&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34; title=&#34;XML&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;android:name=&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;android.permission.INTERNET&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;2&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;android:name=&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;android.permission.ACCESS_NETWORK_STATE&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;3&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;android:name=&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;android.permission.VIBRATE&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;4&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;android:name=&lt;/span&gt;&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;android.permission.RECEIVE_BOOT_COMPLETED&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#8839ef&#34;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;flujo-correcto-para-solicitar-un-permiso-peligroso&#34;&gt;Flujo correcto para solicitar un permiso peligroso&lt;a class=&#34;anchor&#34; href=&#34;#flujo-correcto-para-solicitar-un-permiso-peligroso&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1. Comprobar si ya está concedido (ContextCompat.checkSelfPermission)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       │&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       ├── GRANTED → Ejecutar la función directamente&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       │&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       └── DENIED&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             │&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             ├── shouldShowRequestPermissionRationale() == true&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             │    → Mostrar explicación al usuario ANTES del diálogo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             │&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             └── Lanzar launcher.launch(permiso)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       │&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       ├── Usuario acepta → GRANTED → ejecutar función&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       │&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       └── Usuario deniega&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             │&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             ├── Primera denegación → puede volver a solicitar&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                             └── &amp;#34;No volver a preguntar&amp;#34; → redirigir a Ajustes del sistema&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;redirigir-al-usuario-a-los-ajustes-si-deniega-permanentemente&#34;&gt;Redirigir al usuario a los Ajustes si deniega permanentemente&lt;a class=&#34;anchor&#34; href=&#34;#redirigir-al-usuario-a-los-ajustes-si-deniega-permanentemente&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34; title=&#34;Kotlin&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#4c4f69;background-color:#eff1f5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-kotlin&#34; data-lang=&#34;kotlin&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#1e66f5;font-weight:bold&#34;&gt;@Composable&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style=&#34;color:#8839ef&#34;&gt;fun&lt;/span&gt; &lt;span style=&#34;color:#1e66f5&#34;&gt;MensajePermisoDenegadoPermanentemente&lt;/span&gt;(permiso: String) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 3&lt;/span&gt;&lt;span&gt;    &lt;span style=&#34;color:#8839ef&#34;&gt;val&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;context&lt;/span&gt; = &lt;span style=&#34;color:#df8e1d&#34;&gt;LocalContext&lt;/span&gt;.current&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 4&lt;/span&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 5&lt;/span&gt;&lt;span&gt;    Column(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 6&lt;/span&gt;&lt;span&gt;        horizontalAlignment = &lt;span style=&#34;color:#df8e1d&#34;&gt;Alignment&lt;/span&gt;.CenterHorizontally,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 7&lt;/span&gt;&lt;span&gt;        modifier = &lt;span style=&#34;color:#df8e1d&#34;&gt;Modifier&lt;/span&gt;.padding(&lt;span style=&#34;color:#fe640b&#34;&gt;24&lt;/span&gt;.dp)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 8&lt;/span&gt;&lt;span&gt;    ) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt; 9&lt;/span&gt;&lt;span&gt;        Icon(&lt;span style=&#34;color:#df8e1d&#34;&gt;Icons&lt;/span&gt;.&lt;span style=&#34;color:#df8e1d&#34;&gt;Default&lt;/span&gt;.Block, contentDescription = &lt;span style=&#34;color:#8839ef&#34;&gt;null&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;10&lt;/span&gt;&lt;span&gt;            modifier = &lt;span style=&#34;color:#df8e1d&#34;&gt;Modifier&lt;/span&gt;.size(&lt;span style=&#34;color:#fe640b&#34;&gt;64&lt;/span&gt;.dp),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;11&lt;/span&gt;&lt;span&gt;            tint = &lt;span style=&#34;color:#df8e1d&#34;&gt;MaterialTheme&lt;/span&gt;.colorScheme.error)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;12&lt;/span&gt;&lt;span&gt;        Spacer(&lt;span style=&#34;color:#df8e1d&#34;&gt;Modifier&lt;/span&gt;.height(&lt;span style=&#34;color:#fe640b&#34;&gt;16&lt;/span&gt;.dp))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;13&lt;/span&gt;&lt;span&gt;        Text(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;14&lt;/span&gt;&lt;span&gt;            &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;El permiso ha sido denegado permanentemente. &amp;#34;&lt;/span&gt; +&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;15&lt;/span&gt;&lt;span&gt;            &lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;Ve a Ajustes → Aplicaciones → AppFlix → Permisos para activarlo.&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;16&lt;/span&gt;&lt;span&gt;            textAlign = &lt;span style=&#34;color:#df8e1d&#34;&gt;TextAlign&lt;/span&gt;.Center&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;17&lt;/span&gt;&lt;span&gt;        )&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;18&lt;/span&gt;&lt;span&gt;        Spacer(&lt;span style=&#34;color:#df8e1d&#34;&gt;Modifier&lt;/span&gt;.height(&lt;span style=&#34;color:#fe640b&#34;&gt;24&lt;/span&gt;.dp))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;19&lt;/span&gt;&lt;span&gt;        Button(onClick = {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;20&lt;/span&gt;&lt;span&gt;            &lt;span style=&#34;color:#9ca0b0;font-style:italic&#34;&gt;// Abrir la pantalla de permisos de la app en los ajustes del sistema&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;21&lt;/span&gt;&lt;span&gt;            &lt;span style=&#34;color:#8839ef&#34;&gt;val&lt;/span&gt; &lt;span style=&#34;color:#fe640b&#34;&gt;intent&lt;/span&gt; = Intent(&lt;span style=&#34;color:#df8e1d&#34;&gt;Settings&lt;/span&gt;.ACTION_APPLICATION_DETAILS_SETTINGS).apply {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;22&lt;/span&gt;&lt;span&gt;                &lt;span style=&#34;color:#8839ef&#34;&gt;data&lt;/span&gt; = &lt;span style=&#34;color:#df8e1d&#34;&gt;Uri&lt;/span&gt;.fromParts(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;package&amp;#34;&lt;/span&gt;, context.packageName, &lt;span style=&#34;color:#8839ef&#34;&gt;null&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;23&lt;/span&gt;&lt;span&gt;            }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;24&lt;/span&gt;&lt;span&gt;            context.startActivity(intent)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;25&lt;/span&gt;&lt;span&gt;        }) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;26&lt;/span&gt;&lt;span&gt;            Text(&lt;span style=&#34;color:#40a02b&#34;&gt;&amp;#34;Ir a Ajustes&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;27&lt;/span&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;28&lt;/span&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1&#34;&gt;29&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;&#xA;&lt;h2 id=&#34;2-fileprovider-compartir-archivos-entre-apps&#34;&gt;2. FileProvider: compartir archivos entre apps&lt;a class=&#34;anchor&#34; href=&#34;#2-fileprovider-compartir-archivos-entre-apps&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Cuando una app necesita compartir un archivo (foto tomada con CameraX, documento generado) con otra app (WhatsApp, email, Google Drive), &lt;strong&gt;no puede pasar una ruta de archivo directa&lt;/strong&gt; (&lt;code&gt;file:///&lt;/code&gt;) desde Android 7.0 (API 24). En su lugar, debe usar un &lt;code&gt;FileProvider&lt;/code&gt; que genera una URI de contenido segura (&lt;code&gt;content://&lt;/code&gt;).&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
