Archiv der Kategorie: android apps

Processing mit Eclipse entwickeln


Zuerst sollte man dieses Tutorial durcharbeiten: http://erik-bartmann.de/programmierung/processing/processing-mit-eclipse.html

Mit der folgenden Funktion kann man seinen Code auch als Java Application laufen lassen.

public static void main(String args[]) {
PApplet.main(new String[] { "--present", "NAMEDERKLASSE" });
}

Da Processing von PApplet abgeleitet wird, muss jede Klasse neue “ extends PApplet“ enthalten, damit alle Processing – Objekte auch innerhalb der neuen Klasse funktionieren.

Will man aber separate  Klassen erzeugen, die von einer Processing Anwendung aus benutzbar sind, haben wir das Problem, dass sich die Processing eigenen Anweisungen, wie z.B. rect() u.a. nicht verwenden lassen. Dieses Problem kann man lösen, in dem man der Klasse sagt, dass sie auf dem PApplet zeichnen soll.

Details darüber findet man hier: http://www.learningprocessing.com/tutorials/processing-in-eclipse/

Eine andere sehr gute Anleitung gibt es hier: http://creativecoding.org/en/beyond/p5/eclipse_as_editor

Processing Sketch in eine vollständige Android-App einbinden


In diesem Tutorial wird gezeigt, wie man einen Procesing-Sketch in Eclipse zu einer vollständigen App mit Menü-Activity und einem Button ausbaut, der die Processing-Acitvity öffnet. Bei der Erstellung ist dabei die Processing-IDE auch weiterhin sinnvoll. Die Processing-Sketches werden weiterhin darin entwickelt und dann, wenn sie fertig sind exportiert. Dabei erstellt Processing im Sketchbook-Folder einen Ordner mit dem Namen Android. Darin sind im src Ordner die *.java – Dateien zu finden, die man dann in das Eclipse-Projekt importieren kann.

Vorbereitungen: Installation der Android SDK des ADT Plugins für Eclipse lt. Anleitung.Image

1. Wir erstellen mit Hilfe des Assistenten des ADT-Plugins ein neues Android Programm –> New Android Programm . Alle Felder ausfüllen und Create Projekt from existing Sample –> Skeleton App wählen. Das erstellt ein leeres Android Projekt mit einer Activity und allen Dateien, die sonst noch notwendig sind.

Die Ordner-Struktur sieht dann folgendermaßen aus:

  • src: enthält die Java-Quelltexte
  • gen: hier finden sich automatisch generierte Klassen, wie die R-Klasse
  • res: hier kommen die Resourcen hin
  • asset: weiterer Ordner für Ressourcen
  • im root liegt dann noch die Android Manifest.xmlImage

2. Wir kopieren die Processing .java – Exportdatei aus dem Sketchbook /src/.. -Ordner in den Eclipse- /src-Ordner. Danach werden wir von Eclipse auf einige Fehler hingewiesen. Das liegt daran, dass Eclipse die Processing- Library nicht automatisch einbindet.

3. Die Library processing-core.jar einbinden. Re. Maustaste auf Projektname –> Build Path –> Add External Archieves. Dann die im Processing-Exportordner unter Android/libs processing-core.jar.

4. Die neue Activity muss in die AndroidManifest.xml eingetragen werden. Und zwar innerhalb des Application-Tags

<application android:icon="@drawable/icon" android:label="@string/app_name">
 <activity android:name="Proctest"
 android:label="@string/app_name">
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 <activity android:name=".Procactivity" />
 </application>

5. Zu guter Letzt müssen wir noch die Acitvity starten. Das machen wir, wie in Android üblich per Intent. Wir werden dafür einen Button in der Start-Activity erstellen und von dort aus die Processing-Activity starten. Dafür ergänzen wir die main.xml in /res/layout um die folgenden Zeilen:

<Button
 android:id="@+id/start"  
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"   
 android:text="@string/start"
 android:onClick="onClickStarten" />

Die erste Zeile android:id=“@+id/start“ bedingt, dass wir auch in der Datei stings.xml in /res/values die Zeile: <string name=“start“>Start</string> innerhalb des resources-Tags ergänzen müssen.

Dannach erweitern wir die, vom Android-Assistenten erstellte *.java -Datei um diese Zeilen innerhalb der onCreate-Funktion:

final Button buttonstart =
 (Button) findViewById(R.id.start);
 buttonstart.setOnClickListener(mStartenListener);

Dadurch wird unserem Button ein Listener hinzugefügt. In den folgenden Zeilen wird dann noch ein der Intent aufgerufen, der die Processing -Acitvity startet. Dieser Code muss nach der onCreate-Funktion aufgerufen werden.

private OnClickListener mStartenListener =
 new OnClickListener() {
 public void onClick(View v) {
 onClickStarten(v);
 }
 };

 public void onClickStarten(final View sfNormal) {
 final Intent i = new Intent(this, Procactivity.class);
 startActivity(i);
 }

Damit sind wir fertig und können nun eine Processing-Acitvity inkl. Optionsmenü von einer beliebigen Activity aus starten.

Hier noch der gesamte Quellcode zum Download: proctest.zip

Processing Apps für Android – Optionsmenü


Nachdem Optionsmenüs für Android-Apps enorm wichtig sind, hier ein Code-Beispiel, wie man eines erstellen kann.

Als Beispiel habe ich die Funktion Vieleck aus dem basic-Artikel Winkel und Wellen gewählt, in dem man dann die Eckenzahl mit Hilfe eines Optionsmenüs wählen kann. Die Funktion ist, wie in den anderen Artikeln auch, einfach gewählt, damit der Fokus auf den eigentlichen Inhalten bleibt. In diesem Fall das Optionsmenü.

  • Processing Sketches laufen in Android als Activity, d.h. die Processing-Klasse PApplet erweitert die Klasse Acitvity. In so fern stehen auch alle Methoden der Acitvity-Klasse zur Verfügung.
  • menu.add(0, DREI_ID, Menu.NONE, „3“); erzeugt einen Menüeintrag, wobei 0 die goupId, DREI_ID die itemId, Menu.NONE die Reihenfolge und „3“ den Titel des Menüpunkts definieren. Menu.NONE wird angegeben, wenn die Reihenfolge der Einträge egal ist
//Imports für die Anzeige des Menüs
import android.view.Menu;
import android.view.MenuItem;

int ecken = 5; //Anzahl der Ecken beim Start
int winkel;
float x1, y1, x2, y2;

//IDs der Menüeinträge werden zugewiesen
public static final int DREI_ID =  Menu.FIRST;
public static final int VIER_ID =Menu.FIRST+2;
public static final  int FUENF_ID = Menu.FIRST+3;
public static final int SECHS_ID = Menu.FIRST+4;
public static final int ACHT_ID = Menu.FIRST+5;

void setup() {
 smooth();
}

void draw() {
 fill(255, 20);
 rect(0, 0, width, height);
 vieleck(ecken, mouseX, mouseY, 10, 10);
}

void  vieleck (int seiten, int x, int y, int radiusX, int radiusY) {
 winkel = (int) 360/seiten;
 for (int grade=0; grade<360; grade+=winkel) {
 x1 =sin(radians(grade))*radiusX+(x);
 y1 =cos(radians(grade))*radiusY+(y);
 x2 =sin(radians(grade+winkel))*radiusX+(x);
 y2 =cos(radians(grade+winkel))*radiusY+(y);
 line(x1, y1, x2, y2);
 }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
 // hier werden die einzelnen Menüeinträge erzeugt
 menu.add(0, DREI_ID, Menu.NONE, "3");
 menu.add(1, VIER_ID, Menu.NONE, "4");
 menu.add(2, FUENF_ID, Menu.NONE, "5");
 menu.add(3, SECHS_ID, Menu.NONE, "6");
 menu.add(4, ACHT_ID, Menu.NONE, "8");
 return super.onCreateOptionsMenu(menu);
}

//wird aufgerufen, wenn ein Menüpunkt ausgewählt worden ist
@Override
public boolean onOptionsItemSelected(MenuItem item) {
 //die Auswahl wird über die ItemId des Menüpunktes überprüft
 switch (item.getItemId()) {
 case DREI_ID:
 ecken=3;
 break;

 case VIER_ID:
 ecken=4;
 break;

 case FUENF_ID:
 ecken=5;
 break;

 case SECHS_ID:
 ecken=6;
 break;

 case ACHT_ID:
 ecken=8;
 break;
 }
 return super.onOptionsItemSelected(item);
}

Das wars!

Android Grundlagen


Android ist ein auf Linux basierendes Betriebssystem, das für die Anwendung auf mobilen Geräten optimiert ist. Da sich der Linux-Kernel relativ leicht an die Anforderungen verschiedener Hardware-Plattformen anpassen lässt, ist das anfangs nur für ARM -Prozessoren verfügbare Android heute auf vielen verschiedenen Plattformen anzutreffen. Es kommt u.a. in Fernsehern, Infotainment-Systemen in Autos, Spielekonsolen und vielem mehr zum Einsatz.

Image

Wie in der Abbildung (Quelle: Wikipedia) oben zu sehen ist, stellt der Linux- Kernel die Basis von Android dar.

Die Libraries (oder Bibliotheken, geschrieben in C/C++) stellen die vom Anwendungsrahmen (Application Framework) benötigte Funktionalität zur Verfügung.

Daneben steht die Android-Laufzeit (Runtime), deren Kernkomponente die Dalvik-VM (DVM) ist. Sie sorgt dafür, dass pro Anwendung ein eigener Systemprozess gestartet wird. Dieser enthält eine eigene Dalvic-VM und darin die Anwendung selbst. Dies hat den Vorteil, dass nicht das ganze Betriebssystem „hängt“, wenn eine Anwendung abstürzt. Was die Programmierung angeht, kann man Android vollständig in Java programmieren, man muss allerdings den Java-Code noch extra durch den Dx-Converter verarbeiten.In Summe sieht das das dann so aus:

(Java) IDE (Processing) –> Java-Compiler –> *.class-Datei –> Dx-Konverter –> *.dex

Der Anwendungs-Rahmen (Application-Framework) stellt jetzt die Basis für unsere Entwicklungsarbeit. Sie enthält viele Systemklassen, auf die wir aus unseren Processing-Anwendungen heraus zugreifen können. Processing-Programme laufen als Activity. Diese Activitys unterliegen einem Lebenszyklus, d.h. bestimmte Ereignisse im Lebenszyklus können als Trigger in unseren Programmen verwendet werden.

Alle Anwendungen (Applications) greifen auf den darunter liegenden Anwendungs-Rahmen zu.

Weiterführende Info: Android-Laufzeitumgebung.pdf

Processing Apps für Android X – Erstellen einer .apk-Datei aus .pde


Image

Nun, da wir das Projekt Pure Pong! soweit fertig gestellt haben, versuchen wir jetzt es zu veröffentlichen. Da es in Processing derzeit keine Möglichkeit gibt, das per Knopfdruck zu erledigen, müssen wir hier selber Hand anlegen. Dafür gibt es auch eine Step by Step Anleitung von Eric Pavey, die aber bei mir auf Ubuntu 10.10 nicht genau funktionierte. Sehr hilfreich war bei mir dann die Anleitung von Google selbst.

Deshalb hier noch meine Erfahrungen Schritt für Schritt:

  1. Processing Sketch Exportieren
    Dabei erhalten wir eine .pde -Datei im Projektverzeichnis im Sketchbook.
  2. Einen geheimen Schlüssel erstellen
    In Ubuntu 10.10 sind alle notwendigen tools schon installiert. sudo keytool -genkey -v -keystore NAMEDESPROGRAMMS-release-key.keystore -alias DEINNAMEHIER -keyalg RSA -keysize 2048 -validity 10000
    Bevor der Schlüssel erstellt wird, muss man noch einige Fragen beantworten, die bei der Erstellung eine Rolle spielen. Wenn das Programm keytool durchgelaufen ist, wird im aktuellen Verzeichnis eine Datei NAMEDESPROGRAMMS-release-key.keystore erstellt.

    Vorsicht: der Schlüssel muss unbeding gesichert werden, denn für etwaige Updates muss das neue Programm wieder mit dem originalen Schlüssel signiert werden.

  3. Das Programm compilieren
    Unter Ubuntu brauchte ich dafür nur in das Sketchbook-Verzeichnis von Pure Pong! und dann in den Ordner android. Mit dem Befehl

    ant release

    wird dann ein neues Unterverzeichnis /bin erzeugt in der sich ein Verzeichnis classes und folgende Dateien befinden classes.dex  PurePong_.ap_  PurePong_-unsigned.apk.

  4. Das Programm signierenROGRAMMS-release-key.keystore -alias DEINNAMEHIER -keyalg RSA -keysize 2048 -validity 10000
    Die PurePong_-unsigned.apk ist wie der Name schon sagt, nicht signiert. Das erledigen wir mit dem Programm jarsigner. Ein vollständiger Komandozeilen-Befehlt sieht dann etwa so aus:

    jarsigner -verbose -keystore NAMEDESPROGRAMMS-release-key.keystore /VOLLSTÄNDIGER_PFAD+NAME-unsigned.apk DEINNAMEHIER

    Man muss dann noch das vorher bei der Schlüsselerstellung gewählte Passwort eingeben und schon laufen einige Zeilen Code mit adding und signing auf der Konsole durch und schon ist die Sache erledigt! Eine Erfolgsmeldung oder ähnliches gibt es bei mir nicht.

  5. Erstellen der fertigen .apk -Datei
    Hier kommt das Programm zipalign zum Einsatz. Es befindet sich im Installationsverzeichnis der Android SDK im Unterordner tools. Von dort aus gestartet macht es aus unserer Datei eine fertige .apk- Datei.

    /PFAD ZU DEINEM HOME VERZEICHNIS/android-sdk-linux_x86/tools/zipalign -v 4 /VOLLSTÄNDIGER_PFAD+NAME-unsigned.apk GEWÜNSCHTER_NAME.apkWenn das Programm fertig ist hat man ein fertige .apk -Datei zur Verfügung

Zu guter Letzt meine purepong.apk zum Download (mit RechtsClick – Datei speichern unter)!!!

Veröffentlichen im Market – Vorbereitungen

Die oben beschriebene Art der Veröffentlichung ist sozusagen die „basic“ Variante. Will man seine App im Market platzieren, sollte man noch einige Schritte ergänzen. Eine englischsprachige Anleitung gibt es direkt von Google.

3 Dinge sind hier wichtig:

  • Die App muss mit einem Sicherheitsschlüssel signiert werden, der bis 2033 gültig ist. Das habe wir mit dem Schlüssel oben erfüllt, da wir das keytool mit einer -validity 10000 aufgerufen haben. Diese Einstellung erzeugt einen Schlüssel mit einer Gültigkeit von 10000 Tagen, also ~27 Jahren.
    Image
  • Die Datei AndroidManifest.XML muss unbedingt einen Eintrag android:versionCode und android:versionName enthalten. Diese werden von Processing automatisch beim Exportieren erstellt und man muss sich nicht darum kümmern, wenn man das nicht ausdrücklich will.
  • Weiters müssen im Application-Tag noch die Attribute android:label und android:icon gesetzt sein, was Processing ebenfalls schon automatisch erledigt.

Ich habe dann noch ein eigenes Icon erstellt. Hier muss man allerdings gleich 3 mit verschiedenen Auflösungen generieren, damit es möglichst vielen Geräten funktioniert. Alle sind im Sketchbook-Ordner des Projekts unter /android/res/drawable zu finden. Meine Empfehlung: Das größte Icon im Ordner /drawable-hdpi mit Gimp öffner und bearbeiten. Ist es so, wie man es sich vorstellt, kann man es dann nach unten skalieren und auch in die anderen Ordner mit den entsprechenden Auflösungen speichern.

Der Android Market bietet die Möglichkeit das Lizensierungs-Modell von Google zu verwenden. Ich werde das in diesem Fall nicht tun. Infos darüber gibt es hier: Lizensierung für den Android Market.

Veröffentlichen im Market

Um Apps auf dem Market veröffentlichen zu können, braucht man, wie nicht anders zu erwarten eine Konto bei Google. Damit kann man sich dann auf dieser Seite für den Market anmelden: http://market.android.com/publish

  • Hier ist dann erst einmal ein Formular auszufüllen, das unter anderem auch nach der Telefonnummer fragt! Typisch Google.
  • Weiters sind 25 USD zu bezahlen (per Kreditkarte)
  • Danach muss man nur noch alles akzeptieren, was Google verlangt.

Geschafft. Nun kann man seine App in den Market hochladen.

Image

Interessanterweise hatte ich in weiterer Folge die größten Probleme damit, einen Screenshot von meinem Game zu erzeugen. All gratis im Market verfügbaren Programme versagten auf meinem Phone. Ich habe dann den Inhalt einfach abfotografiert. Ist zwar nicht so schön, aber es funkt.

Geschafft: Game ist im Market unter: https://market.android.com/search?q=PurePong!

Probiert es aus, ich freue mich über jedes Feedback!

Android App Pure Ping Pong!


Processing 2.0

Mein erstes fertiges Projekt ist wieder mal Ping Pong, diesmal Pure Ping Pong!. Zum allgemeinen Verständnis siehe: Projekt Ping Pong. Die Version für Android ist eine schon recht deutlich veränderte.

  • Ich habe im Gegensatz zu Ping Pong für die Steuerung des Balls und der Spielerbalken jetzt PVector-Objekte verwendet.
  • Das Spiel nutzt Multitouch und ist ein reines Multiplayer-Game.
    • Durch das Bewegen des Balkens während der Ballberührung kann man den Balls seitlich beschleunigen.
    • Die Geschwindigkeit des Balls hängt von der Größe des Pointers während der Ballberührung ab. Er kann dadurch beschleunigt, oder gebremst werden.
  • Es wurden Vibrations-Effekte für das haptisches Feedback eingebaut.

Hier der Quellcode mit Kommentaren:

<pre>// Imports
import android.content.Context;
import android.app.Notification;
import android.app.NotificationManager;

// Setup vibration globals:
NotificationManager gNotificationManager;
Notification gNotification;
long[] gVibrate = {
0, 100
};

// Globale Variablen
int size;
int s2;
int balls=5;
int balls1=5;
int serve=2;
int frame=0;
PVector ballPos;
PVector ballDir;
int pPosx;
int pPosy;
int ppPosx;
int pPosx1;
int pPosy1;
int ppPosx1;
float ballspeed;
float ballspeed1;
float maxSpeed;
float minSpeed;
int h24;
int h48;
int hh6;
int h6;
int h4;
int w8;
int w6;
int blockdir=0;
color bg = color(0, 150, 255);
color pl = color(255, 170, 0);

PFont font;

void setup()
{
size(displayWidth, displayHeight);

//Damit sich die Ausrichtung des Displays nicht während des Spiels ändert
orientation(PORTRAIT);
maxSpeed=displayHeight/40;
minSpeed=displayHeight/200;
size=(int)height/24;
//hier die am öftesten vorkommenden Berechnungen
s2=(int) size/2;
h24=(int) displayHeight/24;
h48=(int)displayHeight/48;
hh6=(int)displayHeight-displayHeight/6;
h6=(int)displayHeight/6;
h4=(int)displayHeight/4;
w8=(int)displayWidth/8;
w6=(int)displayWidth/6;

// die PVector-Objekte werden erzeugt
pPosx = (int)width/2;
pPosy = hh6;
ppPosx = pPosx;
pPosx1 = (int)width/2;
pPosy1 = h6;

ppPosx1 = pPosx1;
ballPos = new PVector(width/2, height-h4);
ballDir = new PVector (0, -4);
textAlign(CENTER);
rectMode(CENTER);
font = createFont("Arial", 12);
stroke(180);

// Create our Notification Manager:
gNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Create our Notification that will do the vibration:
gNotification = new Notification();
// Set the vibration:
gNotification.vibrate = gVibrate;
}

void draw()
{
background(bg);
fill(180);
// für die Start-Einblendung
if (frameCount<120) {
translate(width/2, height/2);
textSize(w8);
rotate(PI/2);
text("PURE PING PONG!", 0, 0);
rotate(-PI/2);
translate(-width/2, -height/2);
}
else {  // hier läuft das Spiel
line(0, height/2, width, height/2);

//Zeichnet verbleibende Bälle für die Spieler
for (int i=1; i<=balls1; i++) {
ellipse(width/(balls1+1)*i, height/3, h48, h48);
}
for (int i=1; i<=balls; i++) {
ellipse(width/(balls+1)*i, height*2/3, h48, h48);
}

// wenn ein Spieler gewonnen hat
if (balls<=0 || balls1 <=0) {
textSize(w8);
translate(width/2, height/2);
if (balls>balls1) {
text("YOU WON !", 0, h4);
}
else {
rotate(PI);
text("YOU WON !", 0, h4);
rotate(-PI);
}
translate(-width/2, -height/2);
}
else {

// Bewegung des Balles
ballPos.add(ballDir);

//Begrenzung seitlich
if (ballPos.x < 0+s2 || ballPos.x > width-s2) {
ballDir.x *= -1;
}

// Begrenzung Spieler 1 und Fehler

// Ball ist im Bereich des Balkens
if ( int(ballPos.y) >= int(hh6-h48-s2) && serve==2) {

//Ball ist vor dem Balken
if ((ballPos.x > pPosx-w6 && ballPos.x < pPosx+w6) && blockdir>4) {

//Beschleunigung oder Verzögerung des Ball je nach Druckpunkt
ballDir.y *=-lerp(0.6, 3, ballspeed);

//Maximal und Minimalwerte für die Ballgeschwindigkeit
if (ballDir.y>0) {
ballDir.y=min(ballDir.y, maxSpeed);
ballDir.y=max(ballDir.y, minSpeed);
}
else {
ballDir.y=max(ballDir.y, -maxSpeed);
ballDir.y=min(ballDir.y, -minSpeed);
}

// Damit kann man dem Ball "Schnitt" verleihen
ballDir.x -=(ppPosx-pPosx)/3;

//Haptisches Feedback wenn der Ball getroffen wird
gNotificationManager.notify(1, gNotification);

//Damit verhindert wird, dass der Ball mehrmals die Richtung wechselt
blockdir=0;
}

//bei Fehler
else {
frame=0;

balls-=1;
serve=0;
}
}

// Begrenzung Spieler 1 und Fehler

// Ball ist im Bereich des Balkens
if ( int(ballPos.y) <= int(h6+h48+s2) && serve==2) {

//Ball ist vor dem Balken
if ((ballPos.x > pPosx1-w6 && ballPos.x < pPosx1+w6) && blockdir>4) {

//Beschleunigung oder Verzögerung des Ball je nach Druckpunkt
ballDir.y *=-lerp(0.6, 3, ballspeed1);

//Maximal und Minimalwerte für die Ballgeschwindigkeit
if (ballDir.y>0) {
ballDir.y=min(ballDir.y, maxSpeed);
ballDir.y=max(ballDir.y, minSpeed);
}
else {
ballDir.y=max(ballDir.y, -maxSpeed);
ballDir.y=min(ballDir.y, -minSpeed);
}

// Damit kann man dem Ball "Schnitt" verleihen
ballDir.x -=(ppPosx1-pPosx1)/3;

//Haptisches Feedback wenn der Ball getroffen wird
gNotificationManager.notify(1, gNotification);

//Damit verhindert wird, dass der Ball mehrmals die Richtung wechselt
blockdir=0;
}

//bei Fehler
else {
frame=0;

balls1-=1;
serve=1;
}
}

// Zeichnet den Ball
stroke(255);
fill(255);
ellipse(ballPos.x, ballPos.y, size, size);

//Zeichnet die Balken
stroke(pl);
strokeWeight(h24);
line(pPosx-w8, hh6, pPosx+w8, hh6);
line(pPosx1-w8, h6, pPosx1+w8, h6);
strokeWeight(0);
stroke(200);

// Bewegung Player 1 und 2
ppPosx=pPosx;
ppPosx1=pPosx1;
}

// Spielverzögerung bei Fehler
if (serve==0 && frame>30) {
ballDir.x=0;
ballPos.x=pPosx;
ballPos.y=height-h4;
if (serve==0 && frame>90) {
ballDir.y *=-1;

serve =2;
}
}
if (serve==1 && frame>30) {
ballPos.x=pPosx1;
ballPos.y=h4;
ballDir.x=0;
if (serve==1 && frame>90) {
ballDir.y *=-1;

serve =2;
}
}

// Verzögerung bei Fehler
frame++;

// Blockierung der Ballrichtung nach dem Rückprall am Balken
blockdir++;
}
}

//Funktion für Multitouch Events von
// Eric Pavey - www.akeric.com - 2010-10-24  (verändert)
//-----------------------------------------------------------------------------------------
// Override Processing's surfaceTouchEvent, which will intercept all
// screen touch events.  This code only runs when the screen is touched.

public boolean surfaceTouchEvent(MotionEvent me) {
int pointers = me.getPointerCount();

if (pointers>1) {
// Zuordnung der TouchPoints zum jeweiligen Spieler
if (int(me.getY(0))<height/2) {
pPosx=(int)me.getX(1);
pPosx1=(int)me.getX(0);
ballspeed = me.getSize(1);
ballspeed1= me.getSize(0);
}

else {
pPosx=(int)me.getX(0);
pPosx1=(int)me.getX(1);
ballspeed = me.getSize(0);
ballspeed1= me.getSize(1);
}
}
return super.surfaceTouchEvent(me);
}

Viel Spass!

Processing Apps für Android II – Multitouch


Processing 2.0

Ein interessantes Feature der Android- Programmierung ist auf jeden Fall die Möglichkeit Multitouch zu verwenden. Es gibt im Netz schon einige Implementierungen, von denen ich diese von Eric Pavey für mein Projekt Pong für Android genutzt habe. Dieser Beispielcode ist zum Testen hervorragende geeignet.

Das Kernstück verwendet den Processing surfaceTouchEvent und triggert ihn mit dem MotionEvent aus der Android-Library.

//-----------------------------------------------------------------------------------------
// Override Processing's surfaceTouchEvent, which will intercept all
// screen touch events.  This code only runs when the screen is touched.

public boolean surfaceTouchEvent(MotionEvent me) {
 // Number of places on the screen being touched:
 int numPointers = me.getPointerCount();
 if (int(me.getY(0))<height/2) {
  playerPos.x=me.getX(1);
  playerPos1.x=me.getX(0);
  ballspeed = me.getSize(1);
  ballspeed1= me.getSize(0);
 } else {
  playerPos.x=me.getX(0);
  playerPos1.x=me.getX(1);
  ballspeed = me.getSize(0);
  ballspeed1= me.getSize(1);
 }
 return super.surfaceTouchEvent(me);
}

Ich habe diesen Code für mein Projekt Pure Pong! genutzt. Man kann mit ihm dann die 2 Pointer für das Spiel dem richtigen Spieler zuordnen und in draw() ihre Koordinaten verarbeiten.

Processing Apps für Android III – Vibration


Auch die Vibrationsfunktion von Android-Handys kann man in Processing nutzen. Dabei muss man der Anwendung aber zuerst die Rechte dazu einräumen. Das geht unter Processing Menü –> Android –> Sketch Permissions –> Vibration. Oder in der Datei AndroidManifest.XML.

Dieser Code von Eric Pavey ist gut zum Experimentieren geeignet.

Im Projekt Pure Pong! wurde ein ganz leicht veränderter Code verwendet. Zuerst müssen die nötigen Lybraries importiert werden.

import android.content.Context;
import android.app.Notification;
import android.app.NotificationManager;

Dann werden die Objekte erzeugt.

NotificationManager gNotificationManager;
Notification gNotification;
long[] gVibrate = {0,100};

Dann erzeugt man das die eigentliche Benachrichtigung mit folgendem Code. Ich habe diesen in setup() platziert.

void setup() {
    .
    .
    .
  // Create our Notification Manager:
  gNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  // Create our Notification that will do the vibration:
  gNotification = new Notification();
  // Set the vibration:
  gNotification.vibrate = gVibrate;
}

Irgendwo im Code, bei mir in draw() kann die Vibration dann aufgerufen werden.

gNotificationManager.notify(1, gNotification);

Processing Apps für Android I – Erste App erstellen


Processing 2.0

Hier die offizielle Dokumentation für Processing auf Android und die entsprechende Abteilung im Forum.

Auch das ist ein guter Erfahrungsbericht und eine sehr einfache Schritt für Schritt Anleitung.

Unterstützt werden Android-Versionen ab 2.3.3 (API 10).

  1. Zuerst muss die Android SDK heruntergeladen werden. Ich verwende Ubuntu 12.04 und habe das entsprechende Paket laut Anleitung installiert.
    Das ADT-Plugin für Eclipse muss nicht installiert werden. Dafür müssen aber im Schritt 4 der Installationsanleitung die folgenden Pakete installiert werden:

    • unter Available Packages –> Android Repository: SDK Platform Android 2.3.3, API 10

    Man kann auch die neueren Versionen der API oder gleich alles zusätzlich installieren.

  2. In Processing 2.0 Android-Mode aktivieren, Berechtigungen zu setzen usw.
  3. ImageWenn wir unser Processing 2.0 jezt starten und im Menü –> Android Mode aktiviert haben, können wir, mit Shift Play den Sketch starten , wird dieser automatisch im Emulator ausgeführt. Allerdings muss der Sketch vorher gespeichert werden. Es kann mal passieren, dass der Emulator nicht beim ersten Mal startet.
  4. Hier ein kleines Beispielprogramm zum Testen:
  5. void setup() {
    Imagesize(240,400);
    noStroke();
    fill(255);
    
    ellipseMode(CENTER);
    };
    void draw() {
    background(10,80,139);
    ellipse(width/2, height/2, 150, 150);
    };
  6. Damit man das Programm nun auf dem Android-Gerät laufen lassen kann, muss man die Anleitung hier durcharbeiten: http://developer.android.com/guide/developing/device.html
  7. Wenn das Gerät verbunden ist, kann man das Programm von oben in Processing 2.0 mit einem Klick auf Playam Gerät laufen lassen. Mit Shift Play ist es aber nach wie vor möglich, den Emulator aufzurufen!
  8. Einige Tipps zur Programmierung speziell für Android:
    • Will man 3D Sketches im Emulator laufen lassen, muss man die virtuelle Maschine im AVD Manager bearbeiten und unter Hardware die GPU emulation auf yes stellen. Dort können auch andere Hardwareoptionen aktiviert werden.
    • Viele Mobiltelefone unterstützen nicht die volle 24bit Farbtiefe. Dadurch kann es zu Darstellungsproblemen bei Farbübergängen kommen.
    • Die Verwendung von createFont() bringt speziell bei 2D Anwendungen Qualitätsvorteile gegenüber loadFont().
    • Statt size(width, height), ist es besser size(displayWidth, displayHeight) zu verwenden. Dann wird die Anwendung immer auf den vollen Bildschirm skaliert. Als 3D Renderer kann man P2D oder P3D verwenden.
    • Was Maus-Eingabe betrifft, können mouseX und mouseY wie gehabt verwendet werden, zusätzlich gibt es neue Variablen. motionX, motionY, pmotionX, pmotionY und motionPressure.
    • EventHandler für Key– und MouseEvents sind nicht verfügbar.
    • Wenn man die Bildschirm-Orientierung sperren will, kann man das mit orientation(PORTRAIT) oder orientation(LANDSCAPE) machen.
    • weiter info unter: http://wiki.processing.org/w/Android