lunedì 5 novembre 2012

Array a dimensione variabile in Android

Uno degli aspetti piu' divertenti dei linguaggi di programmazionee evoluti e' la possibilita' di gestire degli array a dimensione non predefinita (a partire dalla STL di C++)

In Java ed Android vi sono ben due possibilita' date dal formato Vector ed ArrayList

Nei due esempi gli array vengono popolati con i valori della funzione Seno.
Dal punto di vista operativo le differenze sono veramente minime.
  1. i metodi del Vector sono sincroni mentre gli ArrayList non sono sincroni
  2. i Vector sono thread-safe ma sono piu' lenti nell'aumentare le dimensioni
  3. ad ogni add Vector raddoppia le dimensioni disponibili mentre ArrayList aumenta le dimensioni di meta' della propria dimensione

Vettore
-------------------------------------------------------
v = new Vector<Float>();
for (int t=0;t<360;t++)
        {
            v.add((float) Math.sin(Math.toRadians(t)));
        }
int length = v.size();
Log.d("lenght_t", Integer.toString(length));

-------------------------------------------------------
ArrayList
-------------------------------------------------------
al = new ArrayList<Float>();
for (int s=0;s<360;s++)
        {
            al.add((float) Math.sin(Math.toRadians(s)));
        }
length_s = al.size();
Log.d("length_s", Integer.toString(length_s));
Iterator<Float> it = al.iterator();
    while (it.hasNext()) {
            System.out.println("Data is "+ it.next());
    }

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

domenica 4 novembre 2012

Personalizzare Nautilus

Una delle cose che non mi e' mai piaciuta di Nautilis e' l'interfaccia stile Explorer di Windows con la lista di una sola directory per ogni finestra...considero decisamente piu' funzionale l'interfaccia tipo Norton



In realta' con la 'sola pressione del tasto F3 si riesce ad avere una visione a due finestre affiancate 



mentre con il tasto F9 si fa apparire e scomparire la colonna delle directory predefinite di destra (alla colonna delle directory predefinite si possono aggiungere elementi tramite il drag and drop)



venerdì 2 novembre 2012

Creare grafici con AChartEngine in Android

Un altro metodo per creare grafici con Android e' quello di impiegare la libreria AChartEngine

Il problema con questa libreria e' che sostanzialmente priva di esempi e non e' cosi' immediato usarla
Si possono trovare dei video tipo questo


ma se si prova a seguire l'esempio il programma genera sempre un'eccezione

il trucco e' che in modo preliminare si devono modificare project.properties e Manifest.xml cosi' come evidenziato in giallo

project.properties
------------------------------------------------
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-15
manifestmerger.enabled=true 

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


Manifest.xml
------------------------------------------------
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.graph2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

------------------------------------------------
Dopo di cio' si puo' iniziare a scrivere il codice
Di fatto il grafico vive in una sua finestra per cui va lanciato mediante Intent

MainActivity
------------------------------------------------
package com.test.graph2;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
   
    public void lineGraphHandler (View view)
    {
        LineGraph line = new LineGraph();
        Intent lineIntent = line.getIntent(this);
        startActivity(lineIntent);
    }

}

------------------------------------------------
Per il resto il codice per generazione del grafico e' piuttosto autoesplicativa

LineGraph.java
------------------------------------------------
package com.test.graph2;

import org.achartengine.ChartFactory;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;

public class LineGraph {
public Intent getIntent(Context context) {
       
        // Our first data
        int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // x values!
        int[] y =  { 30, 34, 45, 57, 77, 89, 100, 111 ,123 ,145 }; // y values!
        TimeSeries series = new TimeSeries("Line1");
        for( int i = 0; i < x.length; i++)
        {
            series.add(x[i], y[i]);
        }
       
        // Our second data
        int[] x2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // x values!
        int[] y2 =  { 145, 123, 111, 100, 89, 77, 57, 45, 34, 30}; // y values!
        TimeSeries series2 = new TimeSeries("Line2");
        for( int i = 0; i < x2.length; i++)
        {
            series2.add(x2[i], y2[i]);
        }
       
        XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
        dataset.addSeries(series);
        dataset.addSeries(series2);
       
        XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer(); // Holds a collection of XYSeriesRenderer and customizes the graph
        XYSeriesRenderer renderer = new XYSeriesRenderer(); // This will be used to customize line 1
        XYSeriesRenderer renderer2 = new XYSeriesRenderer(); // This will be used to customize line 2
        mRenderer.addSeriesRenderer(renderer);
        mRenderer.addSeriesRenderer(renderer2);
       
        // Customization time for line 1!
        renderer.setColor(Color.WHITE);
        renderer.setPointStyle(PointStyle.SQUARE);
        renderer.setFillPoints(true);
        // Customization time for line 2!
        renderer2.setColor(Color.YELLOW);
        renderer2.setPointStyle(PointStyle.DIAMOND);
        renderer2.setFillPoints(true);
       
        Intent intent = ChartFactory.getLineChartIntent(context, dataset, mRenderer, "Line Graph Title");
        return intent;
       
    }
}
 

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

Plugin Android per Eclipse

Al momento attuale esistono diversi plugin per Android o meglio diversi pacchetti

Scaricando il Google Plugin si ha oltre al necessario per sviluppare Android in Eclipse anche la possibilita' di scaricare l'SDK di Android e GWT ed AppEngine

Invece a questo link si trova il solo pacchetto ADT in cui e' presente il solo plugin Android per Eclipse. L'SDK dovra' essere scaricato a parte


martedì 30 ottobre 2012

Disegnare grafici in Android con GrahView

Un'altra libreria (oltre alla gia' citata AndroidPlot) per disegnare grafici su Android e' GraphView

Rispetto alla precedente e' meno commentata ed di utilizzo un po' piu' difficile ma permette di mostrare dati in realtime ed ha lo zoom ed il pan dinamico mediante gesture

Un po' di indicazioni: il tutorial sul sito dello sviluppatore funziona solo con la versione 2.0 (al momento della scrittura di questo post la versione piu' recente e' la 3.0); per questo motivo anche io ho usato la versione 2

Inoltre di default i colori delle label sugli assi delle ascisse e delle ordinate ed il titolo sono bianchi per cui iniziando un progetto da zero con il nuovo SDK si deve cambiare il colore di background della activity (che gia' di suo e' bianco) altrimenti scompare tutto

-------------------------------------------
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     android:background="#000000" >

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/graph1" />
       
</RelativeLayout>

-------------------------------------------
Usando il codice sotto riportato (un misto tra il codice di esempio ed alcune righe che ho inserito io)  si ha come risultato questa immagine




-------------------------------------------
package com.test.graph;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Menu;
import android.widget.LinearLayout;

import com.jjoe64.graphview.GraphView.GraphViewData;
import com.jjoe64.graphview.GraphView.GraphViewSeries;
import com.jjoe64.graphview.GraphView.LegendAlign;
import com.jjoe64.graphview.LineGraphView;

public class MainActivity extends Activity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        int num = 150; 
        GraphViewData[] data = new GraphViewData[num]; 
        double v=0; 
        for (int i=0; i<num; i++) { 
           v += 0.2; 
           data[i] = new GraphViewData(i, Math.sin(v)); 
        } 
        GraphViewSeries seriesSin = new GraphViewSeries("Seno", Color.rgb(200, 50, 00), data); 
       
        //attenzione l'array dei dati deve essere completo
        //se si omette per esempio di dichiarare dati[4] il programma genera una eccezione
        GraphViewData[] dati = new GraphViewData[5];
        dati[0] = new GraphViewData(0,0);
        dati[1] = new GraphViewData(10,0.5);
        dati[2] = new GraphViewData(15,1.5);
        dati[3] = new GraphViewData(17,0.7);
        dati[4] = new GraphViewData(22,0.7);

       
        GraphViewSeries seriedati = new GraphViewSeries("Misure", Color.rgb(0, 250, 00), dati);
       
        LineGraphView graphView = new LineGraphView( 
              this 
              , "Titolo Grafico" 
        );
       
        // aggiungi la serie dati
        graphView.addSeries(seriesSin);
        graphView.addSeries(seriedati); 
     
        // finestra di visualizzazione del grafico 
        graphView.setViewPort(0, 20); 
        graphView.setScrollable(true); 
        graphView.setScalable(true); 
       
        // Legenda 
        graphView.setShowLegend(true); 
        graphView.setLegendAlign(LegendAlign.BOTTOM); 
        graphView.setLegendWidth(70);
         
        LinearLayout layout = (LinearLayout) findViewById(R.id.graph1); 
        layout.addView(graphView); 
    }

  

venerdì 26 ottobre 2012

Errore su Toast in Android

Un esempio di come puo' avere dei trabocchetti la programmazione su Android anche su cose semplici come la creazione di un widget Toast



Nel referenziare il context del comando Toast.maketext e' necessario riportare il nome della activity in cui si sviluppa il comando (in questo caso MainActivity) altrimenti si genera un errore
   
------------------------------------------------------
btngraph.setOnClickListener(new View.OnClickListener() {
               private Toast toast;
                public void onClick(View v) {

                       // Questo genera un errore
 
                        toast = Toast.makeText(this, R.string.errore, Toast.LENGTH_LONG);
 
                       // Questo NON genera un errore                         toast = Toast.makeText(MainActivity.this, R.string.errore, Toast.LENGTH_LONG);
 


                       toast.show();
                    }

Marida Marine Debris Archive

Sto provando ad utilizzare Marida, un archivio di immagini supervisionate di Sentinel 2, raccolte in area non mediterranea con 15 categorie ...