commit fb46d0a62f950dbaff780f5c86d719e7c16e32f0
Author: dankert <devnull@localhost>
Date: Wed, 28 Sep 2011 22:34:57 +0200
Erste Version des Blogging-Clients.
Diffstat:
14 files changed, 644 insertions(+), 0 deletions(-)
diff --git a/.classpath b/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/.project b/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>Blog1</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="de.openrat.android.blog"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+ <activity android:name=".OpenRatBlog"
+ 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="Configuration"></activity>
+</application>
+
+
+</manifest> +
\ No newline at end of file
diff --git a/default.properties b/default.properties
@@ -0,0 +1,13 @@
+# 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 use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Indicates whether an apk should be generated for each density.
+split.density=false
+# Project target.
+target=android-6
diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png
Binary files differ.
diff --git a/res/drawable-ldpi/icon.png b/res/drawable-ldpi/icon.png
Binary files differ.
diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png
Binary files differ.
diff --git a/res/layout/main.xml b/res/layout/main.xml
@@ -0,0 +1,12 @@
+<?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"
+ >
+<TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/hello"
+ />
+</LinearLayout>
diff --git a/res/menu/main.xml b/res/menu/main.xml
@@ -0,0 +1,4 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_preferences" android:title="@string/preferences"></item>
+</menu>
+ +
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="hello">Hello World, OpenRatBlog!</string>
+ <string name="app_name"></string>
+<string name="preferences">Einstellungen</string>
+</resources>
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+<PreferenceCategory><EditTextPreference android:key="server" android:title="Server"></EditTextPreference>
+</PreferenceCategory>
+</PreferenceScreen>
diff --git a/src/de/openrat/android/blog/Configuration.java b/src/de/openrat/android/blog/Configuration.java
@@ -0,0 +1,15 @@
+package de.openrat.android.blog;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class Configuration extends PreferenceActivity
+{
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+}
diff --git a/src/de/openrat/android/blog/OpenRatBlog.java b/src/de/openrat/android/blog/OpenRatBlog.java
@@ -0,0 +1,128 @@
+package de.openrat.android.blog;
+
+import java.io.IOException;
+
+import org.json.JSONObject;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import de.openrat.android.blog.client.CMSRequest;
+
+public class OpenRatBlog extends Activity
+{
+ private static final String PREFS_NAME = "OR_BLOG_PREFS";
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ CMSRequest request = new CMSRequest("demo.openrat.de");
+
+ request.setParameter("action", "index");
+ request.setParameter("subaction", "login");
+ request.setParameter("dbid", "db1");
+ request.setParameter("login_name", "admin");
+ request.setParameter("login_password", "admin");
+ String response = null;
+ try
+ {
+ response = request.performRequest();
+
+ } catch (IOException e)
+ {
+ response = e.getMessage();
+ }
+
+ try
+ {
+ JSONObject json = new JSONObject(response);
+ JSONObject session = json.getJSONObject("session");
+ final String sessionName = session.getString("name");
+ final String sessionId = session.getString("id");
+
+ final String msgText = json.getJSONArray("notices")
+ .getJSONObject(0).getString("text");
+// final String msgText2 = json.getJSONArray("notics")
+// .getJSONObject(0).getString("text");
+
+ // TextView text = new TextView(this);
+ // text.setText("Sitzung '" + sessionId + "': " + sessionId);
+
+ request.setCookie(sessionName, sessionId);
+ TextView tv = new TextView(this);
+ tv.setVerticalScrollBarEnabled(true);
+ tv.setHorizontalScrollBarEnabled(true);
+ tv.setScrollBarStyle(TextView.SCROLLBARS_INSIDE_INSET);
+ tv.setText(msgText + "\nSitzung '" + sessionName + "': "
+ + sessionId + "\nAusgabe: " + response);
+
+ ScrollView scrollView =new ScrollView(this);
+ scrollView.setScrollContainer(true);
+ scrollView.setFocusable(true);
+ scrollView.addView(tv);
+
+ setContentView(scrollView);
+
+ } catch (Exception e)
+ {
+ response = e.getMessage();
+
+ TextView tv = new TextView(this);
+ tv.setText("Fehler: " + response);
+ setContentView(tv);
+
+ }
+
+ // Restore preferences
+ // SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
+ // boolean silent = settings.getBoolean("silentMode", false);
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ super.onCreateOptionsMenu(menu);
+ MenuInflater mi = new MenuInflater(getApplication());
+ mi.inflate(R.menu.main, menu);
+
+ return true;
+ }
+
+
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch (item.getItemId())
+ {
+ case R.id.menu_preferences:
+ startActivity( new Intent(this,Configuration.class));
+ }
+ return false;
+ }
+
+ @Override
+ protected void onStop()
+ {
+ super.onStop();
+
+ // Save user preferences. We need an Editor object to
+ // make changes. All objects are from android.context.Context
+ SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
+ SharedPreferences.Editor editor = settings.edit();
+ // editor.putBoolean("silentMode", mSilentMode);
+
+ // Don't forget to commit your edits!!!
+ editor.commit();
+ }
+
+}+
\ No newline at end of file
diff --git a/src/de/openrat/android/blog/client/CMSRequest.java b/src/de/openrat/android/blog/client/CMSRequest.java
@@ -0,0 +1,396 @@
+/*
+OpenRat Java-Client
+Copyright (C) 2009 Jan Dankert
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the
+Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+Boston, MA 02110-1301, USA.
+
+ */
+package de.openrat.android.blog.client;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * API-Request to the OpenRat Content Management System. <br>
+ * <br>
+ * The call to the CMS server is done via a (non-SSL) HTTP connection.<br>
+ * <br>
+ * Before a call you are able to set some key/value-pairs as parameters. After calling the CMS a
+ * DOM-document is returned, which contains the server response.<br>
+ * Example <br>
+ *
+ * <pre>
+ * CMSRequest request = new CMSRequest("your.openrat.example.com");
+ * //prints tracing information to stdout.
+ * request.trace = true;
+ * try {
+ * request.parameter.put("action", "index");
+ * request.parameter.put("subaction", "showlogin"); // login page
+ * request.parameter.put("...", "...");
+ * Document response = request.call();
+ * // now traverse through the dom tree and get your information.
+ * }
+ * catch (IOException e) {
+ * // your error handling.
+ * }
+ * </pre>
+ *
+ * @author Jan Dankert
+ */
+public class CMSRequest {
+
+ // some constants...
+ private static final String CHARSET_UTF8 = "UTF-8";
+ private static final String HTTP_GET = "GET";
+ private static final String HTTP_POST = "POST";
+
+ /**
+ * if <code>true</code>, Tracing-Output will be logged to stdout. Default: <code>false</code>.
+ */
+ // this is public, for easier use.
+ public boolean trace = false;
+
+ /**
+ * HTTP-method, must be "GET" or "POST", default: "GET".
+ */
+ private String method = HTTP_GET;
+
+ /**
+ * Parameter map.
+ */
+ private Map<String, String> parameter = new HashMap<String, String>();
+
+ private String serverPath;
+ private String serverHost;
+ private int serverPort;
+
+ private String proxyHostname;
+ private int proxyPort;
+ private SocketAddress socketAddress;
+
+ private String cookieName;
+ private String cookieValue;
+ private String language;
+
+
+ /**
+ *
+ */
+ public CMSRequest()
+ {
+ super();
+ this.language = Locale.getDefault().getLanguage();
+ }
+
+ public String getLanguage()
+ {
+ return language;
+ }
+
+ public void setLanguage(String language)
+ {
+ this.language = language;
+ }
+
+ /**
+ * Setting a HTTP-Cookie.
+ *
+ * @param name name
+ * @param value value
+ */
+ public void setCookie(String name, String value) {
+
+ this.cookieName = this.urlEncode(name);
+ this.cookieValue = this.urlEncode(value);
+ }
+
+ /**
+ * URL-Encoder.
+ *
+ * @param value
+ * @return url-encoded value
+ */
+ private String urlEncode(String value) {
+
+ try {
+ return URLEncoder.encode(value, CHARSET_UTF8);
+ }
+ catch (UnsupportedEncodingException e) {
+ // maybe... this would be strange
+ throw new IllegalStateException(CHARSET_UTF8 + " ist not supported by this VM");
+ }
+ }
+
+ /**
+ * Setting a HTTP-Proxy.
+ *
+ * @param host hostname
+ * @param port port
+ */
+ public void setProxy(String host, int port) {
+
+ this.proxyHostname = host;
+ this.proxyPort = port;
+ }
+
+ /**
+ * Set the HTTP Method. Default is "GET".
+ *
+ * @param method HTTP-method
+ */
+ public void setMethod(String method) {
+
+ if (!HTTP_GET.equalsIgnoreCase(method) && !HTTP_POST.equalsIgnoreCase(method))
+ throw new IllegalArgumentException("Method must be '" + HTTP_POST + "' or '" + HTTP_GET
+ + "'.");
+
+ this.method = method.toUpperCase();
+ }
+
+ /**
+ * Clear parameter values.
+ */
+ public void clearParameters() {
+
+ parameter.clear();
+ }
+
+ /**
+ * Setting a parameter value. <strong>DO NOT url-encode your values</strong> as this is done
+ * automatically inside this method!
+ *
+ * @param paramName name
+ * @param paramValue value
+ */
+ public void setParameter(String paramName, String paramValue) {
+
+ if (paramName == null || paramValue == null || "" == paramName)
+ throw new IllegalArgumentException("parameter name and value must have values");
+
+ parameter.put(paramName, paramValue);
+ }
+
+ /**
+ * Constructs a CMS-Request to the specified server.<br>
+ * Server-Path is "/", Server-Port is 80.
+ *
+ * @param host hostname
+ */
+ public CMSRequest(String host) {
+
+ super();
+ this.serverHost = host;
+ this.serverPath = "/";
+ this.serverPort = 80;
+ }
+
+ /**
+ * Constructs a CMS-Request to the specified server/path.<br>
+ * Server-Port is 80.
+ *
+ * @param host hostname
+ * @param path path
+ */
+ public CMSRequest(String host, String path) {
+
+ super();
+ this.serverHost = host;
+ this.serverPath = path;
+ this.serverPort = 80;
+ }
+
+ /**
+ * Constructs a CMS-Request to the specified server/path/port.
+ *
+ * @param host hostname
+ * @param path path
+ * @param port port-number
+ */
+ public CMSRequest(String host, String path, int port) {
+
+ super();
+ this.serverHost = host;
+ this.serverPath = path;
+ this.serverPort = port;
+ }
+
+ /**
+ * Sends a request to the openrat-server and parses the response into a DOM tree document.
+ *
+ * @return server response as a DOM tree
+ * @throws IOException if server is unrechable or responds non-wellformed XML
+ */
+ public String performRequest() throws IOException {
+
+ final Socket socket = new Socket();
+
+ try {
+
+ final boolean useProxy = this.proxyHostname != null;
+ final boolean useCookie = this.cookieName != null;
+
+ if (serverPath == null)
+ this.serverPath = "/";
+ if (!serverPath.startsWith("/"))
+ this.serverPath = "/" + this.serverPath;
+
+ // When a client uses a proxy, it typically sends all requests to that proxy, instead
+ // of to the servers in the URLs. Requests to a proxy differ from normal requests in one
+ // way: in the first line, they use the complete URL of the resource being requested,
+ // instead of just the path.
+ if (useProxy) {
+ socketAddress = new InetSocketAddress(this.proxyHostname, this.proxyPort);
+ } else {
+ socketAddress = new InetSocketAddress(this.serverHost, serverPort);
+ }
+
+ socket.setKeepAlive(false);
+ socket.setReuseAddress(false);
+ socket.connect(socketAddress, 5000);
+
+ final StringBuffer header = new StringBuffer();
+
+ final StringBuffer parameterList = new StringBuffer();
+
+ for (Entry<String, String> entry : this.parameter.entrySet()) {
+ if (parameterList.length() > 0)
+ parameterList.append("&");
+ parameterList.append(this.urlEncode(entry.getKey()));
+ parameterList.append("=");
+ parameterList.append(this.urlEncode(entry.getValue()));
+ }
+
+ String httpUrl = this.serverPath;
+
+ if (useProxy)
+ // See RFC 2616 Section 5.1.2 "Request-URI"
+ // "The absolute URI form is REQUIRED when the request is being made to a proxy"
+ httpUrl = "http://" + this.serverHost + httpUrl;
+
+ if (HTTP_GET.equals(this.method))
+ httpUrl = httpUrl + "?" + parameterList;
+
+ // using HTTP/1.0 as this is supported by all HTTP-servers and proxys.
+ // We have no need for HTTP/1.1 at the moment.
+ header.append(this.method + " " + httpUrl + " HTTP/1.0\n");
+
+ // Setting the HTTP Header
+ header.append("Host: " + this.serverHost + "\n");
+ header.append("User-Agent: Mozilla/5.0; compatible (OpenRat android-client)\n");
+ header.append("Accept: application/json\n");
+ header.append("Accept-Language: " + language + "\n");
+ header.append("Accept-Charset: utf-8\n");
+ header.append("Connection: close\n");
+ if (useCookie)
+ header.append("Cookie: " + cookieName + "=" + cookieValue + "\n");
+
+ if (HTTP_POST.equals(this.method)) {
+ header.append("Content-Type: application/x-www-form-urlencoded" + "\n");
+ header.append("Content-Length: " + parameterList.length() + "\n");
+ }
+
+ header.append("\n");
+
+ if (HTTP_POST.equals(this.method))
+ header.append(parameterList);
+
+ if (this.trace)
+ System.out.println("--- request ---");
+ if (this.trace)
+ System.out.println(header.toString());
+
+ final PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
+ printWriter.write(header.toString());
+ printWriter.flush();
+
+ final InputStream inputStream = socket.getInputStream();
+ final int available = inputStream.available();
+
+ final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket
+ .getInputStream()));
+
+ final String httpResponse = bufferedReader.readLine().trim();
+ final String httpRetCode = httpResponse.substring(9, 12);
+
+ if (this.trace)
+ System.out.println("--- response ---");
+ if (this.trace)
+ System.out.println(httpResponse);
+
+ // Check if we got the status 200=OK.
+ if (!httpRetCode.equals("200")) {
+
+ // non-200-status seems to be an error.
+ throw new IOException("No HTTP 200: Status=" + httpRetCode + " (" + httpResponse
+ + ")");
+ }
+
+ while (true) {
+
+ String responseHeader = bufferedReader.readLine().trim();
+
+ if (responseHeader.equals(""))
+ break;
+
+ if (this.trace)
+ System.out.println(responseHeader);
+ }
+
+ StringBuffer response = new StringBuffer();
+ while (bufferedReader.ready()) {
+
+ response.append(bufferedReader.readLine() + "\n");
+ }
+ socket.close();
+
+ if (this.trace)
+ System.out.println("--- response body ---");
+ if (this.trace)
+ System.out.println(response + "\n\n\n");
+
+ return response.toString();
+ }
+ finally {
+ try {
+ socket.close(); // Clean up the socket.
+ }
+ catch (IOException e) {
+ // We have done our very best.
+ }
+ }
+ }
+}