home / infca / android (navigation links) Do androids dream of electric sheep ?

developer options | MTP i PTP | Termux -> Tempest | Bluestack
tips and tricks | code an APP | crash debug
voice typing
no screen -> access from PC {ext} | ADB at PC {ext}
Links | End | mapa

Android & APPs

go 2 top
Homepage, Documentation,

Install Customize Parameters Tuning BSDSs Logging Restart URLs

What is Android ?

Wiki : Android is a mobile operating system developed by Google, based on the Linux kernel and designed primarily for touchscreen mobile devices such as smartphones and tablets.

wiki


Android developer options

developer options explained

To enable Developer options:

"Developer mode" in TAB8

the Samsung Galaxy Tab A8 likes to hide it one layer deeper than other tablets.
Samsung uses their "One UI" layout, so the "Build number" isn't on the first page of the settings.

Here is the exact path for the Tab A8:

  1. Find the Build Number
    1. Open Settings.
    2. Scroll down the left-hand menu to the very bottom and tap "About tablet".
    3. On the right side of the screen, tap "Software information".
    4. Find Build number in that list.
    5. Tap it 7 times quickly. You’ll see a popup saying "Developer mode has been turned on."
  2. Locate the New Menu
    1. Go back to the main Settings screen.
    2. Look at the left-hand menu again. Developer options will now appear at the very bottom, right below "About tablet."
Diagnose the 15-second freeze

Since you are on a Tab A8 (which has a decent but not "high-end" processor), a 15-second freeze is massive.
Here are two specific things to check in that new menu:

"Connectivity Labs" in TAB8

How to unlock the "Secret" Connectivity Labs

  1. Go to Settings > Connections > Wi-Fi.
  2. Tap the three dots in the top right, then tap "Intelligent Wi-Fi".
  3. Scroll to the very bottom where it says "Intelligent Wi-Fi [Version Number]".
  4. Tap that version number 7-10 times.
  5. A message will appear: "Connectivity Labs is enabled"
  6. Now, a new menu called "Connectivity Labs" will appear at the bottom of the Intelligent Wi-Fi screen.

What to check in Connectivity Labs:


Android USB connections

USB mass storage is the standard protocol used by flash drives, external hard drives, SD cards, and other USB storage devices. The drive makes itself completely available to the computer, just as if it were an internal drive.

USB mass storage -- also known as "USB mass storage device class," USB MSC, or UMS -- was the way older versions of Android exposed their storage to a computer. When you connected your Android device to your computer, you'd have to specifically tap a "Connect storage to PC" button to make the Android device's storage accessible to the computer over USB mass storage. When disconnecting it from the computer, you'd have to tap a "Turn off USB storage" button.

MTP stands for "Media Transfer Protocol." When Android uses this protocol, it appears to the computer as a "media device."

This protocol works very differently from USB mass storage. Rather than exposing your Android device's raw file system to Windows, MTP operates at the file level. Your Android device doesn't expose its entire storage device to Windows. Instead, when you connect a device to your computer, the computer queries the device and the device responds with a list of files and directories it offers.

PTP stands for "Picture Transfer Protocol." When Android uses this protocol, it appears to the computer as a digital camera.

how to geek


Amunt! Top Amunt!
Android Studio

Homepage 2.3.3 - W500 was v 2.1.1 {updated 20171021}. v 3.0

Install, first app, user guide

From "android-studio-bundle-162.4069837-windows" we install into program directory "C:\Program Files\Android\Android Studio\"

V3 comes as "android-studio-ide-171.4402976-windows.zip"

My first APP : SaMeuaApp

"Studio" files are located at "C:\Users\Administrator\AndroidStudioProjects\SaMeuaApp\"

My files (as app-release.apk) are at "C:\sebas\miscosas\android\"

Languages

If I go to homepage, then "Develop", then "Samples" and then "Language", I find

No way I am to use Java, and I prefer not to use C/C++.

Kotlin

What is it ? wiki

Kotlin is a statically-typed programming language that runs on the Java virtual machine and also can be compiled to JavaScript source code or use the LLVM compiler infrastructure. Its primary development is from a team of JetBrains programmers based in Saint Petersburg, Russia.

Installing the Kotlin plugin
The Kotlin plugin is bundled with Android Studio starting from version 3.0 (I have 2.3.3, 20171022).
If you use an earlier version, you'll need to install the Kotlin plugin. Go to "File | Settings | Plugins | Install JetBrains plugin" ... and then search for and install Kotlin. You'll need to restart the IDE after this completes.

Kotlin sample app

Toast, Count, Random app under v3

github

run code on hw

I want to run the program on a hardware device :

Before you can start debugging on your device, there are a few things you must do:

Conecto el S7 al W500 per USB i es veu des "Android Studio" com "Samsung SM-G935F (Android 7.0, API 24)"

debug

Before you start debugging your app, make sure you're using a build variant that sets the debuggable build type property to true, such as the "debug" build variant. To change the build variant Android Studio uses, select "Build > Select Build Variant" in the menu bar, and then select a build variant from the drop-down menu.

To start debugging, click "Debug app" in the toolbar. You have to set some breakpoints to inspect your vars at specific moments.

Kotlin Koans

Koans = series of exercises to get familiar with Kotlin, by Svetlana Isakova


Aplicacions Android interessants

Lista de la compra

ShortCuts

WeSmartPark

Homepage

Video a uTube

Per accedir als parkings amb Bluetooth, només has de posar la matrícula del cotxe a "Gestiona els teus vehicles", que s'hi arriba amb "Perfil".
En aquest apartat pots afegir i eliminar matrícules.

Al arribar al parking has de tenir el bluetooth activat, la geolocalització i l' app oberta. A la app i a la reserva, hi ha les indicacions per obrir la porta del parking.


Els escacs al Android

Per avaluar partides en PNG, tinc instalat "Analyze This" (not free anymore) i "DroidFish"

Problemes

Si envio una partida per WhatsApp i la vull obrir, rebo

You may not have a proper app for viewing this content

Mentre, si la envio per Gmail, va be :

Tambe va be si amb el "Total Commander" vaig a "/storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Documents/Sent"

El fitxer PGN ja te la associacio correcta

how files are opened from WhatsApp making use of file extensions

stack exchange


Termux

Termux is an Android terminal emulator ; own wiki

Pagina de benvinguda :

Wiki: https://wiki.termux.com Community forum: https://termux.com/community Gitter chat: https://gitter.im/termux/termux IRC channel: #termux on freenode Working with packages: * Search packages: pkg search <query> * Install a package: pkg install <package> * Upgrade package: pkg upgrade Subscribint to additional repositories: * Root: pkg install root-repo * Unstable: pkg install unstable-repo * X11: pkg install x11-repo Report issues at https://termux.com/issues

Paquets que instalo - first, run apt update to download the package index

Paquets disponibles : "apt list"

Entorn

$ pwd /data/data/com.termux/files/home $ echo $PATH /data/data/com.termux/files/usr/bin:/data/data/com.termux/files/usr/bin/applets $ echo $SHELL /data/data/com.termux/files/usr/bin/bash $ python -V Python 3.10.5
TAB and other special keys

Termux uses the Volume down button to emulate the Ctrl key.

touch kbd

Preparar el entorn per codificar

config envir to code

Terminal remot

Si volem fer servir SSH o Putty per accedir a Termux, hem de fer servir SSHD

$ whoami u0_a212 $ passwd # set new password sebas $ ifconfig wlan1: inet 192.168.55.252
SSHD

"sshd" - Termux starts SSH on port 8022 :

nicolau@mars:~/sebas/android$ ssh -p 8022 u0_a212@192.168.55.252

If problems :

$ killall sshd $ sshd -d

Per no fer servir usr/pwd, es millor fer servir claus publiques i privades

Instalar-hi un bash o un python meu

$ cd /data/data/com.termux/files/usr/bin/applets ./hola.sh
display syslog

in Ubuntu, the syslog POSIX function in Ubuntu writes to /var/log/syslog

in Android NDK, syslog outputs to logcat: What is the Log API to call from an Android JNI program?

$ logcat -d
Termux URLs


Tempest

.


Emuladors de Android

APPs per Android

Bluestack

Download and install Bluestacks
For better performance and compatibility, choose BlueStacks 5 Nougat 64-bit

Fronius.Solar.web under Bluestack

Fent servir "Play Store", trobem la APP pero ens diu ... Esta aplicacion no funcionará en tu dispositivo {???}

  1. start "BlueStacks App Player"
  2. download "Fronius Solar.web live_1.1.7_APKPure.apk"
  3. right-click on the file and select "Open with ..." and choose "Bluestack"
  4. la icona "Solar.web live" apareix dintre de Bluestack i tambe al escriptori
  5. engeguem la APP amb la icona, pareix un menu per seleccionar l'inversor ... i "cau" Bluestacks
solar.web under Nox

Requirements :

Lets go on T440 :

  1. get NoxPlayer {20250125 - v 7.0.6.2 }
    enable VT is possible

  2. right-click on the file and select "Open with ..." and choose "NoxPlayer" -the "Solar.web live" ison appears {1st "Solar.web live" v 1.1.7}

  3. click on the icon and we get the message "Cargando los datos ..."

  4. pico al (+) a la vora del Fronius de baix a la dreta i ...
    1040-v7.0.6.2 : Perdón, la maquina virtual no ha podido activarse. Por favor, facilita tus comentarios.
    W7 window : Microsoft Visual C++ Runtime Library : This application has requested the Runtime to terminate it in an unusual way.

    Si pico a "Inicial sesion" dintre de les 3 ratlletes de dalt a l'esquerra ...
    La aplicacion Solar.web ha dejado de funcionar

  5. {2nd "Solar.web pro" v 2.2.8 }
    No se han podido recibir datos válidos del servidor.

la paperera del WhatsApp

  1. obre "Google Files"
  2. escull "internal storage"
  3. ves a "Android"
  4. segueix per "Media"
  5. entra a "com.whatsapp"
  6. i ara a "WhatsApp"
  7. .. dintre de "Media" tens un munt de imatges, videos, etc

Android Photos

Backup

Google Photos

Google Photos

Google Drive

Google Drive

raw copy

  1. connect the Android phone to the PC using a USC cable
  2. on Android, select (MTP) "File transfer" mode
  3. on PC, open "Mi9" device, then select "Internal Storage", "WhatsApp", "Media", "WhatsApp Images"
  4. select the images to copy, then paste them on PC Explorer

imobie


disable GetApps + 2 PC commands for Android

4 methods to disable GetApps


primeOS

Homepage


stored passwords

  1. settings
  2. Google
  3. manage your Google account
  4. security (to the right)
  5. password manager (down)
  6. select APP + click "eye" to see

wifi throttling

Wi-Fi scan throttling is a feature on Android devices that limits how often apps can scan for nearby Wi-Fi networks.
This restriction is designed to conserve battery life and improve network performance and security.

When Wi-Fi scan throttling is enabled, the device restricts the frequency of Wi-Fi scanning. This helps prevent apps from constantly scanning for networks, which can drain the battery. For example, on many Android versions, a foreground app is limited to four scans every two minutes, while all background apps combined can only scan once every 30 minutes.

While beneficial for battery life, Wi-Fi scan throttling can sometimes affect the performance of apps that rely on frequent Wi-Fi scans.
For instance, Wi-Fi analyzer apps may not provide real-time, accurate results because their ability to scan is limited. Similarly, some users have reported that turning off this feature improved their network speed and connection reliability, particularly in cases where their device was slow to switch between Wi-Fi bands (like 2.4 GHz and 5 GHz).

🚫 Disabling Wi-Fi Scan Throttling 🚫

If you're experiencing connectivity issues, you can disable this feature in your device's developer options

  1. navigate to Developer options : it may be under System or Advanced (Redmi 10 & 12 : "Additional settings")
  2. find the Wi-Fi scan throttling toggle and turn it off.

Disabling this setting can improve the performance of some apps and network stability, but it may also slightly increase battery consumption.


Android tips and tricks
remove "Today's recommendations" from desktop

crast.net - Security, My Music, Themes, Cleaner, File Manager, Mi Browser ...

  1. open "Security" app
  2. top right click on "Settings"
  3. scroll down until you find "Receive recommendations"
  4. uncheck it
display SD size

  1. open Google "Files" app
  2. top left click on "Menu" (3 horizontal bars)
  3. select "Clean"
  4. all your cards are displayed
Google-related


Android emulator

5 Best Android emulators for Linux (2020) - fossbytes

  1. Android-x86
    You can also run it without installation using the Live CD option
  2. AVD (Android Virtual Device)
  3. Genymotion
  4. Bliss OS
  5. Anbox
android-x86

Homepage android-x86.org

System requirements :

Booting using ISO :

  1. download ISO from here - url (921 MB)
  2. connect destination USB
  3. check the connected USB device name by :

    $ lsblk
  4. include the USB name in the command

    $ dd status=progress if=android-x86_64-9.0-r1.iso of=/dev/sdX nicolau@mars:~/android_emulator$ sudo dd status=progress if=android-x86_64-9.0-r2.iso of=/dev/sdb 961606144 bytes (962 MB, 917 MiB) copied, 280 s, 3.4 MB/s 1886208+0 records in 1886208+0 records out 965738496 bytes (966 MB, 921 MiB) copied, 280.86 s, 3.4 MB/s

    ... where sdX is the device name of your USB drive

  5. boot your PC into the USB

    T60 :

    This kernel requires a x86-64 CPU, but only detected an i686 CPU. Unable to boot - please use a kernel appropiate for your CPU.

    32-bit :

    Detecting Android-x86 Found at /dev/sdb

url

nicolau@mars:~/android_emulator$ sudo dd if=android-x86_64-9.0-r2.iso of=/dev/sdb
genymotion

Genymotion - Android emulator

Requirements :

nicolau@mars:~/android_emulator$ ./genymotion-3.1.2-linux_x64.bin . Unknown option: .. Usage: genymotion-3.1.2-linux_x64.bin [--destination path][--uninstall][--yes] Options: --destination | -d : folder where to install binaries. Defaults to [/home/nicolau/android_emulator] --uninstall | -u : remove binaries and resources from destination folder --yes | -y : answer yes to all questions nicolau@mars:~/android_emulator$ ./genymotion-3.1.2-linux_x64.bin Installing for current user only. To install for all users, restart this installer as root. Installing to folder [/home/nicolau/android_emulator/genymotion]. Are you sure [y/n] ? y - Trying to find VirtualBox toolset .................... OK (Valid version of VirtualBox found: 5.2.42_Ubuntur137960) - Extracting files ..................................... OK (Extract into: [/home/nicolau/android_emulator/genymotion]) - Installing launcher icon ............................. OK Installation done successfully. You can now use these tools from [/home/nicolau/android_emulator/genymotion]: - genymotion - genymotion-shell - gmtool

Lets run :

nicolau@mars:~/android_emulator/genymotion$ ./genymotion . Logging activities to file: /home/nicolau/.Genymobile/genymotion.log

  1. creating a "Samsung Galaxy 7" device, Android 8, 1440 x 2560
  2. install "Open GApps" (store) - Open GApps archive is corrupted -> go version 3.2.0.beta

Instalo Play Store, pero no puc instalar SimCity


com fer una App per Android
Eines per fer una App per Android mitjançant python

Gemini

Input : escriu una app per android que rebi dades de la pantalla i ho envii a un servidor via REST

Output :

// MainActivity.kt package com.example.screencaptureapp import android.Manifest import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.PixelFormat import android.hardware.display.DisplayManager import android.media.Image import android.media.ImageReader import android.media.projection.MediaProjection import android.media.projection.MediaProjectionManager import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.DisplayMetrics import android.util.Log import android.view.Display import android.view.View import android.view.WindowManager import android.widget.Button import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.google.gson.Gson import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import java.io.ByteArrayOutputStream import java.io.IOException import java.nio.ByteBuffer import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import android.net.ConnectivityManager import android.net.NetworkCapabilities // Permisos necessaris private const val PERMISSION_REQUEST_CODE = 100 private const val MEDIA_PROJECTION_REQUEST_CODE = 200 private val REQUIRED_PERMISSIONS = arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.INTERNET, // Afegit el permís d'Internet Manifest.permission.ACCESS_NETWORK_STATE // Afegit el permís per comprovar l'estat de la xarxa ) class MainActivity : AppCompatActivity() { // Declaració de variables private var mediaProjectionManager: MediaProjectionManager? = null private var mediaProjection: MediaProjection? = null private var imageReader: ImageReader? = null private var handler: Handler? = null private var display: Display? = null private var windowManager: WindowManager? = null private var densityDpi = 0 private var screenWidth = 0 private var screenHeight = 0 private lateinit var captureButton: Button private lateinit var resultTextView: TextView private var isCapturing = false private val serverUrl = "http://your-server-address/upload" // Reemplaça amb la teva URL del servidor private val httpClient = OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) // Augmenta el timeout de connexió .readTimeout(30, TimeUnit.SECONDS) // Augmenta el timeout de lectura .writeTimeout(30, TimeUnit.SECONDS) // Augmenta el timeout d'escriptura .build() private val gson = Gson() private val executor = Executors.newSingleThreadExecutor() // Utilitza un únic fil per a les operacions de xarxa override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Inicialització de variables i obtenció de serveis del sistema captureButton = findViewById(R.id.captureButton) resultTextView = findViewById(R.id.resultTextView) mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager display = windowManager?.defaultDisplay // Obtenció de les mètriques de la pantalla val metrics = DisplayMetrics() display?.getRealMetrics(metrics) // Utilitza getRealMetrics per obtenir la resolució real densityDpi = metrics.densityDpi screenWidth = metrics.widthPixels screenHeight = metrics.heightPixels // Inicialització del handler per a la captura de pantalla handler = Handler(Looper.getMainLooper()) // Configuració del listener del botó de captura captureButton.setOnClickListener { if (isCapturing) { stopCapture() captureButton.text = "Start Capture" // Canvia el text del botó } else { startCapture() captureButton.text = "Stop Capture" // Canvia el text del botó } } // Comprovació i sol·licitud de permisos if (!checkPermissions()) { requestPermissions() } else { // Si els permisos ja estan concedits, inicialitza la captura de pantalla // Això és important per al flux on l'usuari ja ha concedit permisos anteriorment. prepareMediaProjection() } } // Funció per comprovar si tots els permisos necessaris estan concedits private fun checkPermissions(): Boolean { for (permission in REQUIRED_PERMISSIONS) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { return false } } return true } // Funció per sol·licitar els permisos necessaris private fun requestPermissions() { ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, PERMISSION_REQUEST_CODE) } // Funció per inicialitzar la captura de pantalla private fun startCapture() { if (mediaProjection == null) { prepareMediaProjection() // Assegura que mediaProjection està inicialitzat return } // Lógica per iniciar la captura de pantalla createImageReader() startCaptureLoop() isCapturing = true } private fun stopCapture() { isCapturing = false; handler?.removeCallbacksAndMessages(null); // Important: Remove any pending posts. if (imageReader != null) { imageReader?.close() } if (mediaProjection != null) { mediaProjection?.stop() } imageReader = null; mediaProjection = null; } // Funció per preparar la projecció de mitjans private fun prepareMediaProjection() { if (mediaProjectionManager != null) { val captureIntent = mediaProjectionManager?.createScreenCaptureIntent() if (captureIntent != null) { startActivityForResult(captureIntent, MEDIA_PROJECTION_REQUEST_CODE) } else { Toast.makeText(this, "Failed to create screen capture intent", Toast.LENGTH_SHORT).show() } } else { Toast.makeText(this, "MediaProjectionManager is null", Toast.LENGTH_SHORT).show() } } // Funció per crear l'ImageReader private fun createImageReader() { imageReader = ImageReader.newInstance( screenWidth, screenHeight, PixelFormat.RGBA_8888, 2 ) // Increased maxImages to 2 } // Funció per iniciar el bucle de captura de pantalla private fun startCaptureLoop() { handler?.post(object : Runnable { override fun run() { if (!isCapturing) { return // Stop if not capturing } captureScreen() handler?.postDelayed(this, 1000) // Captura cada segon (1000ms) } }) } // Funció per capturar la pantalla private fun captureScreen() { if (mediaProjection != null && imageReader != null) { try { mediaProjection?.acquireNextImage(imageReader!!, 0)?.let { image -> // Utilitzar un fil per a la conversió a bitmap i enviament executor.execute { val bitmap = imageToBitmap(image) image.close() // Important: Close the image after use if (bitmap != null) { sendData(bitmap) } } } } catch (e: Exception) { Log.e("CaptureError", "Error capturing or processing image: ${e.message}") e.printStackTrace() // Print the stack trace to get detailed error information. runOnUiThread { resultTextView.text = "Error: ${e.message}" } } } else { Log.e("CaptureError", "MediaProjection or ImageReader is null") runOnUiThread { resultTextView.text = "Error: MediaProjection or ImageReader is null" } } } // Funció per convertir Image a Bitmap private fun imageToBitmap(image: Image): Bitmap? { val plane = image.planes[0] val buffer = plane.buffer val pixelStride = plane.pixelStride val rowStride = plane.rowStride val rowPadding = rowStride - image.width * pixelStride val bitmap = Bitmap.createBitmap( image.width, image.height, Bitmap.Config.ARGB_8888 ) bitmap.copyPixelsFromBuffer(buffer) return bitmap } // Funció per enviar les dades al servidor private fun sendData(bitmap: Bitmap) { if (!isNetworkAvailable()) { Log.e("NetworkError", "No network connection") runOnUiThread { resultTextView.text = "Error: No network connection" } return } val stream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream) // Compress as PNG val byteArray = stream.toByteArray() val requestBody = byteArray.toRequestBody("image/png".toMediaTypeOrNull()) // Set correct MIME type val request = Request.Builder() .url(serverUrl) .post(requestBody) .build() try { val response = httpClient.newCall(request).execute() val responseBody = response.body?.string() // Get the response body if (response.isSuccessful) { Log.d("SendData", "Data sent successfully. Response: $responseBody") runOnUiThread { resultTextView.text = "Data sent successfully. Response: $responseBody" } } else { Log.e("SendData", "Failed to send data. Response Code: ${response.code}, Response Body: $responseBody") runOnUiThread { resultTextView.text = "Failed to send data. Code: ${response.code}, Response: $responseBody" } } response.close() // Close the response stream.close() } catch (e: IOException) { Log.e("SendData", "Error sending data: ${e.message}") e.printStackTrace() runOnUiThread { resultTextView.text = "Error sending data: ${e.message}" } } } private fun isNetworkAvailable(): Boolean { val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val network = connectivityManager.activeNetwork ?: return false val activeNetwork = connectivityManager.getNetworkCapabilities(network) ?: return false return when { activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true else -> false } } else { // Deprecated method, but still needed for older devices. val networkInfo = connectivityManager.activeNetworkInfo return networkInfo != null && networkInfo.isConnected } } // Funció per alliberar recursos override fun onDestroy() { super.onDestroy() handler?.removeCallbacksAndMessages(null) // Clear handler callbacks executor.shutdown() // Shutdown the executor if (mediaProjection != null) { mediaProjection?.stop() mediaProjection = null } if (imageReader != null) { imageReader?.close() imageReader = null } } // Funció per gestionar el resultat de la sol·licitud de projecció de mitjans override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == MEDIA_PROJECTION_REQUEST_CODE) { if (resultCode == RESULT_OK && data != null) { try { mediaProjection = mediaProjectionManager?.getMediaProjection(resultCode, data) if (mediaProjection != null) { // Inicialitza ImageReader i comença la captura només si mediaProjection té èxit createImageReader() // Inicialitza el ImageReader aquí startCapture() isCapturing = true; captureButton.text = "Stop Capture" } else { Toast.makeText(this, "Failed to get MediaProjection", Toast.LENGTH_SHORT).show() resultTextView.text = "Error: Failed to get MediaProjection" } } catch (e: Exception) { Log.e("ProjectionError", "Error getting MediaProjection: ${e.message}") e.printStackTrace() Toast.makeText(this, "Error: ${e.message}", Toast.LENGTH_SHORT).show() resultTextView.text = "Error: ${e.message}" } } else { Toast.makeText(this, "User cancelled MediaProjection permission", Toast.LENGTH_SHORT).show() resultTextView.text = "Error: User cancelled MediaProjection permission" } } else if (requestCode == PERMISSION_REQUEST_CODE) { if (resultCode == RESULT_OK) { // Fer alguna cosa si els permisos són concedits prepareMediaProjection() } else { Toast.makeText(this, "Permissions not granted", Toast.LENGTH_SHORT).show() resultTextView.text = "Error: Permissions not granted" } } } // Per assegurar-nos que alliberem els recursos adequadament quan l'activitat es deté. override fun onStop() { super.onStop() if (isCapturing) { stopCapture() captureButton.text = "Start Capture" } } }

Explanation :

Here's a breakdown of the code: Permissions: The app requests necessary permissions (storage, internet, and network state) at runtime. UI Setup: activity_main.xml: Defines the layout with a button to start/stop capture and a text view for results. The code initializes captureButton and resultTextView. Screen Capture: MediaProjectionManager and MediaProjection: Used to capture the screen. ImageReader: Captures screen frames as Image objects. The imageReader is initialized with the screen dimensions. The captureScreen() function acquires the next available image from the ImageReader, converts it to a Bitmap, and sends it to the server. The image.close() method is crucial to release the Image resources. The startCaptureLoop() method repeatedly calls captureScreen() every second using a Handler. Bitmap Conversion: The imageToBitmap() function converts the Image object from the ImageReader into a Bitmap. Data Sending: sendData(): Converts the Bitmap to a PNG byte array. Sends the data to the server using an HTTP POST request with OkHttpClient. The MediaType is set to image/png. Handles the server response and updates the UI with the result. Checks for network connectivity before sending data. Server Interaction: The serverUrl variable should be replaced with your server's endpoint. The server needs to be set up to receive the image data and process it accordingly. The server should expect a POST request with the image data in the body. Error Handling: The code includes error handling for various operations, such as: Permission issues. Media projection errors. Network connectivity problems. Server communication failures. Cleanup: The onDestroy() method releases resources, including stopping the MediaProjection, closing the ImageReader, and shutting down the executor. The handler.removeCallbacksAndMessages(null) call is added to prevent memory leaks. Network Check: The isNetworkAvailable() function checks if the device is connected to a network before attempting to send data. It handles both modern and deprecated methods for checking network connectivity. Background Thread: The image conversion and sending to server are done on a background thread using Executors.newSingleThreadExecutor() to prevent blocking the main thread. Activity Result: The onActivityResult method handles the result of the MediaProjectionManager.createScreenCaptureIntent() call. Permissions: The checkPermissions() and requestPermissions() methods check for and request the necessary permissions. Resource Management: The image.close() method is used to free up resources after the image has been processed. The response.close() method is used to close the HTTP response body. The stream.close() method is used to close the byte array output stream. User Feedback: The resultTextView is updated on the main thread using runOnUiThread to display the result of the operation to the user. Toast messages are also used for short notifications.

Final :

Remember to replace "http://your-server-address/upload" with your actual server URL.

How to debug an App crash

  1. on Android, install "Logcat Reader"

  2. grant the permissions :

    1. if you phone is "rooted", select "Rooted", otherwise "Manual" -> we shall use "Manual"
    2. install ADB on your computer (Android Debug Bridge)
    3. connect your phone via USB with USB debugging enabled
    4. run this command:

      adb shell pm grant com.nolanlawson.logcat android.permission.READ_LOGS
    5. restart the app → you should now see full system log output

  3. clear the old logs

  4. produce the crash

  5. search the logs for "Tempest" text

Voice typing

Prova :

  1. open Youtube video, as Joan Rivers
  2. open Google Docs on Android phone
    pica els 4 quadradets i escull "Veu" (icona de microfon)
    Toca aquesta icona. S'obrirà un menú amb diverses eines. Si veus el micròfon allà, el pots arrossegar cap a la barra principal per tenir-lo sempre a mà.

Missatges de PC

Els missatges d'alerta de Protecció Civil al mòbil a Espanya funcionen a través del sistema ES-Alert, també conegut com a "Public Warning System" o "Alertes Públiques".

Redmi Note 10 Pro

  1. Android version 13
  2. open "Settings"
  3. search for "Wireless emergency alerts" (under "Safety and emergency")
  4. disable
Samsung S8 tablet

  1. Android version 14
  2. open "Settings"
  3. search for "Wireless emergency alerts" (under "Safety and emergency")
  4. disable
Redmi Note 12 5G

  1. Android version 15
  2. open "Settings"
  3. search for "Alertes d'emergencia sense fil" (under "Seguretat i emergencia")
  4. disable

Find Hub network

Your Android device stores encrypted recent locations with Google and participates in the Find Hub network, a crowdsourced network of Android devices that uses end-to-end encrypted location information to help Android users find their lost devices.

support Google

Per gestionar la participació del dispositiu, ves a Configuració > Google > Tots els serveis (si hi ha pestanyes) > Localitzador > Cerca els teus dispositius sense connexió


Dubtes de Android


Links


Ep ! Valid HTML 4.01!   Valid CSS! Escriu-me !
Updated 20230423 (a)  
Uf !