Let’s call it inspiration

If this comes to official repositories, we could say that eventually Gnome stopped copying from MacOSX and started copying from Unity.

Firefox 5 landed in Ubuntu Natty

A beta version of Firefox 5 (seems a b5pre) has just landed in the natty-proposed repository. Good thing that Ubuntu decided to stay up to date with Firefox.

Using GestureDetector to detect Long Touch, Double Tap, Scroll or other touch events in Android

Most of the Android UI elements already come with some easy way to detect and handle touch events. For example have a look to the following code:

TextView myTextView = (TextView) findViewById(R.id.myTextView);
myTextView.setOnLongClickListener(new OnLongClickListener() {
	@Override
	public boolean onLongClick(View v) {
		Log.i("MyExample", "A Long Click has been detected");
		return true;
	}
});

When you touch the myTextView long enough, you will see in the logs the print A Long Click has been detected.
In other cases, however, in which this kind of solution is not available, or doesn’t fit your needs. For example

  • the UI element does not let you set a listener for the action you want to detect. You can’t set a double click listener for a TextView widget, and other elements, like the Map Overlay, can only detect a very limited set of actions;
  • you need more information about the action, e.g. the exact position of the pointer (finger).

In those cases the best solution is to use the GestureDetector.

The GestureDetector works a little bit differently from what you may be used to. In fact it is not listening to the actions: it is in charge of translating what a widget or another UI element sees as a generic touch event, to a more specific action. Fortunately any UI element gives you some way to handle a generic touch event.

Let’s see a complete example of how to put the GestureDetector to work within a simple Activity class.

package com.example;
 
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
 
public class GestureDetectorExample extends Activity {
    static private String TAG = "GestureDetectorExample";
    private GestureDetector mGestureDetector;
    private TextView mTextView;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        mTextView = (TextView) findViewById(R.id.myTextView);
        mTextView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });
 
        mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
            @Override
            public void onLongPress(MotionEvent e) {
                Log.d(TAG, "Long Press event");
            }
 
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                Log.d(TAG, "Double Tap event");
                return true;
            }
 
            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }
        });
        mGestureDetector.setIsLongpressEnabled(true);
    }
}

Let’s see now what happens in the example:

  • a TouchListener is set for the TextView;
  • a GestureDetector object is instantiated, with a reference to an object which implements the OnGestureListener interface (we’ll come back on this later);
  • when a touch event is detected by the TextView, the method onTouch is called;
  • the method onTouch calls the GestureDetector and pass it the MotionEvent, an object containing the information needed by the GestureDetector to recognize the different touch events;
  • the GestureDetector uses the MotionEvent object to identify the touch events;
  • once identified the type of the event, the GestureDetector calls the appropriate method of the OnGestureListener (double tap, long press, etc.).

It’s time to run the program and perform some long tap, or double click on the TextView while keeping an eye on the logs in the LogCat.

A couple of notes.

  • The onDown method.
    If you try to remove it you will see that the onDoubleTap method is not called anymore. Same if the onDown method returns false. So keep in mind that to make onDoubleTap work you must have a onDown method returning true.
  • SimpleOnGestureListener class vs OnGestureListener interface
    In the example, the SimpleOnGestureListener class is used. It is a commodity class that implements the OnGestureListener interface. If you decide to implement the OnGestureListener interface you must implement all its methods, even you only need to handle one event. When you inherit from the SimpleOnGestureListener, instead, you will only override the methods you need.

Let’s now see another example, this time using the Overlay from the Google Maps API.

package com.example;
 
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
 
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
 
public class GestureDetectExampleMap extends MapActivity {
    private static String TAG = "GestureDetectorExampleMap";
    MapView mMapView;
    GestureDetector mGestureDetector;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        mMapView = (MapView) findViewById(R.id.MapView);
 
        mMapView.getOverlays().add(new Overlay() {
            @Override
            public boolean onTouchEvent(MotionEvent e, MapView mapView) {
                mGestureDetector.onTouchEvent(e);
                return super.onTouchEvent(e, mapView);
            }
        });
 
        mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
            @Override
            public void onLongPress(MotionEvent e) {
                Log.d(TAG, "Long Press event");
            }
 
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                Log.d(TAG, "Double Tap event");
                return true;
            }
 
            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }
        });
    }
 
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

The GestureDetector part is exactly the same, but in this case the GestureDetector.onTouchEvent is called by the map Overlay, and unlike a generic View element, there is no need to instantiate a Listener for it.
A touch event will go through the following steps:

  • the touch event triggers the onTouchEvent inside the Overlay;
  • the onTouchEvent of the Overlay calls the correspondent method of the GestureDetector and pass it the MotionEvent, an object containing the information needed by the GestureDetector to recognize the different touch events;
  • the GestureDetector uses the MotionEvent object to identify the touch events;
  • once identified the type of the event, the GestureDetector calls the appropriate method of the OnGestureListener (double tap, long press, etc.).

For lazy people only: download a zip file with the two examples.

It may be useful for you to have a look to a few articles that I also consulted before writing this article:

Feel free to comment to ask any question, correct any mistake or suggest any improvement.

C++

Sono sempre più convinto che Bjarne Stroustrup abbia qualche disturbo associativo che gli impedisce di scrivere libri in maniera ordinata o creare linguaggi di programmazione in cui la complicazione delle operazioni più semplici sembra essere la norma più che l’eccezione.

H.264, che confusione

Macity prende un po’ di cantonate sull’H.264 quando dice che:

«MPEG LA rende lo standard H.264 royalty-free»
Titolo d’effetto ma vero solo in parte: non pagherà diritti e brevetti solo chi lo userà a titolo gratuito. E poi ci mancherebbe altro che se metto un video in H.264 sul mio blog (che non abbia pubblicità, per carità di Dio!) debba anche pagare qualcuno. Pensate, a titolo d’esempio, se Tim Berners-Lee avesse deciso di dare via il Web nella stessa maniera.

«non verranno mai richieste royalties a chi utilizzerà il codec per produrre e distribuire filmati gratuiti per l’utente finale.»
Produrre video? H.264 viene usato solo in fase di distribuzione. Quando ci lavori sopra ci lavori sempre in formati non compressi. Se poi qualcuno si è sbagliato e ha scritto “produrre” invece di “registrare”, allora mi scuso io per non aver capito una vostra improprietà di linguaggio. E comunque mi piacerebbe trovare una telecamerina che registri in H.264 che mi venga fornita a titolo gratuito.

«L’annuncio del consorzio conferma nell’H.264 il formato di riferimento per l’HTML5 e allontana i potenziali sostenitori dell’Ogg Theora, il formato open-source fortemente voluto da Mozilla.»
Il formato non è fortemente voluto da Mozilla ma anche da giganti del calibro di Google, che è poi anche il padrone di Youtube. E poi, cari amici di Macity (l’articolo l’ha scritto Mauro Notarianni) siete rimasti indietro: è da un po’ che abbiamo WebM il quale, nel caso non vi foste giunta voce, è qualcosa in più di un codec video. Voi continuate pure a giocherellare con le vostre dita su schermi luccicanti. Se non vi scoccia troppo, nel frattempo noi andremmo avanti.

Partita a tre

A guardare il video seguente mi viene in mente che:

  • al diavolo le app, è il browser che conta;
  • Windows Mobile 7 va davvero bene;
  • Symbian non se lo caga più nessuno, tra un po’ nemmeno Nokia;
  • la partita si giocherà a tre: Linux (leggi: Android, Meego, etc.), Windows Mobile, ed Apple;
  • se Google smette di spingere su Android, Linux farà una brutta fine anche sul mobile.

iPhone4

Andato a cena con nuovi amici, chiedo a uno di loro come si trova col nuovo iPhone 4. Bene, mi dice.
È vera tutta la faccenda dell’antenna? Sì, è vera.
E la batteria come va? Peggio del 3GS.

Detto questo resta da dire che l’iPhone 4 è davvero ben fatto. È bello quasi quanto il mio Nexus One.

Stratosferico Nexus One

C’è da dire che il primo tentativo è andato male, ma il video del secondo lancio è eccezionale.

Di cosa sto parlando? Di un Nexus One montato su un razzo e fatto salire fino a otto chilometri e mezzo d’altitudine (ok, non è stratosfera, quella inizia a 12 chilometri, ma il nome ci sta tutto).

Answering Darek Currie

After writing an article about the Secunia report stating the Apple software has the highest number of security bugs, I have been attacked by a biologist/zoologist who now works as “Creative Technologist” (from now on I will say that my job is “Wonderful Engineer“) for an Apple specialist and authorized seller. Although the “creative” word in his job name, he states to be in the security field. I could guess that his job is to say “You don’t need anti-virus on Mac, because no criminal is caring about a platform used by only 5% of active computer population”. Or, since he is an active Christian, probably his job consists in praying “Please Jesus, protect all the Apple computers from viruses and hackers”.

Here is the answer I posted to Darek Currie1’s blog, just in case he decides to not approve it in order to hide away his complete ignorance of what computer security is.

Dear Derek,
on the oneITSecurity blog you have accused me to plagiarize an article appeared on PCWorld. I don’t want to involve my Italian readers in a quite useless (for them) discussion. Still I want to state some points:

1. I did not plagiarize. PCWorld has copied and pasted a paragraph from the Secunia report. I read the Secunia pdf document, chose the most interesting parts and summarized the most interesting parts putting them in other words in a way that in Italian could sound better while keeping the current meaning. It seems you never read the Secunia report (I’m citing it, taking the news from it, copying even the numbers from it), or otherwise you would have not accused me.

2. I partially agree with you about the correct interpretation of the Secunia Report, and I did write it. Just counting the bugs is quite stupid. I believe that we should look at the time of bugs resolution, and at their severity. And this would lead us to a better evaluation of the “security” of a software.

3. My readers are quite aware of the difference of safety and security. My parents live in a small town. Their house has a wood door with an easy to pick lock. I live in a big city, with a reinforced steel door and a twelve plungers lock. And still while my house is more secure than theirs, their house is safer than mine. In software case, some software is safer only because it is lot easier to aim at a bigger target than a small one.

4. The Secunia report is talking about general software, while you are talking about the mere operating system, even in your post you are comparing Windows and MacOSX. Even I say that “Microsoft is not so bad, after all” there is some irony that I guess is not so easy to translate using an automatic service.

5. It seems more likely that you are an Apple fanatic more than I am “an anti-Mac security myth mongerer”. (BTW, thanks for teaching me a new English word: mongerer. Never heard or read it before, probably it is not used in UK).

6. If a friend of mine asks me “what computer should I buy”, I will suggest him or her to buy a Mac (except for some special application need, like Autocad).

7. Still waiting your apologies.

  1. Do you think he is also smelling like curry? []
web

Italia.it vs France.fr

Techcrunch dedica tutto un post puntare il dito contro i disservizi di France.fr mentre finora nemmeno una riga è stata finora spesa dal famoso blog per il nostro portale per il turismo Italia.it benché le nostre figuracce siano iniziate da molto molto prima.

Il che fa di noi doppiamente perdenti: non ci prendono in considerazione né per il turismo, né per l’incompetenza.