Archiv der Kategorie: Android SDK

Der Android Marktanteil bei Tablets, Smartphones und anderen Embedded Geräten ist im Mobile Bereich in den letzten Jahren stark angestiegen. Aus diesem Grund beschäftige ich mich gelegentlich mit dem Android SDK, welches die Entwicklung von Apps mit der Programmiersprache Java ermöglicht.

Android statistics and facts

Problem

During the development of android applications the developer has to decide which API Level his applications requires. The API Level is clearly associated with a Android Codename (i.e. Ice Cream Sandwich: 14 and 15 (MR1), Jelly Bean 16 to 17 (MR1), Kit Kat 18…).

A trustable source that shows the frequency of usage for Android Versions can give the information about which versions should be considered retrospective.

Approach

A link collection of  popular sources will be provided in this article. The developer has to customize the androidmanifest.xml in his application to define the minimum API Level.

Solution

Which android versions have to be considered for the development?

http://developer.android.com/about/dashboards/index.html

Where can i get an actual complete list of API Levels and Android Names?

http://developer.android.com/guide/appendix/api-levels.html

 

 

Android: JOYN deaktvieren / ausschalten / ausstellen ohne zu rooten oder Custom ROM zu installieren

Problem

Die deutschen Netzanbieter, insbesondere die Telekom, haben sich darauf geeinigt einen neuen Dienst JOYN als Alternative zu WhatsApp anzubieten. Das Ziel ist es zu verhindern, dass die Kunden alle zu kostenlosen Anbietern wie WhatsApp, Tremor etc wechseln. Seitdem die Handys internetfähig sind können die Provider lediglich über das Anbieten von Paketdatenverbindungen Geld für Nachrichten verdienen. Früher war es möglich pro SMS abzurechnen, heute lediglich je übertragenem Datenvolumen (insofern keine Flatrate vorhanden ist).

Nun ist es leider so, dass dieser JOYN Dienst penetrant nervt, das Handy vibrieren lässt und einem ständig durch Notifications/Statusmeldungen in den Glauben bringt, man hätte gerade eine SMS empfangen. Dies passiert z.B. wenn ein WLAN gefunden wurde. Es passiert auch nachts wenn die WLAN Verbindung mal zusammenbricht. Dies kann fürchterlich nerven

Prämissen

Zunächst sollte die neuste Android Version des Anbieters installiert sein.

Ansatz

In den Menüs der neuen Android Version (hier im Beispiel ein Galaxy S4 mit D1 Vertrag) befindet sich ein Eintrag um JOYN zu deaktivieren.

Lösung für Galaxy S4 mit Telekom D1 Branding

  1. Bild 1: Menü -> Einstellungen (links unten der Button unterhalb des Display)
  2. Bild 2: Verbindungen -> Weitere Einstellungen
  3. Bild 3: JOYN-Dienste
  4. Bild 4: Haken bei JOYN Dienste rausnehmen

wpid-screenshot_2014-04-20-12-51-59.png

wpid-screenshot_2014-04-20-12-52-15.png

wpid-screenshot_2014-04-20-12-52-21.png

wpid-screenshot_2014-04-20-12-52-29.png

Fazit

Das Problem von Custom ROMs die speziell von Mobilfunkanbietern angefertigt und ausgeliefert werden ist nicht nur, das man später in den Besitz der neusten Android Version kommt, sondern auch die nicht-vorhandene Community, die mit leidenschaft Updates und Funktionen in integriert und idealistisch fehlerfreie Software in kurzer Zeit bereitstellt.

Android SDK: Easteregg: Entwickler-Optionen ausgeblendet / Developer Options not shown

Problem

Bei neueren Samsung Geräten wie dem Samsung Galaxy S4 oder Galaxy Tab 3 ist der Punkt „Entwickler-Optionen“ verschwunden, der einem das USB Debugging mit dem Android ADK ermöglicht.

Ansatz

Die Entwickleroptionen sind nun in Form eines Eastereggs unter „Einstellungen > Infos zu Gerät“ oder „Settings > About“ verschoben worden.

Lösung / Solution

Im About / Info-Bidlschirm 7x auf die Build-Nummer klicken. Es erscheint die Meldung „You are now Developer“.

Click 7 times on the Build number in the About Screen to enable the Developer Settings.

Android SDK: Accelerate or Speed up Android Emulator / Schnellerer Android Emulator

Problem

Wer mit dem Android SDK, dem Android Update Manager und den zahlreichen ADK Tools für Eclipse bereits Apps entwickeln durfte, hat sich mit Sicherheit schon über den langsamen Android Emulator geärgert. Welche Möglichkeiten gibt es die Geschwindigkeit zu verbessern?

Programmers who are using the Android Emulator that comes with the Android ADK should already have mentioned that the speed of the emulator is not what you would expect when developing apps in a sophisticated environment. This article describes one way to speed up the Android Emulator

Prämissen / Premisse

Um die beschriebene Vorgehensweise dieses Artikels nachvollziehen zu können benötigen Sie einen Intel x86 Prozessor.

To take advantage of this article your developer computer must have an Intel x86 Architecture.

Ansatz / Approach

Im BIOS des Intel x86 Rechners gibt es in dem Menü Advanced die Möglichkeit die Intel Virtualization Technology (Vt-X) zu aktivieren, welche nach der Installation zusätzlicher Softwarekomponenten genutzt werden kann

Intel provides the so called VT-X Technology, that can be enabled in the BIOS of the Intel x86 Architecture. Additionally some software components should be installed

Lösung / Solution

  1. Starten Sie ihren Rechner neu und gehen sie vor dem Erscheinen des Windows-Bildschirms in ihr BIOS (normalerweise Drücken von F2 oder ENTF/DEL)
  2. Suchen Sie den Punkt „Intel Virtualization Technology“ oder „VT-X“ und setzen sie den Schalter von Disabled auf Enabled
  3. Starten Sie in dem Eclipse ihren Android SDK Manager.
  4. Unter Extras aktivieren sie das Häkchen bei „HAXM Intel Acceleration Technolgy“
  5. Gehen sie in das Verzeichnis ihres Android SDKs unter Extras -> Intel -> HAXM…. -> installieren Haxm*.exe (das passiert nicht automatisch auf wenn das SDK „installed“ anzeigt)
  6. Wählen sie unter ihrem installiertem API-Order (API17, API18….) das Intel Atom x86 Image zusätzlich zu dem ARM Image aus und installieren sie es
  7. Erstellen Sie ein neues virtuelles Gerät, wählen sie unter CPU das x86 Image aus
  8. Stellen sie die RUN-Configuration des Android Eclipse Projectes mit dem Target auf das neue Gerät
  9. Wenn alles funktioniert sagt ihnen Eclipse „HAX is working and emulator runs in fast virt mode“

If you need a detailed explaination please visit this site:

http://software.intel.com/en-us/articles/speeding-up-the-android-emulator-on-intel-architecture

Android&PHP Backend: Netzwerkkommunikation, Authentifizierung und Login

Aufgabenstellung

Es wird eine Möglichkeit gesucht eine Android App mit einen PHP Backend kommunizieren zu lassen

Intention

PHP mit MySQL Server erhält man oft schon mit billigem Webspace. Ein weiterer Vorteil eines fertigen Webpacks/Webspace ist, dass es nicht notwendig wird sich um eine Backupstrategie zu kümmern. In den meisten Fällen (SLAs und AGBs des Providers studieren) liegt dieses Problem in den Händen des Providers. Er kümmert sich auch um die Sicherheit des Servers. Bei Hackerattacken ist man nicht in der Verantwortung den Server zu härten und zu schützen. Daher kann der Provider auch keine Schadensersatzansprüche gegen den Kunden geltend machen, wenn ein Server gekapert wird und z.B. mit der Installation eines Botnetzes die Leistungsfähigkeit des Rechenzentrums beeinträchtigt ist.

Ansatz

  • Implementierung eines möglichst einfachen Authentifierungsmechanismus in PHP mit MySQL-Anbindung
  • Wegkapseln der Serviceaufrufe
  • Asynchrone Verarbeitung der JSON Aufrufe per Java Thread
    • Reaktion in der MainActivity beim Erhalten des Service-Ergebnisses für UI Manipulationen

Der häufigste Ansatz, den man in Tutorials findet, ist die Kommunikation über JSON, einem kompakten Datenformat in für Mensch und Maschine einfach lesbarer Textform zum Zweck des Datenaustauschs zwischen Anwendungen.

Lösung

BjoernServiceCaller.java – Klasse für weggekapselte Service aufrufe mit CallBack-Funktionalität über onLoginResult

package com.caprisoft.contactupload.services;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import com.caprisoft.contactupload.MainActivity;

import android.content.Context;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;


public class BjoernsServiceCaller 
{
	
	final String authenticationURL = "authenticationservice.php";
	private static BjoernsServiceCaller instance = null;
	private BjoernsServiceCaller() 	{}
	

    /**
     * Statische Methode, liefert die einzige Instanz dieser
     * Klasse zurück
     */
    public static BjoernsServiceCaller getInstance() 
    {
        if (instance == null) 
        {
            instance = new BjoernsServiceCaller();
        }
        return instance;
    }
	
	
	public void loginUser(final MainActivity ctx, 
                                    final String email, final String password) 
	{
        Thread t = new Thread()
        {
	        public void run() 
	        {
                        //For Preparing Message Pool for the child Thread
		        Looper.prepare(); 
				
		        HttpClient client = new DefaultHttpClient();
                         //Timeout Limit
		        HttpConnectionParams
                               .setConnectionTimeout(client.getParams(), 10000);
		        HttpResponse response;
		        JSONObject json = new JSONObject();
		        try
		        {
		            HttpPost post = new HttpPost(authenticationURL);
		            json.put("email", email);
		            json.put("password", password);
		            StringEntity se = new StringEntity( json.toString());  
		            se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
                                          application/json"));
		            post.setEntity(se);
		            response = client.execute(post);
		            /*Checking response */
		            if(response!=null)
		            {
		                BufferedReader reader = new BufferedReader
                                (
                                    new InputStreamReader
                                    (
                                       response.getEntity().getContent(), "UTF-8"
                                    )
                                );
		                String derText = reader.readLine();
                                // CallBack aufruf in MainActivity
		                ctx.onLoginResult(derText);
		            }
		
		        }
		        catch(Exception e)
		        {
		            e.printStackTrace();
		        }
		        Looper.loop(); //Loop in the message queue
	        }
        };
        t.start();          
    }
}

authenticationservice.php – Das PHP Backend, was die Datenbankabfragen macht und auf jedem Billigwebspace läuft

<?php  
    include("configuration/database.php");
	$json = file_get_contents('php://input');
	$obj = json_decode($json);
	$result2=mysql_query("SELECT id, activationcode FROM users ".
                                      "WHERE email='".$obj->{'email'}."' AND ".
                                      "password='".$obj->{'password'}."'") 
                                       or die(mysql_error());
	
	$user="nouser";
	while ($row = mysql_fetch_array($result2, MYSQL_NUM)) {
	   $user=$row[0];
	   $activationcode=$row[1];
	}	
    
    $posts = array(1);
    
    if($user!="nouser")
    {
    	if($activationcode=="activated")
    	{
    		session_start();
    		session_register("userid");
    		$_SESSION["userid"] =$user;
    		header('Content-type: application/json');
    		echo "success";
    	}
    	else 
    	{
    	   $registrationcode=substr(md5($obj->{'email'}." ".$obj->{'password'}),6);
    	   mysql_query("UPDATE users SET activationcode='".$registrationcode.
           "' WHERE email='".$obj->{'email'}."'") or die(mysql_error());
    	   mail($obj->{'email'},"Registrationcode for contactupload.com",
            "Hello!<br><br>\n You or someone else has registered this email ".
            "address via mobile phone.<br><br>\nThe generated registrationcode is ".
            $registrationcode.".<br><br>\nPlease type this registrationcode in ".
            "the register section of the contact sync app.<br><br> .
            "\nWith best regards,<br>\ncontactupload.com");
    		echo "not activated";
    	}
    }
    else 
    {
        echo "not registered";
    } 
    mysql_close($con);
?>

MainActivity.java – Die Klasse präsentiert den Code der Benutzeroberfläche der Activity (VIEW)

package com.caprisoft.contactupload;

import com.caprisoft.contactupload.services.BjoernsServiceCaller;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
	
	private EditText email = null;
	private EditText passwort = null;
	
	/** Called when the user selects the Send button */
	public void onClickLoginButton(View view) {
	    // Do something in response to button
		Log.d(this.getClass().toString(), "Login Button gedrückt!");
		BjoernsServiceCaller.
                getInstance().
                loginUser
                (
                    this, 
                    email.getText().toString(), 
                    passwort.getText().toString()
                );
	}
	
	/** Called when the user selects the Send button */
	public void onClickRegisterButton(View view) {
	    // Do something in response to button
		Log.d(this.getClass().toString(), "Register Button gedrückt!");
	}	
	
	public void onLoginResult(String text)
	{
		Toast.makeText(this, "HALLO: "+text, Toast.LENGTH_LONG).show();
	}

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        email = (EditText) findViewById(R.id.textUsername);
        passwort = (EditText) findViewById(R.id.textPassword);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    
}

Activity_main.xml – Das eigentliche Frontend

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/labelUsername"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/labelUsername"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    
  <EditText android:id="@+id/textUsername"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:inputType="textNoSuggestions"
        android:hint="@string/hintUsername" />
  
   <TextView
        android:id="@+id/labelPassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/labelPassword"
        android:textAppearance="?android:attr/textAppearanceLarge" />
      
   <EditText android:id="@+id/textPassword"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:inputType="textPassword"
        android:hint="@string/hintPassword" />

   <Button
       android:id="@+id/buttonLogin"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:onClick="onClickLoginButton"
       android:text="@string/buttonLogin" />

   <Button
       android:id="@+id/buttonRegister"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:onClick="onClickRegisterButton"
       android:text="@string/buttonRegister" />
  
</LinearLayout>

AndroidManifest.xml – Permission für den Zugriff auf das Internet einrichten

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.caprisoft.contactupload"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
     <uses-permission android:name="android.permission.INTERNET" /> 
    <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>
    </application>
</manifest>