Archivo

Archivo para la categoría ‘Android’

Temas AOD en Miui

martes, 6 de diciembre de 2022 2 comentarios

En MIUI se puede escoger un tema en concreto para la función AOD de algunos terminales con animaciones e información. Si quieres fabricar el tuyo propio la documentación oficial es francamente escasa y la mayor parte en chino. Pero una vez consigues un ejemplo funcional el resto es relativamente fácil.

Según la documentación oficial, la estructura del fichero .mtz que tenemos que generar es la siguiente:

Básicamente se trata de un fichero ZIP (método de compresión deflate) al que se le ha cambiado la extensión por .MTZ que contiene un fichero «description.xml» como este:

<?xml version=’1.0′ encoding=’utf-8′ standalone=’yes’ ?>
<MIUI-Theme>
<title>Mi primer AOD</title>
<designer>Cristian</designer>
<author>Cristian</author>
<version>1.0</version>
<uiVersion>12</uiVersion>
<keywords></keywords>
</MIUI-Theme>

El fichero que aparece en el diagrama con el nombre «aod» es también un fichero ZIP (método de compresión deflate) al que se le ha quitado su extensión y que contiene una carpeta «content» y un fichero «aod_description.xml» como este:

<?xml version=’1.0′ encoding=’utf-8′ standalone=’yes’ ?>
<MIUI_Theme_Values>
<!– 类型;百变框架 maml_style –>
<theme_type>maml_style</theme_type>

<!– 是否支持显示农历开关;1 支持,0 不支持,默认为0 –>
<support_lunar_calendar>1</support_lunar_calendar>
<!– 是否支持显示电量开关 –>
<support_battery>1</support_battery>
<!– 是否支持显示通知开关 –>
<support_notification>1</support_notification>

<!– 开关初始状态:显示农历-关闭 –>
<lunar_calendar_enable>0</lunar_calendar_enable>
<!– 开关初始状态:显示电量-开启 –>
<battery_enable>1</battery_enable>
<!– 开关初始状态:显示通知-开启 –>
<notification_enable>1</notification_enable>

</MIUI_Theme_Values>

En el fichero anterior se definen ciertas opciones iniciales y capacidades de las que dispone nuestro tema.

Por otro lado, dentro de la carpeta «content» tenemos la implementación de nuestro AOD. En mi caso se ve así:

Lo interesante ocurre en el fichero «manifest.xml»:

<?xml version=»1.0″ encoding=»utf-8″?>
<Aod frameRate=»60″ screenWidth=»1080″ version=»1″ extraScales=»sw880-den440:0.8148,sw1860-den440:1″ extraResources=»sw880-den440::0.91,sw1860-den440::0.5323″>

<!– aod模块注意事项;1.动画触发放在下方 Trigger 中;2.动画时长不超过4s,超过部分将会被强制停止;3.动画仅播放一次,此后每分钟刷新一次时间 –>
<ExternalCommands>
<Trigger action=»init»>
<ExternCommand command=»animationState» strPara=»‘init'» />
</Trigger>
<Trigger action=»play»>
<AnimationCommand target=»aodAni» command=»play»/>
<AnimationCommand target=»hourAni» command=»play»/>
<AnimationCommand target=»minuteAni» command=»play»/>
</Trigger>
</ExternalCommands>

<VariableBinders>
<!– 查询通知 –>
<ContentProviderBinder name=»data» uri=»content://aod.notification/notifications» columns=»icon» countName=»hasnotifications»>
<Variable name=»notice_icon0″ type=»blob.bitmap» column=»icon» row=»0″/>
<Variable name=»notice_icon1″ type=»blob.bitmap» column=»icon» row=»1″/>
<Variable name=»notice_icon2″ type=»blob.bitmap» column=»icon» row=»2″/>
<Variable name=»notice_icon3″ type=»blob.bitmap» column=»icon» row=»3″/>
</ContentProviderBinder>
</VariableBinders>

<Var name=»aodAni»>
<VariableAnimation loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″/>
<AniFrame value=»1″ time=»1500″/>
</VariableAnimation>
</Var>
<Var name=»hourAni»>
<VariableAnimation loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″ />
<AniFrame value=»0″ time=»1000″ easeType=»CubicEaseOut»/>
<AniFrame value=»1″ time=»1500″/>
</VariableAnimation>
</Var>
<Var name=»minuteAni»>
<VariableAnimation name=»minuteAnimation» loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″ />
<AniFrame value=»0″ time=»1200″ easeType=»CubicEaseOut»/>
<AniFrame value=»1″ time=»1700″/>
<Triggers>
<Trigger action=»end» condition=»#minuteAnimation.current_frame==-1″>
<!– 动画结束之后记得给系统发个命令 –>
<ExternCommand command=»animationState» strPara=»‘finish'» />
</Trigger>
</Triggers>
</VariableAnimation>
</Var>

<Image x=»540″ y=»360″ align=»center» alignV=»center» srcid=»#aodAni*12″ src=»img/num.webp» />
<Image x=»540″ y=»360″ align=»center» alignV=»center» pivotX=»18″ pivotY=»300″ rotation=»(#hourAni-1)*40+#hour12*30+#minute/2″ src=»hour.webp» alpha=»#hourAni*255″ />
<Image x=»540″ y=»360″ align=»center» alignV=»center» pivotX=»29″ pivotY=»300″ rotation=»(#minuteAni-1)*40+#minute*6″ src=»minute.webp» alpha=»#minuteAni*255″ />

<!– 时间 –>
<Group visibility=»eq(#time_format,0)» >
<DateTime x=»540″ y=»700″ format=»hh:mm» size=»110″ color=»#ffffff» align=»center» alignV=»center»/>
</Group>

<Var name=»es_week_xiaoxie» expression=»ifelse(eq(#day_of_week,1),’Domingo’,eq(#day_of_week,2),’Lunes’,eq(#day_of_week,3),’Martes’,eq(#day_of_week,4),’Miércoles’,eq(#day_of_week,5),’Jueves’,eq(#day_of_week,6),’Viernes’,’Sábado’)» type=»string»/>

<Var name=»es_month_jianxie» expression=»ifelse(eq(#month,0),’Enero’,eq(#month,1),’Febrero’,eq(#month,2),’Marzo’,eq(#month,3),’Abril’,eq(#month,4),’Mayo’,eq(#month,5),’Junio’,eq(#month,6),’Julio’,eq(#month,7),’Agosto’,eq(#month,8),’Septiembre’,eq(#month,9),’Octubre’,eq(#month,10),’Noviembre’,’Diciembre’)» type=»string»/>

<Group visibility=»eq(#time_format,1)»>
<DateTime x=»540″ y=»700″ format=»kk:mm» size=»110″ color=»#ffffff» align=»center» alignV=»center»/>
</Group>
<!– 日期、农历 –>
<Text x=»540″ y=»770″ color=»#ffffff» size=»32″ textExp=»@es_week_xiaoxie+’ ‘ +#day_of_week+’ de ‘+@es_month_jianxie+’ de ‘+#year» align=»center» bold=»true»/>
<Text x=»540″ y=»776″ color=»#ffffff» size=»32″ textExp=»@es_week_xiaoxie+’ ‘+#date+’ de ‘+@es_month_jianxie+’ de ‘ #year» align=»center» alignV=»bottom» bold=»true»/>
<!–<DateTime x=»540″ y=»776″ align=»center» alignV=»center» color=»#ffffffff» size=»40″ format=»M月d日 E» bold=»true»/>–>
<DateTime x=»540″ y=»830″ align=»center» alignV=»center» color=»#ffffffff» size=»40″ format=»YY年 N月e» bold=»true» visibility=»#lunar_calendar_enable»/>
<!– 电量 –>
<Group y=»886″ w=»1080″ h=»50″ alignV=»center» visibility=»#battery_enable»>
<Var name=»batteryColor» expression=»ifelse(#battery_state==1||#battery_state==3,’#ff4CB012′,’#ffffffff’)» type=»string» />
<Text x=»540″ y=»25″ align=»right» alignV=»center» color=»#ffffffff» size=»33″ textExp=»#battery_level+’%'» bold=»true»/>
<Rectangle x=»552″ y=»25″ w=»68″ h=»30″ alignV=»center» strokeColor=»#ffffffff» weight=»3″ strokeAlign=»inner» cornerRadius=»15″/>
<Group x=»558″ y=»25″ w=»0.56*#battery_level» h=»18″ alignV=»center» clip=»true»>
<Rectangle w=»56″ h=»18″ fillColor=»@batteryColor» cornerRadius=»9″/>
</Group>
<Image x=»558+28″ y=»25″ align=»center» alignV=»center» src=»lightning.png» visibility=»#battery_state==1||#battery_state==3″ />
</Group>

<!– 本地 预览模式 下显示几条通知;#preview_mode 是否为预览模式 –>
<Var name=»noticeCount» expression=»4″ type=»number» const=»true» />
<!– 通知 –>
<Group x=»ifelse(#preview_mode,-min(#noticeCount-1,3)*60,-min(#hasnotifications-1,3)*60)» visibility=»int(#notification_enable**#preview_mode) || #notification_enable»>
<Image name=»notice_icon0″ x=»540+120*0″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=1||#noticeCount}=1″ srcExp=»ifelse(#preview_mode,’noticeIcon/contacts.png’,»)» />
<Image name=»notice_icon1″ x=»540+120*1″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=2||#noticeCount}=2″ srcExp=»ifelse(#preview_mode,’noticeIcon/mms.png’,»)» />
<Image name=»notice_icon2″ x=»540+120*2″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=3||#noticeCount}=3″ srcExp=»ifelse(#preview_mode,’noticeIcon/email.png’,»)» />
<Image name=»notice_icon3″ x=»540+120*3″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=4||#noticeCount}=4″ srcExp=»ifelse(#preview_mode,’noticeIcon/theme.png’,»)» />
</Group>

</Aod>

Al faltar documentación esta parte es la más complicada de sacar y la vas haciendo fijándote en temas ya hechos. En principio los fotogramas de la animación están separados y se ejecutan en bucle parándose en uno en concreto, con lo cual la imagen que obtendremos en el AOD no siempre corresponderá al mismo fotograma, lo que ayuda a mantener la salud de las pantallas AMOLED.

 

Categories: Android Tags: , ,

Conectando desde nuestro ordenador a Android por SSH

martes, 5 de mayo de 2020 Sin comentarios

Si disponemos de un dispositivo Android al cual queremos acceder por SSH para, por ejemplo, trasferir ficheros porque MTP es intratable desde Linux (al menos con KDE), podemos hacerlo a través de una aplicación llamada Termux. Esta aplicación nos habilita un terminal desde el cual podemos instalar paquetes y configurarlos de forma muy similar a como lo haríamos en cualquier distribución de Linux.

Instalaremos el servicio, averiguaremos con qué usuarios estamos accediendo al terminal, le cambiaremos la contraseña y mostraremos nuestra IP local:

pkg install openssh

whoami

passwd

ifconfig

sshd

Y con un simple comando desde nuestro ordenador conectaremos:

ssh usuario@192.168.1.123 -p8022

Si queremos tener acceso a la tarjeta microSD, tendremos que darle permisos de almacenamiento a la aplicación Termux desde los ajustes de Android. Una vez hecho eso podremos acceder en modo lectura. Para poder realizar escrituras deberemos ejecutar lo siguiente en Termux:

termux-setup-storage

Esto nos habilitará ciertas zonas de escritura dentro del móvil:

cd $HOME/storage

ls -l

Lo anterior nos devolverá algo similar a lo siguiente:

dcim -> /storage/emulated/0/DCIM
downloads -> /storage/emulated/0/Download
external-1 -> /storage/3868-4120/Android/data/com.termux/files
movies -> /storage/emulated/0/Movies
music -> /storage/emulated/0/Music
pictures -> /storage/emulated/0/Pictures
shared -> /storage/emulated/0

La carpeta «external-1» nos llegaría a la tarjeta microSD donde podríamos copiar ficheros y después moverlos con alguna aplicación de Android.

Y para dejar de utilizar nuestro servicio SSH solo tendremos que ejecutar lo siguiente:

pkill sshd

Si queremos automatizar el arranque del servicio SSH cuando abramos la aplicación, sólo tenemos que crear el fichero «~/.bashrc» con «vi» y añadir lo siguiente:

alias exit=»pkill sshd && exit»

sshd
echo «Your IP is: »
ifconfig | grep -Eo ‘inet (addr:)?([0-9]*\.){3}[0-9]*’ | grep -Eo ‘([0-9]*\.){3}[0-9]*’ | grep -v ‘127.0.0.1’

Con lo anterior tendremos el servicio en marcha y nos mostrará en pantalla la IP local que tenemos actualmente. Además incorporamos un alias al comando «exit» que terminará el servicio SSH, lo que nos da un poco de comodidad a la hora de cerrar sesiones.

Categories: Android, GNU/Linux Tags: , , , , ,

Manipular la pantalla de nuestro Android desde el ordenador

martes, 31 de diciembre de 2019 Sin comentarios

Hace algún tiempo que salió el proyecto de Scrcpy pero hasta hace un rato no lo había vuelto a probar y la cuestión es que funciona a la primera y con nuevas características bastante interesantes. Es multiplataforma y su última versión se puede instalar en OpenSuse desde repositorios de la comunidad habiendo tenido previamente la precaución de instalar las herramientas de desarrollo de Android.

Una vez instalado, simplemente tendremos que tener habilitado el modo de depuración en las Opciones de Desarrollador de nuestro terminal y conectarlo por USB a nuestro equipo. Escribiremos el comando «scrcpy» y, tras la confirmación en nuestro móvil, ya podremos utilizarlo. Con el comando CRTL+O podremos apagar la pantalla del móvil mientras lo seguimos utilizando desde el ordenador. También permite su conexión a través de la Wifi con lo que lo convierte en algo bastante cómodo.

Categories: Android Tags: ,

Aumentar el volumen del altavoz de llamadas

jueves, 24 de septiembre de 2015 Sin comentarios

Una de las cosas que mayor incomodidad me producen al recibir una llamada, es no poder escuchar a mi interlocutor con suficiente volumen. Es por ello que, si poseemos un teléfono con Android, podemos amplificar un poco la potencia del altavoz.

A través de un explorador de archivos en modo «root» (Root Browser), accederemos al archivo «/system/etc/mixer_paths.xml» y buscaremos el parámetro «voice-handset» cuyo valor, en mi caso, era de 84 y que pude subir a 94 sin que se produjese distorsión sonora.

No es que se note notablemente pero sí lo suficiente como para dejar de estrujar el móvil contra tu oreja.

Categories: Android Tags: , ,