venerdì 20 ottobre 2017

Foto ed imageview su Android

Aggiornamento: facendo delle prove con Nexus 5x e Nexus 9 ho scoperto che l'immagine risulta ruotata di 90° nonostante non ci siano modifiche nel codice
A questo link viene descritto il medesimo problema

Un sistema per una app che scatta una foto e mette il risultato in una imageview ed effettua il salvataggio (gestione dei permessi di scrittura non gestita..vedi post precedenti)



-----------------------------------------------
package com.example.lucainnocenti.photonotation;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;


public class MainActivity extends AppCompatActivity {
    private static final int CAMERA_REQUEST = 1888;
    private ImageView foto;
    private Bitmap ff;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        foto = (ImageView) findViewById(R.id.imageView);
        Button scatto = (Button) findViewById(R.id.button);


        scatto.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(camera, CAMERA_REQUEST);
            }
        });


    }
    protected void onActivityResult(int requestCode,int resultCode, Intent data)
    {
        if (requestCode== CAMERA_REQUEST && resultCode == Activity.RESULT_OK){
            ff = (Bitmap) data.getExtras().get("data");
            foto.setImageBitmap(ff);
            foto.setImageURI(data.getData());
            Bitmap bm=((BitmapDrawable)foto.getDrawable()).getBitmap();
            saveImageFile(bm);
        }

    }

    public String saveImageFile(Bitmap bitmap) {
        FileOutputStream out = null;
        String filename = getFilename();
        try {
            out = new FileOutputStream(filename);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.d("luca22","Errore");
        }
        return filename;
    }

    private String getFilename() {
        File file = new File(Environment.getExternalStorageDirectory()
                .getPath(), "TestFolder");
        if (!file.exists()) {
            file.mkdirs();
        }
        String uriSting = (file.getAbsolutePath() + "/"                + System.currentTimeMillis() + ".jpg");
        Log.d("luca22",uriSting);
        return uriSting;
    }
}

Azimuth Pitch e Roll su Android N

Gestione dei sensori con RotationMatrix su Android



--------------------------------------------------------------
package com.example.lucainnocenti.sensori;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity implements SensorEventListener{

    private SensorManager mSensorManager;
    private final float[] mAccelerometerReading = new float[3];
    private final float[] mMagnetometerReading = new float[3];

    private final float[] mRotationMatrix = new float[9];
    private final float[] mOrientationAngles = new float[3];
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;

    private double az;
    private double pi;
    private double ro;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);


    }

    @Override    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override    protected void onResume() {
        super.onResume();

        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);

    }

    @Override    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

    @Override    public void onSensorChanged(SensorEvent event) {

        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mAccelerometerReading, 0, mAccelerometerReading.length);
        }
        else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mMagnetometerReading, 0, mMagnetometerReading.length);
        }
        updateOrientationAngles();
    }


    public void updateOrientationAngles() {
        mSensorManager.getRotationMatrix(mRotationMatrix, null, mAccelerometerReading, mMagnetometerReading);
        mSensorManager.getOrientation(mRotationMatrix, mOrientationAngles);
        az = Math.toDegrees(mOrientationAngles[0]);
        pi = Math.toDegrees(mOrientationAngles[1]);
        ro = Math.toDegrees(mOrientationAngles[2]);
        Log.d("orienta", "Az:"+String.valueOf(az)+" Pi:"+String.valueOf(pi)+" Ro:"+String.valueOf(ro));

    }
}

GPS su Android N

Un esempio di uso del GPS su Android N con getione dei permessi. Evidenziate in giallo le parti di codice di gestione dei permessi


---------------------------------------------------
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.lucainnocenti.gpstest">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />


    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">
        <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>
---------------------------------------------------



---------------------------------------------------
package com.example.lucainnocenti.gpstest;

import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity implements LocationListener{

    LocationManager locationManager;
    String provider;
    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

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

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        provider = locationManager.getBestProvider(new Criteria(), false);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            checkLocationPermission();
            return;
        }
        Location location = locationManager.getLastKnownLocation(provider);

        if (location != null) {

            Log.i("Location Info", "Location achieved!");

        } else {

            Log.i("Location Info", "No location :(");

        }
    }

    @Override    protected void onResume() {
        super.onResume();

        if (checkLocationPermission()) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                locationManager.requestLocationUpdates(provider, 400, 1, this);
            }
        }

    }

    @Override    protected void onPause() {
        super.onPause();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            checkLocationPermission();
            return;
        }
        locationManager.removeUpdates(this);

    }

    @Override    public void onLocationChanged(Location location) {

        Double lat = location.getLatitude();
        Double lng = location.getLongitude();

        Log.i("Location info: Lat", lat.toString());
        Log.i("Location info: Lng", lng.toString());

    }

    @Override    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override    public void onProviderEnabled(String provider) {

    }

    @Override    public void onProviderDisabled(String provider) {

    }

    public void getLocation(View view) {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        Location location = locationManager.getLastKnownLocation(provider);

        onLocationChanged(location);


    }

    public boolean checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_FINE_LOCATION)) {


                new AlertDialog.Builder(this)
                        .setTitle("Permesso GPS")
                        .setMessage("Permesso GPS")
                        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            @Override                            public void onClick(DialogInterface dialogInterface, int i) {
                                //Prompt the user once explanation has been shown                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                        MY_PERMISSIONS_REQUEST_LOCATION);
                            }
                        })
                        .create()
                        .show();


            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
            }
            return false;
        } else {
            return true;
        }
    }

    @Override    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_LOCATION: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        locationManager.requestLocationUpdates(provider, 400, 1, this);
                    }

                } else {

                    // permission denied,

                }
                return;
            }

        }
    }
}

Scrittura JSON su Android N

Un esempio semplice per scrivere un file JSON e gestire in permessi di scrittura su Android 7 e successivi
Nel codice le parti in azzurro sono quelle relative alla gestione dei permessi mentre quelle in giallo sono per la gestione della creazione del JSON


---------------------------------------
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.lucainnocenti.jsontester">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />



    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">
        <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>

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


---------------------------------------
package com.example.lucainnocenti.jsontester;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.JsonWriter;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;


public class MainActivity extends AppCompatActivity {
    private int requestCode;
    private int grantResults[];
    private FileOutputStream out;
    private JsonWriter writer;
    private File card;
    private File file;

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

        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
        onRequestPermissionsResult(requestCode, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, grantResults);
        Button pulsante =(Button) findViewById(R.id.button);
        pulsante.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                card = Environment.getExternalStorageDirectory();
                file = new File (card.getAbsolutePath(),"dati.json");
                try {
                    out = new FileOutputStream(file);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                try {
                    writer = new JsonWriter(new OutputStreamWriter(out,"UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                try {
                    writer.beginObject();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    writer.name("nome").value("Luca");
                    writer.name("cognome").value("Innocenti");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                try {
                    writer.endObject();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                ;


            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {

                // If request is cancelled, the result arrays are empty.                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    Log.d("permission", "granted");
                } else {


                    Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();

                    onDestroy();
                }
                return;
            }
        }
    }
}

giovedì 19 ottobre 2017

Bash ftp script

uno script bash per inviare dati in FTP
un paio di dettagli

  1. per usare le wildcard si devono i comandi mdel ed mput
  2. Per usare mput con la wildcard ci si deve prima spostare nella directory in cui sono contenuti i file mediante lcd perche' mput non permette di inserire il path completo ma solo il nome file
  3. ftp -ni indica una sessione non interattiva e in modalita' autologin
  4. quote serve ad inviare il contenuto della variabile al server remoto
------------------------------------------------------------------------------
#!/bin/sh
HOST="ftp.xxxxxxxxx.it"
USER="xxxxxxxx@aruba.it"
PASSWD="xxxxx"

ftp -ni $HOST<<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
cd xxxxxx/yyyy/zzzzz/
mdel *
lcd /home/luca/
binary
mput *.ics
quit
END_SCRIPT
exit 0


SSH e disconnessione sessione

Succede piuttosto spesso di dover utilizzare una connessione remota in SSH e lanciare dei comandi (tipicamente delle query). Tipicamente quando si chiude una sessione ssh si uccidono anche tutti i processi che si erano aperti nella sezione. Per risolvere questo problema viene in aiuto il comando nohup

ssh luca@ip.ip.ip.ip "nohup /home/luca/comando> /dev/null 2>&1 &"

con la sintassi sopra riportata si lancia comando sia SSH senza che il suo processo venga chiuso al termine della sessione

FTP Client su Midnight Commander

A volte puo' essere utile avere un client FTP che funzioni su una shell testuale, in particolare quando si usa una connessione SSH. Una soluzione molto comoda e' quella di utlizzare Midnight Commander

Per prima cosa si deve creare e popolare il file netrc

touch ~/.netrc
chmod 600 ~/.netrc
nano ~/.netrc

A questo punto si inseriscono le configurazioni di connessione al server FTP con la sintassi

machine ftp.test.it login luca password test

a questo punto si apre Midnight Commander, Left (o Right) -> FTP Link e si digita l'indirizzo del server FTP. In questo modo in uno dei due pannelli viene mostrato il contenuto della directory FTP



mercoledì 11 ottobre 2017

SSTV


Slow Scan Television e' un metodo per inviare immagini/video utilizzando lo stesso canale radio impiegato anche per le comunicazioni voce ed ha origini che si perdono agli albori dell'esplorazione spaziale per inviare immagini dalle sonde verso Terra (anche le prime missioni Apollo utilizzavano SSTV)



La cosa divertente e' che oggi con due semplici terminali Android si puo' effettuare la codifica e decodifica di immagini in SSTV con le applicazioni gratuite SSTV Encoder e Robot36 (che e' il nome di uno dei formati previsti)

Il formato dati e' variabile in dimensione e numero di colori..una immagine in bianco e nero di 120x120 pixel impiega al minimo 8 secondi per essere trasmessa (e ricevuta)



Attualmente e' possibile ricevere immagini via SSTV dalla stazione spaziale internazionale


martedì 10 ottobre 2017

Draft su Lyx

Qui viene indicato come inserire in filigrana una scritta (tipicamente Draft) su un documento editato con Lyx

Qui si inizia scaricando il  pacchetto da qui. Si decomprime e si lancia il file Make...su Centos 7 per terminare correttamente la compilazione e' necessario oltre al pacchetto Lyx anche gv (ghostview)




al termine si copiano i file draftcopy.sty e draftcopy.cfg nella stessa directory dove si trova il file che si sta editando

si modifica quindi il Latex Preamble in Lyx menu Document/Settings/LaTex Preamble con il codice
\usepackage{draftcopy}

per ottenere il risultato si deve fare il preview con pdflatex


lunedì 9 ottobre 2017

Modificare grandezza delle iconde desktop di Centos 7

Le icone sul desktop di Centos 7 sono fastidiosamente grandi, indipendentemente dalla risoluzione. Come si risolve ?? cosi'

 gsettings set org.gnome.nautilus.icon-view default-zoom-level small

per creare uno shortcut sul desktop di una applicazione la via piu' semplice e' copiare il file .desktop da /usr/share/applications/ in /home/user/Desktop

venerdì 6 ottobre 2017

Piu' o meno.....

..... stavo lavorando sulla stessa idea un anno e mezzo fa


bravo a chi e' riuscito a passare dall'idea alla realizzazione e soprattutto alla validazione

giovedì 5 ottobre 2017

Giocando con Emacs

puo' essere cervellotico usare emacs...ma alla fine impazzisci ed inizi ad apprezzarlo

M indica il tasto Meta che sui PC e' tasto ALT di sinistra
C indica il tasto CTRL

Per creare un nuovo file C-x C-f e poi si digita il nome del nuovo file. Si aprira' quindi un buffer.

Per aprire un file esistente C-x C-f poi si puo' digitare il nome oppure si digita Enter e si aprira' un mini file manager da cui selezionare il file desiderato

Per salvare il file C-x C-s

Per selezionare e fare copia/incolla si seleziona mediante C + Spazio per iniziare la selezione e poi con le frecce si seleziona l'area desiderata.
Per fare copia si preme M+W.
Per incollare (Yank nel linguaggio Emacs) C+y

Per effettuare la ricerca di una stringa C+s
Per fare search and replace M-%

Per spostarsi tra i vari buffer aperti (che sarebbero il corrispondente dei tab sugli editor moderni)
C+ x freccia destra
C + x freccia sinistra

per chiudere un buffer che non server piu'
C + x k

per aprire una shell in un buffer
M + x shell
per aprire una shell e contemporaneamente lanciare un comando
M + !  [comando]


Emacs ha il proprio gestore dei pacchetti per le estensioni (ELPA e MELPA). Per abilitare MELPA su Centos 7 si deve creare il file .emacs nella propria home e si aggiungono le seguenti righe

------------------------------------------------------------------
(require 'package) ;; You might already have this line
(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                    (not (gnutls-available-p))))
       (url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
  (add-to-list 'package-archives (cons "melpa" url) t))
(when (< emacs-major-version 24)
  ;; For important compatibility libraries like cl-lib
  (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize) ;; You might already have this line
--------------------------------------------------------------------


Per ottenere la lista ELPA dei plugin di Emacs si digita

M-x list-packages

a questo punto scorrendo la lista facendo Enter si entra nella scheda dell'estensione che si apre come un nuovo buffer. Dentro questo si trova il pulsante Install

Per rimuovere una estensione di riapre di nuovo la lista di ELPA, si cerca la riga desiderata (si puo' fare la ricerca con C-s come stringa); una volta trovato si digita d (per marcare per la cancellazione) e poi x (per la cancellazione)

Web development
si apre in un buffer la pagina html che si vuole modificare. Si digitando quindi i due comandi in successione

M-x httpd-start
M-x impatient-mode

si apre quindi il browser e si punta al seguente indirizzo

http://localhost:8080/imp/

qui si troveranno elencati i buffer html aperti in emacs. Cliccando si apre la pagina. Ogni modifica fatta su Emacs viene immediatamente mostrata sul browser. Uno dei problemi che ho notato e' che la modifica avviene in una porzione della pagina fuori dallo schermo (per esempio in basso su una schermata molto lunga) si viene riportati sempre alla testa della pagina

JSON development
M-x package-install Enter
json-mode Enter

per aprire il modo (come per tutti i modi maggiori)
M-x json-mode

per formattare poi i campi in modo che siano leggibili
C-c C-f

Python development
M-x python-mode
C-c C-z apre una shell pyton
C-c C-c esegue lo script nel buffer selezionato

per vedere i risultati si deve cercare il buffer dove ci sono i risultati dello script con C-x freccia destra/sinistra