Visualizzazione post con etichetta Wear. Mostra tutti i post
Visualizzazione post con etichetta Wear. Mostra tutti i post

mercoledì 12 aprile 2017

Android Wear 2.0

Finalmente e' arrivato l'aggiornamento di Android Wear 2 sul mio LG R...e' quindi tempo di provare le nuove applicazioni per Android Wear che non hanno piu' bisogno dell'app companion sul telefono


Ho quindi preso un vecchio progetto (Aptic Metronome) di Wear 1 per adattarlo ad Wear 2
E' sufficiente in Android Studio crea un progetto per solo Android Wear con un targetSDKVersion pari a 25 (anche la minSDKVersion deve corrispondere a 25 per il solo Android Wear)

Per istruire il Play Store che l'apk non ha un app companion in AndroidManifest.xml e' necessario indicare

<meta-data    android:name="com.google.android.wearable.standalone"
android:value="true" /> 

Fatto cio' il progetto e' compatibile per l'upload su PlayStore. La preparazione su PlayStore e' identica a quella di Wear 1 con la conseguente revisione da parte di Google

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);
        }
    }

}





giovedì 10 settembre 2015

DIY HomeKit con Android Wear e Raspberry

Questo e' un tentativo di realizzare un homekit, un sistema di domotica, che permetta di accendere dei dispositivi con un sensore di prossimita' (tipo il lampadario quando si entra in una stanza)

I componenti di questo kit sono
1) un orologio con Android Wear
2) un Raspberry (qualsiasi modello) con un dongle Bluetooth LE
3) un rele



L'orologio e' stato programmato come emettitore di beacon (e' possibile modificare il valore del minor in modo da personalizzarlo)


Di seguito il codice Android

--------------------------------------
apply plugin: 'com.android.application'

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

final def var = repositories {
    jcenter{
        url "http://jcenter.bintray.com/"    }
}
var

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.support:wearable:1.2.0'    compile 'com.google.android.gms:play-services-wearable:7.5.0'}
dependencies {
    compile 'org.altbeacon:android-beacon-library:2+'
} 

--------------------------------------

--------------------------------------
package luca_innocenti.beacontrasmitter;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.pm.PackageManager;

import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.BeaconTransmitter;
import org.altbeacon.beacon.Identifier;

import java.util.Arrays;


@TargetApi(21)
public class MainActivity extends Activity {

    private BeaconTransmitter mBeaconTransmitter;
    private TextView testo;
    private SeekBar barra;
    private Button pulsante;
    private int stato;
    private TextView testo2;
    private TextView testo3;


    private void trasmetti(){
        if (checkPrerequisites()) {
            //            //mBeaconTransmitter = new BeaconTransmitter(this, new BeaconParser().setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));            mBeaconTransmitter = new BeaconTransmitter(this, new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
            //beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));  // iBeacons
            //beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));      // Estimotes
            //beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=a7ae2eb7,i:4-19,i:20-21,i:22-23,p:24-24"));  // easiBeacons
            // uuid estimote B9407F30-F5F8-466E-AFF9-25556B57FE6D
            Beacon beacon = new Beacon.Builder()
                    .setId1("B9407F30-F5F8-466E-AFF9-25556B57FE6D")
                    .setId2("999")
                    .setId3(testo.getText().toString())
                    .setManufacturer(0x015D) // Simula Estimote                    .setTxPower(-59)
                    .setDataFields(Arrays.asList(new Long[]{0l}))
                    .build();

            mBeaconTransmitter.startAdvertising(beacon);
            stato = 1;
        }

    }

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



        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override            public void onLayoutInflated(WatchViewStub stub) {
                barra = (SeekBar) stub.findViewById(R.id.seekBar);
                testo = (TextView) stub.findViewById(R.id.textView);
                testo2 = (TextView) stub.findViewById(R.id.textView2);
                testo3 = (TextView) stub.findViewById(R.id.textView3);
                pulsante = (Button) stub.findViewById(R.id.button);


                barra.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                                                     @Override                                                     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                                                         testo.setText(String.valueOf(new Integer(progress)));
                                                     }

                                                     @Override                                                     public void onStartTrackingTouch(SeekBar seekBar) {

                                                     }

                                                     @Override                                                     public void onStopTrackingTouch(SeekBar seekBar) {

                                                     }
                                                 }
                );

                pulsante.setOnClickListener(new View.OnClickListener() {
                    @Override                    public void onClick(View v) {
                        testo2.setText("Trasmitter ON");
                        testo3.setText("B9407F30-F5F8-466E-AF\nF9-25556B-57FE6D-999-"+testo.getText());
                        pulsante.setEnabled(false);
                        barra.setEnabled(false);
                        trasmetti();
                    }
                });
            }
        });
    }


    @Override    protected void onDestroy() {
        super.onDestroy();
        if (stato == 1) {
            mBeaconTransmitter.stopAdvertising();
        }
    }

    @TargetApi(21)
    private boolean checkPrerequisites() {

        if (android.os.Build.VERSION.SDK_INT < 18) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth LE not supported by this device's operating system");
            builder.setMessage("You will not be able to transmit as a Beacon");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;
        }
        if (!getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth LE not supported by this device");
            builder.setMessage("You will not be able to transmit as a Beacon");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;
        }
        if (!((BluetoothManager) getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter().isEnabled()){
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth not enabled");
            builder.setMessage("Please enable Bluetooth and restart this app.");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;

        }

        try {
            // Check to see if the getBluetoothLeAdvertiser is available.  If not, this will throw an exception indicating we are not running Android L            ((BluetoothManager) this.getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter().getBluetoothLeAdvertiser();
        }
        catch (Exception e) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Bluetooth LE advertising unavailable");
            builder.setMessage("Sorry, the operating system on this device does not support Bluetooth LE advertising.  As of July 2014, only the Android L preview OS supports this feature in user-installed apps.");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override                public void onDismiss(DialogInterface dialog) {
                    finish();
                }

            });
            builder.show();
            return false;

        }

        return true;
    }
}

--------------------------------------
Per leggere la prossimita' dell'orologio ho montato sulla Raspberry un dongle Broadcome (gia' visto qui) ed il programma in Python iBeacon-Scanner (Github) leggermente modificato

Il programma cicla fino quando non vede un dispositivo con minor=1, allora controlla l'Rssi e stima la distanza. Se la distanza e' inferiore ad un determinato valore si puo' agire sulle porte GPIO ed attivare il rele' (funzione da implementare ma di facilissima realizzazione)

--------------------------------------
import blescan
import sys

import bluetooth._bluetooth as bluez

dev_id = 0
try:
    sock = bluez.hci_open_dev(dev_id)
    #print "ble thread started"

except:
    print "error accessing bluetooth device..."
        sys.exit(1)

blescan.hci_le_set_scan_parameters(sock)
blescan.hci_enable_le_scan(sock)

while True:
    returnedList = blescan.parse_events(sock, 10)
    #print "----------"
    for beacon in returnedList:
        #print beacon
        valori = beacon.split(",")
        mac = valori[0]
        uuid = valori[1]
        major = valori[2]
        minor = valori[3]
        rssi = valori[4]
        rssi2 = valori[5]
        #print minor
        if (minor == "1"):
            #print minor+" "+rssi2
            if (int(rssi2) > -75):
                print "vicino"
            else:
                print "lontano"
--------------------------------------

giovedì 18 giugno 2015

Disinstallare applicazioni da Android Wear

Per disinstallare applicazione da Android Wear non esiste un sistema integrato all'interno dell'orologio.




Se si ha l'applicazione/installer sul telefono basta agire sul telefono che la modifica si replica anche sull'orologio ma se si sta per esempio sviluppando una applicazione in proprio questa strada non risulta applicabile

Ci viene quindi in aiuto adb ma si deve conoscere il nome reale del pacchetto installato (e non il nome dell'applicazione)

Per listare le applicazioni installazione sull'orologio si puo' digitare

adb shell
pm list packages

diciamo che il pacchetto che si vuole disinstallare luca_innocenti.soundwear si esce dalla shell e si digita

adb uninstall luca_innocenti.soundwear

queste istruzioni funzionano se l'orologio e' collegato via USB (ovvero se e' collegato sulla sua basetta). Se invece il debug e' avviato via bluetooth si deve procedere con


adb forward tcp: 4444 local abstract: / adb hub 
adb connect localhost: 4444 
adb devices a
db-s localhost: 4444 shell 
pm list packages 
adb -s localhost: 4444 uninstall luca_innocenti.soundwear

lunedì 15 giugno 2015

Android Wear con Eclipse


Ho un vecchio progetto (vecchio per modo di dire ... ma nell'informatica un anno ha una valenza un po' particolare) in Eclipse a cui volevo aggiungere il supporto ad Android Wear senza trasportare tutto in Android Studio

La procedura per impostare l'ambiente di sviluppo non e' molto lineare e deriva da quanto descritto a questo link

Per prima cosa da Sdk Manager deve essere aggiunto il Google Repository


Una volta terminato il download si deve andare nella directory del proprio SDK ed in particolare in

./extras/google/m2repository/com/google/android/support/wearable/1.0.0/wearable-1.0.0.aar
copiare il file .aar, rinominarlo in .zip e decomprimerlo (attenzione esiste anche un file wearable-1.0.0.jar da non usare)
Dopo lo scompattamento si entra nella cartella, si crea un directory libs e vi si copia il file classes.jar



Si apre quindi Eclipse e si importa la directory con File/New/Project/Android Project From Existing Code
Dopo l'importazione si clicca destro sulla directory wearable-1.0.0. /Properties/Android, si flagga IsLibrary, Apply, Ok e da questo punto in poi e' stato aggiunto il supporto di Android Wear ad Eclipse



Per aggiungere il supporto ad Android Wear ad un progetto si clicca sulle proprieta' del progetto/Android e si aggiunge la libreria wereable




mercoledì 26 marzo 2014

Android Wear

Dopo aver modificato il telefono per avere un dispositivo ad Android 4.4, ho provato Android Wear, la versione per i futuri Smart Watch di Google.

Al momento e' disponibile solo una developer preview (per cui bisogna essere registrati) all'interno dell'emulatore

Sul telefono si installa l'applicazione Android Wear Preview App mentre dall'Android SDK Manager si deve scaricare Android Wear ARM EABI v7a System Image.


e si crea una nuova macchina virtuale AVD basata sull'immagine di Android Wear

A questo punto si esegue l'emulatore, si connette il telefono via USB e si attiva l'applicazione sul telefono.
Al computer si digita quindi il comando

adb -d forward tcp:5601 tcp:5601

l'applicazione sul telefono mostra lo stato di connessione e l'icona sull'emulatore mostra lo stato di connessione.
Per generare quindi una notifica ho effettuato una telefonata al cellulare e sul display dello Smart  Watch e' comparsa la notizia

Di fatto il sistema reagisce sostanzialmente alle notifiche che gli  derivano dal telefono a cui e' accoppiato.
Non e' necessario che le notifiche siano di sistema. Si puo' creare una applicazione che generi notifiche e queste vengono instradate verso lo smartwatch


Per esempio il codice sottostante genera una piccola applicazione che lancia una notifica all'avvio (codice modificato dal post originale, da notare che il codice originale non era stato concepito per Android Wear a dimostrazione di come si possa importare semplicemente codice relativo ad altre API)
Per compilare il codice e' necessario inserire tra le librerie wereable-preview-support.jar tra le Referenced Libraries
-----------------------------------------------------------------------------
package com.wear.orologio;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;


public class MainActivity extends Activity {

NotificationManager notificationManager;
Notification myNotification;
private static final int MY_NOTIFICATION_ID=1;
private final String myBlog = "http://www.google.com/";



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

Context context = getApplicationContext();
   Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(myBlog));
   PendingIntent pendingIntent = PendingIntent.getActivity(
     MainActivity.this, 
     0, 
     myIntent, 
     Intent.FLAG_ACTIVITY_NEW_TASK);
     
   myNotification = new Notification.Builder(context)
         .setContentTitle("Notifica")
         .setContentText("Dal Luca Innocenti")
         .setTicker("Notifica")
         .setWhen(System.currentTimeMillis())
         .setContentIntent(pendingIntent)
         .setDefaults(Notification.DEFAULT_SOUND)
         .setAutoCancel(true)
         .setSmallIcon(R.drawable.ic_launcher)
         .build();
   
   notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
   notificationManager.notify(MY_NOTIFICATION_ID, myNotification);


    }

}

-----------------------------------------------------------------------------
Ma Android Wear sara' solo notifiche???
Non sembra in quanto sull'emulatore dello Smart Watch funziona tranquillamente Hello World per cui il dispositivo sembra avere una propria autonomia dal telefono








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...