giovedì 7 aprile 2011

Length-prefix message framing for streams

/// <summary>
/// Maintains the necessary buffers for applying a length-prefix message framing protocol over a stream.
/// </summary>
/// <remarks>
/// <para>Create one instance of this class for each incoming stream, and assign a handler to <see cref="MessageArrived"/>. As bytes arrive at the stream, pass them to <see cref="DataReceived"/>, which will invoke <see cref="MessageArrived"/> as necessary.</para>
/// <para>If <see cref="DataReceived"/> raises <see cref="System.Net.ProtocolViolationException"/>, then the stream data should be considered invalid. After that point, no methods should be called on that <see cref="PacketProtocol"/> instance.</para>
/// <para>This class uses a 4-byte signed integer length prefix, which allows for message sizes up to 2 GB. Keepalive messages are supported as messages with a length prefix of 0 and no message data.</para>
/// <para>This is EXAMPLE CODE! It is not particularly efficient; in particular, if this class is rewritten so that a particular interface is used (e.g., Socket's IAsyncResult methods), some buffer copies become unnecessary and may be removed.</para>
/// </remarks>
public class PacketProtocol
{
/// <summary>
/// Wraps a message. The wrapped message is ready to send to a stream.
/// </summary>
/// <remarks>
/// <para>Generates a length prefix for the message and returns the combined length prefix and message.</para>
/// </remarks>
/// <param name="message">The message to send.</param>
public static byte[] WrapMessage(byte[] message)
{
// Get the length prefix for the message
byte[] lengthPrefix = BitConverter.GetBytes(message.Length);
// Concatenate the length prefix and the message
byte[] ret = new byte[lengthPrefix.Length + message.Length];
lengthPrefix.CopyTo(ret, 0);
message.CopyTo(ret, lengthPrefix.Length);
return ret;
}
/// <summary>
/// Wraps a keepalive (0-length) message. The wrapped message is ready to send to a stream.
/// </summary>
public static byte[] WrapKeepaliveMessage()
{
return BitConverter.GetBytes((int)0);
}
/// <summary>
/// Initializes a new <see cref="PacketProtocol"/>, limiting message sizes to the given maximum size.
/// </summary>
/// <param name="maxMessageSize">The maximum message size supported by this protocol. This may be less than or equal to zero to indicate no maximum message size.</param>
public PacketProtocol(int maxMessageSize)
{
// We allocate the buffer for receiving message lengths immediately
this.lengthBuffer = new byte[sizeof(int)];
this.maxMessageSize = maxMessageSize;
}
/// <summary>
/// The buffer for the length prefix; this is always 4 bytes long.
/// </summary>
private byte[] lengthBuffer;
/// <summary>
/// The buffer for the data; this is null if we are receiving the length prefix buffer.
/// </summary>
private byte[] dataBuffer;
/// <summary>
/// The number of bytes already read into the buffer (the length buffer if <see cref="dataBuffer"/> is null, otherwise the data buffer).
/// </summary>
private int bytesReceived;
/// <summary>
/// The maximum size of messages allowed.
/// </summary>
private int maxMessageSize;
/// <summary>
/// Indicates the completion of a message read from the stream.
/// </summary>
/// <remarks>
/// <para>This may be called with an empty message, indicating that the other end had sent a keepalive message. This will never be called with a null message.</para>
/// <para>This event is invoked from within a call to <see cref="DataReceived"/>. Handlers for this event should not call <see cref="DataReceived"/>.</para>
/// </remarks>
public Action<byte[]> MessageArrived { get; set; }
/// <summary>
/// Notifies the <see cref="PacketProtocol"/> instance that incoming data has been received from the stream. This method will invoke <see cref="MessageArrived"/> as necessary.
/// </summary>
/// <remarks>
/// <para>This method may invoke <see cref="MessageArrived"/> zero or more times.</para>
/// <para>Zero-length receives are ignored. Many streams use a 0-length read to indicate the end of a stream, but <see cref="PacketProtocol"/> takes no action in this case.</para>
/// </remarks>
/// <param name="data">The data received from the stream. Cannot be null.</param>
/// <exception cref="System.Net.ProtocolViolationException">If the data received is not a properly-formed message.</exception>
public void DataReceived(byte[] data)
{
// Process the incoming data in chunks, as the ReadCompleted requests it
// Logically, we are satisfying read requests with the received data, instead of processing the
// incoming buffer looking for messages.
int i = 0;
while (i != data.Length)
{
// Determine how many bytes we want to transfer to the buffer and transfer them
int bytesAvailable = data.Length - i;
if (this.dataBuffer != null)
{
// We're reading into the data buffer
int bytesRequested = this.dataBuffer.Length - this.bytesReceived;
// Copy the incoming bytes into the buffer
int bytesTransferred = Math.Min(bytesRequested, bytesAvailable);
Array.Copy(data, i, this.dataBuffer, this.bytesReceived, bytesTransferred);
i += bytesTransferred;
// Notify "read completion"
this.ReadCompleted(bytesTransferred);
}
else
{
// We're reading into the length prefix buffer
int bytesRequested = this.lengthBuffer.Length - this.bytesReceived;
// Copy the incoming bytes into the buffer
int bytesTransferred = Math.Min(bytesRequested, bytesAvailable);
Array.Copy(data, i, this.lengthBuffer, this.bytesReceived, bytesTransferred);
i += bytesTransferred;
// Notify "read completion"
this.ReadCompleted(bytesTransferred);
}
}
}
/// <summary>
/// Called when a read completes. Parses the received data and calls <see cref="MessageArrived"/> if necessary.
/// </summary>
/// <param name="count">The number of bytes read.</param>
/// <exception cref="System.Net.ProtocolViolationException">If the data received is not a properly-formed message.</exception>
private void ReadCompleted(int count)
{
// Get the number of bytes read into the buffer
this.bytesReceived += count;
if (this.dataBuffer == null)
{
// We're currently receiving the length buffer
if (this.bytesReceived != sizeof(int))
{
// We haven't gotten all the length buffer yet: just wait for more data to arrive
}
else
{
// We've gotten the length buffer
int length = BitConverter.ToInt32(this.lengthBuffer, 0);
// Sanity check for length < 0
if (length < 0)
throw new System.Net.ProtocolViolationException("Message length is less than zero");
// Another sanity check is needed here for very large packets, to prevent denial-of-service attacks
if (this.maxMessageSize > 0 && length > this.maxMessageSize)
throw new System.Net.ProtocolViolationException("Message length " + length.ToString(System.Globalization.CultureInfo.InvariantCulture) + " is larger than maximum message size " + this.maxMessageSize.ToString(System.Globalization.CultureInfo.InvariantCulture));
// Zero-length packets are allowed as keepalives
if (length == 0)
{
this.bytesReceived = 0;
if (this.MessageArrived != null)
this.MessageArrived(new byte[0]);
}
else
{
// Create the data buffer and start reading into it
this.dataBuffer = new byte[length];
this.bytesReceived = 0;
}
}
}
else
{
if (this.bytesReceived != this.dataBuffer.Length)
{
// We haven't gotten all the data buffer yet: just wait for more data to arrive
}
else
{
// We've gotten an entire packet
if (this.MessageArrived != null)
this.MessageArrived(this.dataBuffer);
// Start reading the length buffer again
this.dataBuffer = null;
this.bytesReceived = 0;
}
}
}
}

martedì 22 marzo 2011

Color Picker



color_picker_seekbar_r.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff000000"
android:centerY="0.5"
android:endColor="#ffff0000"
android:angle="0"
/>
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff000000"
android:centerY="0.5"
android:endColor="#ffff0000"
android:angle="0"
/>
</shape>
</clip>
</item>
</layer-list>


color_picker_seekbar_g.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff000000"
android:centerY="0.5"
android:endColor="#ff00ff00"
android:angle="0"
/>
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff000000"
android:centerY="0.5"
android:endColor="#ff00ff00"
android:angle="0"
/>
</shape>
</clip>
</item>
</layer-list>
color_picker_seekbar_b.xml
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff000000"
android:centerY="0.5"
android:endColor="#ff0000ff"
android:angle="0"
/>
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff000000"
android:centerY="0.5"
android:endColor="#ff0000ff"
android:angle="0"
/>
</shape>
</clip>
</item>
</layer-list>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:id="@+id/changeTextColorButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Change Text Color"
/>
<Button android:id="@+id/changeBackgroundColorButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Change Background Color"
/>
<TextView android:id="@+id/sampleTextView1"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:gravity="center_vertical|center_horizontal"
android:textSize="20dp"
android:text="Sample1"/>
</LinearLayout>
dialog_picker.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="4dp"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="@string/color_picker_viewer"/>
<TextView android:id="@+id/colorPickerViewer"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
<TextView android:id="@+id/colorPickerTextR"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingTop="5dp"/>
<SeekBar android:id="@+id/colorPickerSeekBarR"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:max="255"
android:padding="8dp"
android:progressDrawable="@drawable/color_picker_seekbar_r"/>
<TextView android:id="@+id/colorPickerTextG"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"/>
<SeekBar android:id="@+id/colorPickerSeekBarG"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:max="255"
android:padding="8dp"
android:progressDrawable="@drawable/color_picker_seekbar_g"/>
<TextView android:id="@+id/colorPickerTextB"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"/>
<SeekBar android:id="@+id/colorPickerSeekBarB"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:max="255"
android:padding="8dp"
android:progressDrawable="@drawable/color_picker_seekbar_b" />
</LinearLayout>
dialog_selecter.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<GridView android:id="@+id/colorSelectGridView"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:verticalSpacing="6dp"
android:horizontalSpacing="6dp"
android:numColumns="4"/>
</LinearLayout>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, ColorSelectDialog!</string>
<string name="app_name">Color Select Dialog</string>
<string name="color_picker_viewer">Color Viewer(Click to select 16Color)</string>
<string name="color_picker_red">RED</string>
<string name="color_picker_green">GREEN</string>
<string name="color_picker_blue">BLUE</string>
</resources>
ColorSelectDialog.java
package jp.hiro711.ColorSelectDialog;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class ColorSelectDialog extends Activity {
final int CHANGE_TEXT = 0;
final int CHANGE_BACKGROUND = 1;

final int COLOR_TABLE[] = {
0xffffffff, 0xffc0c0c0, 0xff808080, 0xff000000,
0xffffc0c0, 0xffff6060, 0xffff0000, 0xff800000,
0xffffe0c0, 0xffffb060, 0xffff8000, 0xff804000,
0xffffffc0, 0xffffff60, 0xffffff00, 0xff808000,
0xffe0ffc0, 0xffb0ff60, 0xff80ff00, 0xff408000,
0xffc0ffc0, 0xff60ff60, 0xff00ff00, 0xff008000,
0xffc0ffe0, 0xff60ffb0, 0xff00ff80, 0xff008040,
0xffc0ffff, 0xff60ffff, 0xff00ffff, 0xff008080,
0xffc0e0ff, 0xff60b0ff, 0xff0080ff, 0xff004480,
0xffc0c0ff, 0xff6060ff, 0xff0000ff, 0xff000080,
0xffe0c0ff, 0xffb060ff, 0xff8000ff, 0xff400080,
0xffffc0ff, 0xffff60ff, 0xffff00ff, 0xff800080,
0xffffc0e0, 0xffff60b0, 0xffff0080, 0xff800040
};

int mColor = 0xffffffff;
int mTextColor = 0xffc0c0c0;
int mBackgroundColor = 0xff000000;

LayoutInflater inflater;
View dialogView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

final Button button1 = (Button)findViewById(R.id.changeTextColorButton);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mColor = mTextColor;
colorDialog(CHANGE_TEXT);
}
});
final Button button2 = (Button)findViewById(R.id.changeBackgroundColorButton);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mColor = mBackgroundColor;
colorDialog(CHANGE_BACKGROUND);
}
});
}

private void colorDialog(final int where) {
final String rString = getResources().getString(R.string.color_picker_red);
final String gString = getResources().getString(R.string.color_picker_green);
final String bString = getResources().getString(R.string.color_picker_blue);

inflater = LayoutInflater.from(this);
dialogView = inflater.inflate(R.layout.dialog_picker, null);

final TextView textR = (TextView)dialogView.findViewById(R.id.colorPickerTextR);
textR.setText(String.format("%s(%02X)", rString, (mColor & 0x00ff0000) >> 16));
final TextView textG = (TextView)dialogView.findViewById(R.id.colorPickerTextG);
textG.setText(String.format("%s(%02X)", gString, (mColor & 0x0000ff00) >> 8));
final TextView textB = (TextView)dialogView.findViewById(R.id.colorPickerTextB);
textB.setText(String.format("%s(%02X)", bString, (mColor & 0x000000ff)));
final TextView viewer = (TextView)dialogView.findViewById(R.id.colorPickerViewer);
viewer.setBackgroundColor(mColor);
viewer.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showDialog(0);
}
});

final SeekBar seekBarR = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarR);
seekBarR.setProgress((mColor & 0x00ff0000) >>16);
seekBarR.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int value = seekBar.getProgress();
textR.setText(String.format("%s(%02X)", rString, value));
mColor = (mColor & 0xff00ffff) | value << 16;
viewer.setBackgroundColor(mColor);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
int value = seekBar.getProgress();
textR.setText(String.format("%s(%02X)", rString, value));
mColor = (mColor & 0xff00ffff) | value << 16;
viewer.setBackgroundColor(mColor);
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
int value = seekBar.getProgress();
textR.setText(String.format("%s(%02X)", rString, value));
mColor = (mColor & 0xff00ffff) | value << 16;
viewer.setBackgroundColor(mColor);
}
});
final SeekBar seekBarG = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarG);
seekBarG.setProgress((mColor & 0x0000ff00) >> 8);
seekBarG.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int value = seekBar.getProgress();
textG.setText(String.format("%s(%02X)", gString, value));
mColor = (mColor & 0xffff00ff) | value << 8;
viewer.setBackgroundColor(mColor);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
int value = seekBar.getProgress();
textG.setText(String.format("%s(%02X)", gString, value));
mColor = (mColor & 0xffff00ff) | value << 8;
viewer.setBackgroundColor(mColor);
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
int value = seekBar.getProgress();
textG.setText(String.format("%s(%02X)", gString, value));
mColor = (mColor & 0xffff00ff) | value << 8;
viewer.setBackgroundColor(mColor);
}
});
final SeekBar seekBarB = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarB);
seekBarB.setProgress((mColor & 0x000000ff));
seekBarB.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int value = seekBar.getProgress();
textB.setText(String.format("%s(%02X)", bString, value));
mColor = (mColor & 0xffffff00) | value;
viewer.setBackgroundColor(mColor);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
int value = seekBar.getProgress();
textB.setText(String.format("%s(%02X)", bString, value));
mColor = (mColor & 0xffffff00) | value;
viewer.setBackgroundColor(mColor);
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
int value = seekBar.getProgress();
textB.setText(String.format("%s(%02X)", bString, value));
mColor = (mColor & 0xffffff00) | value;
viewer.setBackgroundColor(mColor);
}
});
final AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setView(dialogView);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int idx) {
switch(where) {
case CHANGE_TEXT:
mTextColor = mColor;
final TextView textView0 = (TextView)findViewById(R.id.sampleTextView1);
textView0.setTextColor(mTextColor);
break;
case CHANGE_BACKGROUND:
mBackgroundColor = mColor;
final TextView textView1 = (TextView)findViewById(R.id.sampleTextView1);
textView1.setBackgroundColor(mBackgroundColor);
break;
}
}
});
alert.show();
}

@Override
protected Dialog onCreateDialog(int id) {
if(id == 0) {
final String rString = getResources().getString(R.string.color_picker_red);
final String gString = getResources().getString(R.string.color_picker_green);
final String bString = getResources().getString(R.string.color_picker_blue);

LayoutInflater inflater1 = LayoutInflater.from(this);
final View dialogView1 = inflater1.inflate(R.layout.dialog_selecter, null);

final GridView gridView = (GridView)dialogView1.findViewById(R.id.colorSelectGridView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setBackgroundColor(COLOR_TABLE[position]);
return view;
}
};
for(int i = 0; i<COLOR_TABLE.length; i++) {
adapter.add("");
}
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
mColor = COLOR_TABLE[arg2];
final TextView textR = (TextView)dialogView.findViewById(R.id.colorPickerTextR);
textR.setText(String.format("%s(%02X)", rString, (mColor & 0x00ff0000) >> 16));
final TextView textG = (TextView)dialogView.findViewById(R.id.colorPickerTextG);
textG.setText(String.format("%s(%02X)", gString, (mColor & 0x0000ff00) >> 8));
final TextView textB = (TextView)dialogView.findViewById(R.id.colorPickerTextB);
textB.setText(String.format("%s(%02X)", bString, (mColor & 0x000000ff)));
final TextView viewer = (TextView)dialogView.findViewById(R.id.colorPickerViewer);
viewer.setBackgroundColor(mColor);
final SeekBar seekBarR = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarR);
seekBarR.setProgress((mColor & 0x00ff0000) >>16);
final SeekBar seekBarG = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarG);
seekBarG.setProgress((mColor & 0x0000ff00) >> 8);
final SeekBar seekBarB = (SeekBar)dialogView.findViewById(R.id.colorPickerSeekBarB);
seekBarB.setProgress((mColor & 0x000000ff));
dismissDialog(0);
}
});

return new AlertDialog.Builder(this)
.setView(dialogView1)
.setNegativeButton("Cancel", null)
.create();
}
return super.onCreateDialog(id);
}
}

martedì 8 febbraio 2011

Installazione Android SDK

In questi primi articoli dedicati al sistema operativo Android cercheremo di affrontare alcuni aspetti fondamentali per preparare il nostro ambiente di sviluppo e conoscerne le più importanti caratteristiche.

Quindi per prima cosa, vediamo come e cosa scaricare per prepararci a sviluppare le nostre applicazioni. L' ambiente di sviluppo è composto dai seguenti componenti:
  • Android SDK (Software development kit) disponibile per i diversi sistemi operativi
  • Android Development Tools (ADT), un plugin per Eclipse che è stato progettato per fornire un potente ed integrato ambiente in cui costruire le applicazioni Android
Il requisito indispensabile per installare l'intero ambiente di sviluppo è ovviamente la presenza del JDK (Java Developer Kit) lo potete scaricare a questo indirizzo JDK (Java Developer Kit).

Installare l'SDK

Il primo passo per creare l'ambiente Android è scaricare il pacchetto Android SDK Starter. Il pacchetto SDK Starter non è un completo ambiente di sviluppo - comprende solo il nucleo SDK Tools, che si puè utilizzare per scaricare il resto dei componenti SDK. E' possibile scaricare l'ultima versione del pacchetto SDK Starter alla SDK download page. Assicurarsi di scaricare il pacchetto appropriato per il proprio sistema operativo.

Dopo aver scaricato, bisogna scompattare l'archivio Android SDK in una posizione a vostra scelta del vostro file system. Per impostazione predefinita, i file SDK sono in una directory chiamata android-sdk-<machine-platform>. Prendere nota del nome e del percorso della directory SDK che avete scompattato sul sistema - è necessario fare riferimento alla directory SDK più tardi, quando si imposta il plugin ADT o quando si utilizzano gli strumenti SDK.

Quindi una volta installato il tutto bisogna avviare il download degli altri componenti tramite AVD Manager. Quindi bisogna accedere alla cartella android-sdk-<machine-platform> e lanciare:
  • Per utenti Windows: il file SDK Setup.exe
  • Mentre per amibienti linux e Mac-Os da riga di comando nella cartella /Tools:
    $ Androide

Adesso bisogna scegliere i componenti aggiuntivi per integrare le funzionalitè dell'ambiente. I componenti richiesti sono oltre al SDK Tools che è già presente nella cartella, bisogna selezionare la Platform SDK che è necessaria per la compilazione, e la creazione di un Virtual Android Device (AVD) che sarebbe l'emulatore per testare le applicazioni. Inoltre è raccomandato scaricare anche la documentazione, i driver USB - per testare direttamente le applicazioni sul un dispositivo collegato al computer (solo per utenti Windows, poichè Linux e Mac-OS hanno giè questi driver) - ed infine gli esempi compresi di codici sorgenti.

Installare il plugin ADT per Eclipse

Adesso invece passiamo all'installazione del plugin per Eclipse. Se non avete Eclipse installato sul vostro computer procedete con l'installazione, scaricando una versione di Eclipse RPC, oppure Eclipse 3.5 Classic reperibili alla pagina Eclipse Downloads

Dal menu Help selezionate la voce Software Updates(Eclipse 3.4 Ganymede) oppure Install New Software (Eclipse Galileo). Selezionate Add ed inserite alla voce Name la stringa "Android Plugin" e nella casella Location il seguente url:
https://dl-ssl.google.com/android/eclipse/
Adesso alla voce Work With selezionate Android Plugin e spuntate Developer Tools. A questo punto cliccate su Next e dovrebbe partire il download del Plugin. Una volta concluso il download sarete guidati nell'installazione. Al termine dell'installazione riavviate Eclipse.

Configurazione dell' ADT Plugin

Adesso non ci resta che configurare velocemente il Plugin in modo tale da collegarlo all'SDK Android. Andare sulla voce Windows -> Preferences e selezionare Android. A questo punto bisogna specificare la directory di installazione dell'SDK (android-sdk-<machine-platform>).

Configurare l'emulatore

Come ultimo passaggio non ci resta che configuare l'emulatore in caso non si dispone di un dispositivo reale che monta Android. Selezionate Window -> Android SDK and AVD Manager, oppure potete aprire l'ADV Manager direttamente dalla directory di Android come abbiamo visto sopra. Dal menu a sinistra bisogna selezionare la voce Virtual Device e cliccare sul tasto New a destra del pannello. Si aprira un'altra finestra dove bisogna specificare il Nome, ad esempio AndroidEmulator, e il Target dove potete selezionare le Api Level (ad esempio Android 1.6 - API Level 4); e per concludere cliccate su Create ADV.

Dopo questa breve e veloce panoramica sull'installazione non ci resta che avventurarci in nuove guide ed articoli dove vedremo insieme come creare semplici applicazioni, per poi passare ad argomenti un po più complessi, cercando di toccare i vari aspetti di quest'ambiente di sviluppo.