mercoledì 25 gennaio 2017

Google IO : Save the date

Google ha lanciato, a modo suo, la data del nuovo Google IO...per sapere il posto ed il luogo e' necessario risolvere 5 puzzle.

Premetto che non intendo spoilerare i risultati (anche se le soluzioni sono gia' disponibili su Internet su Reddit) ..questo e' solo un racconto dei miei due successi e degli insuccessi

Si parte da questo link http://goo.gl/oqro8L. (attenzione a disattivare uBlock e simili)
Da notare che la soluzione per ogni quiz e' una coppia di coordinate geografiche

Il primo link punta a GitHub

basta leggere il codice Javascript per ottenere la prima coordinata

Data la prima soluzione viene fornito il primo indizio e si ha il link per il secondo quesito



Il secondo passo e' un video di Youtube pubblico ma non negli elenchi. L'immagine e' fissa senza audio


Il titolo del video e' See What Cannot Be Heard
attivando i sottotitoli si ottiene la sequenza

Magic I.see_a beach,-yes._i explore daylight

Non sono riuscito a risolverlo..certo che sapere che la soluzione doveva essere una coordinata mi ha dato la certezza che la virgola non era messa li' a caso
Ecco il secondo indizio



Il terzo quiz e' decisamente piu' facile. Una radio ed un microscopio pulsante play (si tratta di una slide di una presentazione)

La voce pronuncia il seguente codice

053 050 046 049 056 050 049 044 032 050 048 046 057 057 054 053

salta subito all'occhio lo 032 centrale e sapendo che si tratta del codice di una coordinata si desume che 032 indichi la virgola separatrice. Basta un confronto col codice ASCII della virgola (32) per capire che la coordinata e' una semplice codifica ascii dei numeri
Il


ed arriviamo ai due quiz per me impossibili
il quarto puzzle rimanda ad una cartella GDrive con alcune immagini

da notare anche il proprietario delle immaigni ovvero Pei Xiu , cartografo cinese
queste sono le immagin

caves.jpg

pillar.jpg

shrine.jpg

spire.jpg

ho provato a vedere se per caso negli Exif ci fosse il geotag con le coordinate. Niente da fare.
Ho provato a cercare le immagini con TinEye ma niente da fare


con Google Image (anche con l'immagine corrotta) si arriva a capire che le immagini sono relative al tempio di Gunung Kawi


pensavo di avere vinto una volta trovate le coordinate del tempio



ma e' tutto sbagliato....non si sono andato nemmeno vicino
con l'aiuto della rete comunque questo e' il quarto indizio


ed arriviamo al quinto quiz..inutile dire che su questo non sono riuscito nemmeno a partire


e questa e' la soluzione finale


2 su 5 e' sempre meglio che 0 su 5 (impegnandomi avrei potuto fare 3 su 5 ma l'enplein era praticamente impossibile)

martedì 17 gennaio 2017

Grafico realtime dellaccelerometro su Android

Un esempio su come visualizzare dati realtime dell'accelerometro su Android


E' stata impiegata la libreria GraphView (per aggiungere la libreria, invece di usare Gradle, ho scaricato il file .jar, ho creato una directory libs nel progetto con Project Clean finale)

--------------------------------
package com.luca_innocenti.wristcoach;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.MessageEvent;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.LegendRenderer;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.DataPointInterface;
import com.jjoe64.graphview.series.LineGraphSeries;


public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private String receivedMessage = null;
    private static final String TAG = "WearMainActivity";

    private SensorManager sensorManager;
    private long lastUpdate;
    private double graph2LastXValue = 5d;
    private LineGraphSeries<DataPointInterface> mSeries;
    private LineGraphSeries<DataPointInterface> mSeries2;
    private LineGraphSeries<DataPointInterface> mSeries3;


    private double[] linear_acceleration = new double[3];
    private double[]  gravity = new double[3];


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        IntentFilter messageFilter = new IntentFilter(Intent.ACTION_SEND);
        MessageReceiver messageReceiver = new MessageReceiver();
        LocalBroadcastManager.getInstance(getApplication()).registerReceiver(messageReceiver, messageFilter);

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

        lastUpdate = System.currentTimeMillis();

        GraphView graph = (GraphView) findViewById(R.id.graph);

        mSeries = new LineGraphSeries<>();
        mSeries2 = new LineGraphSeries<>();
        mSeries3 = new LineGraphSeries<>();



        mSeries.setTitle("AX");
        mSeries.setColor(Color.GREEN);
        //mSeries.setDrawDataPoints(true);        //mSeries.setDataPointsRadius(10);        mSeries.setThickness(2);

        mSeries2.setTitle("AY");
        mSeries2.setColor(Color.RED);
        //mSeries2.setDrawDataPoints(true);        //mSeries2.setDataPointsRadius(10);        mSeries2.setThickness(2);

        mSeries2.setTitle("AZ");
        mSeries2.setColor(Color.RED);
        //mSeries2.setDrawDataPoints(true);        //mSeries2.setDataPointsRadius(10);        mSeries2.setThickness(2);

        graph.addSeries(mSeries);
        graph.addSeries(mSeries2);
        graph.addSeries(mSeries3);
        graph.getViewport().setXAxisBoundsManual(true);
        graph.getViewport().setMinX(0);
        graph.getViewport().setMaxX(40);

        graph.getViewport().setYAxisBoundsManual(true);
        graph.getViewport().setMinY(-7);
        graph.getViewport().setMaxY(7);

        graph.getLegendRenderer().setVisible(true);
        graph.getLegendRenderer().setAlign(LegendRenderer.LegendAlign.TOP);


    }

    public class MessageReceiver extends BroadcastReceiver {
        private static final String TAG = "MessageReceiver";

        @Override        public void onReceive(Context context, Intent intent) {

            receivedMessage = intent.getStringExtra("message");
            Log.d("MessageReceiver", "onReceive() receivedMessage = " + receivedMessage);

            if (receivedMessage != null) {
                // Display message in UI                //message = receivedMessage;                Log.d("MessageReceiver", "receivedMessage =" + receivedMessage);
            } else {
                receivedMessage = "No Message";
                Log.d("MessageReceiver", "receivedMessage = No Message");
            }

        }
    }


    @Override    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            getAccelerometer(event);
        }

    }

    @Override    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //To change body of implemented methods use File | Settings | File Templates.    }

    private void getAccelerometer(SensorEvent event) {
        float[] values = event.values;
        // Movement        float x = values[0];
        float y = values[1];
        float z = values[2];
        final double alpha = 0.8;

        // Isolate the force of gravity with the low-pass filter.        gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
        gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
        gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

        // Remove the gravity contribution with the high-pass filter.        linear_acceleration[0] = event.values[0] - gravity[0];
        linear_acceleration[1] = event.values[1] - gravity[1];
        linear_acceleration[2] = event.values[2] - gravity[2];

        String strTmp = "Acc.\n"                + " X: " + linear_acceleration[0] + "\n"                + " Y: " + linear_acceleration[1] + "\n"                + " Z: " + linear_acceleration[2];
        Log.d(TAG,strTmp);
        Double risultante = Math.sqrt(((linear_acceleration[0]*linear_acceleration[0])+(linear_acceleration[1]*linear_acceleration[1])+(linear_acceleration[1]*linear_acceleration[1])));

        long actualTime = System.currentTimeMillis();
        graph2LastXValue += 1d;
        mSeries.appendData(new DataPoint(graph2LastXValue, linear_acceleration[0]), true, 100);
        mSeries2.appendData(new DataPoint(graph2LastXValue, linear_acceleration[1]), true, 100);
        mSeries3.appendData(new DataPoint(graph2LastXValue, linear_acceleration[2]), true, 100);


        Log.d("luca",Double.toString(risultante));

    }



    @Override    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_FASTEST);
    }
    @Override    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

lunedì 16 gennaio 2017

Integrazione di Android Studio con GitHub

Android Studio permette una buona integrazione con GitHub ma ci sono un po' di passi non banalissimi per arrivare al risultato desiderato.

Per prima cosa dall'interfaccia Web di GitHub si crea il nuovo progetto

Poi da Android Studio si Crea un Git Repository



facendolo puntare alla directory dell'applicazione in fase di sviluppo (in questo caso una applicazione per Android Wear)


Si apre un terminale da dentro Android Studio e nella root del progetto si digita il codice


git remote add origin https://github.com/[username]/[project_name].git

si conferma
In seguito si effettua il primo commit
A questo punto si e' pronti per fare il primo push del progetto verso GitHub




La richiesta della password e' quella relativa all'account GitHub (in questo caso e' pero' il portachiavi di Mac)








giovedì 12 gennaio 2017

RTC Odin OEC12C887A

Mi e' capitato di avere a che fare con un Pentium 166 con la batteria del BIOS esaurita


Facile...basta cambiarla con una nuova CR2032...peccato che non riuscivo a trovarla.
L'attenzione e' stata catturata da una componente a me sconosciuto ovvero ODIN OEC12C887A.
Da una ricerca su questo link e' emerso che Odin e' un RTC (Real Time Clock) con all'interno la batteria tampone. I componenti sono ancora in commercio ma il fatto di essere saldato sulla mother board e' una difficolta' di non poco conto.
Sul medesimo sito sono riportate tecniche, piuttosto intrusive, per far rivivere l'RTC del computer ma vista la scarsa possibilita' di successo forse e' meglio lasciare tutto com'e' ed aggiornare i parametri ad ogni accensione

martedì 10 gennaio 2017

Message Api in Android Wear

Le Message API permettono di scambiare messaggi tra dispositivi Android, nel caso specifico tra il telefono e l'orologio mediante Android Wear
Nell'esempio in esame vengono sincronizzati due NumberPicker



Il progetto completo e' disponibile su GitHub ed e' basato sull'esempio a questo link

Per NumberPicker sul telefono, piu' che altro per la gestione del font, e' stato usato questa modifica



Lato Telefono
build.gradle
--------------------------------------
apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.luca_innocenti.apticmetro"
        minSdkVersion 21
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    wearApp project(':wear')
    compile 'com.google.android.gms:play-services:10.0.1'
    compile 'com.android.support:appcompat-v7:25.1.0'
    compile 'com.shawnlin:number-picker:2.3.0'

    testCompile 'junit:junit:4.12'
}
--------------------------------------

MainActivity
--------------------------------------
package com.luca_innocenti.apticmetro;

import android.icu.lang.UCharacter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
//import android.widget.NumberPicker;
import com.shawnlin.numberpicker.NumberPicker;

import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;



// Applicazione Mobile
public class MainActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener
{

    private static final String TAG = "MainActivity";
    private GoogleApiClient googleApiClient;

    private ImageButton play;
    private NumberPicker bpm;
    private int counter;

    public MainActivity() {
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        googleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        //play = (ImageButton) findViewById(R.id.imageButton);
        bpm = (NumberPicker) findViewById(R.id.number_picker);


        bpm.setMinValue(40);
        bpm.setMaxValue(150);
        bpm.setValue(80);
        bpm.setWrapSelectorWheel(false);


        bpm.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal){
                //Display the newly selected number from picker
                Log.d(TAG,Integer.toString(newVal));
                String sendMessage = Integer.toString(newVal);
                new SendToDataLayerThread("/path", sendMessage).start();
            }
        });



        /*play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Toast.makeText(MainActivity.this, "Inviato", Toast.LENGTH_SHORT).show();
                String sendMessage = "Start";
                counter++;

                new SendToDataLayerThread("/path", sendMessage).start();

                Log.d(TAG, "SendToDataLayerThread()");


            }
        });*/
    }


    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart()");
        googleApiClient.connect();
    }

    // data layer connection
    @Override
    public void onConnected(Bundle bundle) {
        Log.d(TAG, "onConnected()");
    }

    // Activity stop
    @Override
    protected void onStop() {
        if (null != googleApiClient && googleApiClient.isConnected()) {
            googleApiClient.disconnect();
        }
        super.onStop();

        Log.d(TAG, "onStop()");

    }

    @Override
    public void onConnectionSuspended(int cause) { }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) { }

    private class SendToDataLayerThread extends Thread{
        String path;
        String handheldMessage;

        public SendToDataLayerThread(String pth, String message) {
            //path = "/messaggio";
            path = pth;
            handheldMessage = message;
        }
        public void run() {
            Log.d(TAG, "SendToDataLayerThread()");

            NodeApi.GetConnectedNodesResult nodeResult = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
            for (Node node : nodeResult.getNodes()) {
                MessageApi.SendMessageResult result =
                        Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), path, handheldMessage.getBytes()).await();

                if (result.getStatus().isSuccess()) {
                    Log.d(TAG, "To: " + node.getDisplayName());
                    Log.d(TAG, "Message = " + handheldMessage );
                }
                else {
                    Log.d(TAG, "Send error");
                }
            }
        }
    }
}
--------------------------------------


AndroidManifest.xml
--------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.luca_innocenti.apticmetro">

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
--------------------------------------



Lato Orologio 
build.gradle
--------------------------------------
apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.luca_innocenti.apticmetro"
        minSdkVersion 21
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.google.android.support:wearable:2.0.0-beta1'
    compile 'com.google.android.gms:play-services-wearable:10.0.1'
    provided 'com.google.android.wearable:wearable:2.0.0-beta1'
}
--------------------------------------

Manifest.xml
--------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.luca_innocenti.apticmetro">

    <uses-feature android:name="android.hardware.type.watch" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-library android:name="com.google.android.wearable" android:required="false" />



    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.DeviceDefault">
        <uses-library
            android:name="com.google.android.wearable"
            android:required="false" />


        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.DeviceDefault.Light">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".WearService">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
                <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
                <data android:scheme="wear" android:host="*" android:pathPrefix="/path" />
            </intent-filter>
        </service>
    </application>


</manifest>
--------------------------------------

MainActivity
--------------------------------------
package com.luca_innocenti.apticmetro;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.v4.content.LocalBroadcastManager;
import android.support.wearable.activity.WearableActivity;
import android.support.wearable.view.BoxInsetLayout;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.NumberPicker;
import android.os.Handler;

import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.MessageEvent;



// Lato orologio
public class MainActivity extends WearableActivity {

    private BoxInsetLayout mContainerView;
    private NumberPicker bpm;
    private ImageButton play;
    private int stato;
    long startTime = 0;
    long valore_bpm;

    private String receivedMessage = null;
    private String message = "";
    private static final String TAG = "WearMainActivity";




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setAmbientEnabled();

        Log.v(TAG, "onCreate()");
        IntentFilter messageFilter = new IntentFilter(Intent.ACTION_SEND);
        MessageReceiver messageReceiver = new MessageReceiver();
        LocalBroadcastManager.getInstance(getApplication()).registerReceiver(messageReceiver, messageFilter);


        final Handler timerHandler = new Handler();
        final Runnable timerRunnable = new Runnable() {

            @Override
            public void run() {
                Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                vibrator.vibrate((100));
                timerHandler.postDelayed(this, valore_bpm);
            }
        };


        stato = 0;

        mContainerView = (BoxInsetLayout) findViewById(R.id.container);
        bpm = (NumberPicker) findViewById(R.id.numberPicker);
        play =(ImageButton) findViewById(R.id.imageButton);

        bpm.setMinValue(40);
        bpm.setMaxValue(150);
        bpm.setValue(80);
        bpm.setWrapSelectorWheel(false);

        play.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                Log.d("Aptic","BPM "+bpm.getValue());
                valore_bpm = Math.round((60.0/bpm.getValue())*1000.0);
                Log.d("Valore bmp millisecondi","BMP3 "+valore_bpm);
                if (stato == 0) {
                    play.setImageResource(R.drawable.stop_icon);
                    stato = 1;
                    startTime = System.currentTimeMillis();
                    //Toast.makeText(MainActivity.this, Long.toString(valore_bpm), Toast.LENGTH_SHORT).show();
                    timerHandler.postDelayed(timerRunnable, 0);
                }
                else
                {
                    play.setImageResource(R.drawable.play_icon);
                    stato = 0;
                    timerHandler.removeCallbacks(timerRunnable);

                }
            }
        });

    }

    public class MessageReceiver extends BroadcastReceiver {
        private static final String TAG = "MessageReceiver";

        @Override
        public void onReceive(Context context, Intent intent) {

            receivedMessage = intent.getStringExtra("message");
            Log.d("MessageReceiver", "onReceive() receivedMessage = "+receivedMessage);

            if (receivedMessage != null) {
                // Display message in UI
                message = receivedMessage;
                Log.d("MessageReceiver", "receivedMessage =" + receivedMessage);
                bpm.setValue(Integer.parseInt(receivedMessage));
            } else {
                receivedMessage = "No Message";
                Log.d("MessageReceiver", "receivedMessage = No Message");
            }


        }
    }




    @Override
    public void onEnterAmbient(Bundle ambientDetails) {
        super.onEnterAmbient(ambientDetails);
        updateDisplay();
    }

    @Override
    public void onUpdateAmbient() {
        super.onUpdateAmbient();
        updateDisplay();
    }

    @Override
    public void onExitAmbient() {
        updateDisplay();
        super.onExitAmbient();
    }

    private void updateDisplay() {
        if (isAmbient()) {
            mContainerView.setBackgroundColor(getResources().getColor(android.R.color.black));
            play.setVisibility(View.INVISIBLE);
        } else {
            mContainerView.setBackground(null);
            play.setVisibility(View.VISIBLE);
        }
    }




}
--------------------------------------

WearService
--------------------------------------
package com.luca_innocenti.apticmetro;

import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.WearableListenerService;

/**
 * Created by lucainnocenti on 05/01/17.
 */

public class WearService extends WearableListenerService {
    private static final String TAG = "WearService";

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        super.onDataChanged(dataEvents);
        Log.v(TAG, "onDataChanged" );
    }

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        super.onMessageReceived(messageEvent);
        Log.v(TAG, "onMessageReceived" );

        if (messageEvent.getPath().equals("/path")) {

            final String message = new String(messageEvent.getData());

            Log.d(TAG, "Message path received on watch is: " + messageEvent.getPath());
            Log.d(TAG, "Message received on watch is: " + message);

            // Broadcast message to wearable activity for display
            Intent messageIntent = new Intent();
            messageIntent.setAction(Intent.ACTION_SEND);
            messageIntent.putExtra("message", message);
            LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);

        }
        else {
            super.onMessageReceived(messageEvent);
        }
    }

}





Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...