Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: leenookx/speng-droid
base: 0062d73d62
...
head fork: leenookx/speng-droid
compare: 932d99c487
Checking mergeability… Don't worry, you can still create the pull request.
  • 19 commits
  • 20 files changed
  • 0 commit comments
  • 1 contributor
View
17 .classpath
@@ -1,7 +1,10 @@
-<?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>
+<?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="lib" path="lib/acra-3.1.0.jar"/>
+ <classpathentry kind="lib" path="lib/jdom.jar"/>
+ <classpathentry kind="lib" path="lib/rome-1.0.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
15 AndroidManifest.xml
@@ -2,8 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.co.purplemonkeys.spengler"
android:versionCode="1"
- android:versionName="1.0">
- <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
+ android:versionName="v0.0.3" android:installLocation="preferExternal">
+ <application android:icon="@drawable/icon"
+ android:label="@string/app_name"
+ android:debuggable="true"
+ android:name="SpengApp">
<activity android:name=".SpengDroid"
android:label="@string/app_name">
<intent-filter>
@@ -19,6 +22,14 @@
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
+
+ <activity android:name=".Preferences" android:label="@string/app_name"></activity>
+
+ <activity android:name="org.acra.CrashReportDialog"
+ android:theme="@android:style/Theme.Dialog"
+ android:launchMode="singleInstance"
+ android:excludeFromRecents="true"
+ android:finishOnTaskLaunch="true" />
</application>
<uses-sdk android:minSdkVersion="7" />
View
BIN  lib/acra-3.1.0.jar
Binary file not shown
View
BIN  lib/jdom.jar
Binary file not shown
View
BIN  lib/rome-1.0.jar
Binary file not shown
View
15 res/layout/main.xml
@@ -4,9 +4,14 @@
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"
- />
+
+ <Button android:id="@+id/goButton"
+ android:text="Go"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ <ListView android:id="@+id/ListView"
+ android:layout_weight="1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
</LinearLayout>
View
12 res/layout/share_link.xml
@@ -22,6 +22,18 @@
android:inputType="text|textMultiLine|textCapSentences"
android:gravity="top|left"
/>
+ <TextView android:id="@+id/submit_link_title_label"
+ android:text="@string/submit_link_title_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="4dip"
+ />
+ <EditText android:id="@+id/submit_link_title"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:minLines="2"
+ android:inputType="text|textMultiLine|textCapSentences"
+ />
<TextView android:id="@+id/submit_link_description_label"
android:text="@string/submit_link_description_label"
android:layout_width="wrap_content"
View
20 res/menu/spengdroid.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <group android:id="@+id/MAIN_MENU">
+ <item android:id="@+id/preferences_menu_id"
+ android:title="@string/menu_preferences"
+ android:alphabeticShortcut="p"
+ android:icon="@android:drawable/ic_menu_preferences"
+ />
+ <item android:id="@+id/about_menu_id"
+ android:title="@string/menu_about"
+ android:alphabeticShortcut="a"
+ android:icon="@android:drawable/ic_menu_info_details"
+ />
+ <item android:id="@+id/refresh_feed_menu_id"
+ android:title="@string/menu_refresh_feed"
+ android:alphabeticShortcut="r"
+ android:icon="@android:drawable/ic_menu_rotate"
+ />
+ </group>
+</menu>
View
26 res/values/strings.xml
@@ -1,10 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="hello">Hello World, SpengDroid!</string>
<string name="app_name">SpengDroid</string>
-<string name="submit_link_url_label">URL</string>
-<string name="submit_link_description_label">Description</string>
-<string name="submit_link_keywords_label">Keywords</string>
-<string name="submit_button">Submit</string>
-<string name="error_toast">Error! Don\'t panic!</string>
+ <string name="submit_link_url_label">URL</string>
+ <string name="submit_link_description_label">Description</string>
+ <string name="submit_link_keywords_label">Keywords</string>
+ <string name="submit_button">Submit</string>
+ <string name="error_toast">Error! Don\'t panic!</string>
+ <string name="submit_link_title_label">Title</string>
+ <string name="menu_preferences">Preferences</string>
+ <string name="menu_about">About</string>
+
+ <string name="crash_notif_ticker_text">Unexpected error, please send a report...</string>
+ <string name="crash_notif_title">SpengDroid has crashed...</string>
+ <string name="crash_notif_text">Please click here to help fix the issue.</string>
+
+ <string name="crash_dialog_title">SpengDroid has crashed</string>
+ <string name="crash_dialog_text">An unexpected error occurred forcing the
+ application to stop. Please help us fix this by sending us error data,
+ all you have to do is click \'OK\'.</string>
+ <string name="crash_dialog_comment_prompt">You might add your comments about the problem below:</string>
+ <string name="crash_dialog_ok_toast">Thank you !</string>
+ <string name="menu_refresh_feed">Refresh feed</string>
</resources>
View
13 res/xml/preferences.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ <EditTextPreference android:name="URL"
+ android:summary="Where to find the Spengler installation."
+ android:defaultValue="http://localhost:3000"
+ android:title="URL"
+ android:key="pref_url" />
+ <EditTextPreference android:name="auth_code"
+ android:summary="Your unique authentication code."
+ android:defaultValue="abc123"
+ android:title="Authentication Code"
+ android:key="pref_auth_code" />
+</PreferenceScreen>
View
37 src/uk/co/purplemonkeys/common/Common.java
@@ -0,0 +1,37 @@
+package uk.co.purplemonkeys.common;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.widget.Toast;
+
+public class Common
+{
+ public static void ShowErrorToast(Context context, String error, int duration)
+ {
+ Toast toast = Toast.makeText(context, error, duration);
+ toast.setDuration( duration );
+ toast.show();
+ }
+
+ public static void ShowAlertMessage(Context c, String message)
+ {
+ // Create the alert box
+ AlertDialog.Builder alertbox = new AlertDialog.Builder(c);
+
+ // Set the message to display
+ alertbox.setMessage( message );
+
+ // Add a neutral button to the alert box and assign a click listener
+ alertbox.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface arg0, int arg1) {
+ // We don't really care about this here...
+ }
+ });
+
+ // show the alert box
+ alertbox.show();
+ }
+}
View
79 src/uk/co/purplemonkeys/common/XmlResponseParser.java
@@ -0,0 +1,79 @@
+package uk.co.purplemonkeys.common;
+
+import java.io.IOException;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.EntityUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import android.util.Log;
+
+/**
+ * Contains all parser creation and exception handling logic, for parsers
+ * that consume an HttpEntity stream and produce a single object as a result.
+ *
+ * XXX - does not provide a way to return a result before input is completely consumed
+ *
+ * @author spapadim
+ *
+ */
+public abstract class XmlResponseParser<T>
+{
+ private final String TAG = "XmlResponseParser";
+ private HttpEntity e;
+ private T result;
+
+ private XmlPullParserFactory mXmlParserFactory;
+
+ public XmlResponseParser (HttpEntity e) { this.e = e; }
+
+ public void setResult (T result) { this.result = result; }
+ public T getResult () { return result; }
+
+ /**
+ * Handle an XML event from the parser.
+ * @return False if parsing is complete, true otherwise
+ */
+ abstract public boolean onXmlEvent (XmlPullParser parser, int eventType) throws XmlPullParserException, IOException;
+
+ public void onInit (XmlPullParser parser) { }
+
+ public T parse () {
+ try {
+ XmlPullParser parser = getXmlParser(e);
+ onInit(parser);
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (!onXmlEvent(parser, eventType)) {
+ break;
+ }
+ eventType = parser.next();
+ }
+ } catch (Throwable t) {
+ Log.e(TAG, "XmlResponseParser exception", t);
+ setResult(null);
+ } finally {
+ try {
+ e.consumeContent();
+ } catch (Throwable t2) { }
+ }
+ return getResult();
+ }
+
+ private final XmlPullParser getXmlParser (HttpEntity e) throws XmlPullParserException, IllegalStateException, IOException
+ {
+ if (mXmlParserFactory == null) {
+ mXmlParserFactory = XmlPullParserFactory.newInstance();
+ }
+ XmlPullParser parser = mXmlParserFactory.newPullParser();
+ String charSet = EntityUtils.getContentCharSet(e);
+ if (charSet == null) {
+ charSet = HTTP.DEFAULT_CONTENT_CHARSET;
+ }
+ parser.setInput(e.getContent(), charSet);
+ return parser;
+ }
+}
View
31 src/uk/co/purplemonkeys/common/http/GzipDecompressingEntity.java
@@ -0,0 +1,31 @@
+package uk.co.purplemonkeys.common.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.entity.HttpEntityWrapper;
+
+public class GzipDecompressingEntity extends HttpEntityWrapper
+{
+ public GzipDecompressingEntity(final HttpEntity entity)
+ {
+ super(entity);
+ }
+
+ @Override
+ public InputStream getContent() throws IOException, IllegalStateException
+ {
+ // the wrapped entity's getContent() decides about repeatability
+ InputStream wrappedin = wrappedEntity.getContent();
+ return new GZIPInputStream(wrappedin);
+ }
+
+ @Override
+ public long getContentLength()
+ {
+ // length of ungzipped content is not known
+ return -1;
+ }
+}
View
68 src/uk/co/purplemonkeys/common/http/HttpCommon.java
@@ -0,0 +1,68 @@
+package uk.co.purplemonkeys.common.http;
+
+import java.io.IOException;
+
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.protocol.HttpContext;
+
+
+public class HttpCommon
+{
+
+ public static DefaultHttpClient createGzipHttpClient()
+ {
+ BasicHttpParams params = new BasicHttpParams();
+ SchemeRegistry schemeRegistry = new SchemeRegistry();
+ schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
+
+ DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);
+
+ httpclient.addRequestInterceptor(new HttpRequestInterceptor()
+ {
+ public void process(final HttpRequest request,
+ final HttpContext context) throws HttpException, IOException {
+ if (!request.containsHeader("Accept-Encoding")) {
+ request.addHeader("Accept-Encoding", "gzip");
+ }
+ }
+ });
+
+ httpclient.addResponseInterceptor(new HttpResponseInterceptor()
+ {
+ public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException
+ {
+ HttpEntity entity = response.getEntity();
+ Header ceheader = entity.getContentEncoding();
+ if (ceheader != null)
+ {
+ HeaderElement[] codecs = ceheader.getElements();
+ for (int i = 0; i < codecs.length; i++)
+ {
+ if (codecs[i].getName().equalsIgnoreCase("gzip"))
+ {
+ response.setEntity(new GzipDecompressingEntity(response.getEntity()));
+ return;
+ }
+ }
+ }
+ }
+ });
+
+ return httpclient;
+ }
+}
View
22 src/uk/co/purplemonkeys/spengler/Common.java
@@ -1,22 +0,0 @@
-package uk.co.purplemonkeys.spengler;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-import android.widget.Toast;
-
-public class Common
-{
- static void showErrorToast(String error, int duration, Context context)
- {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- Toast t = new Toast(context);
- t.setDuration(duration);
- View v = inflater.inflate(R.layout.error_toast, null);
- TextView errorMessage = (TextView) v.findViewById(R.id.errorMessage);
- errorMessage.setText(error);
- t.setView(v);
- t.show();
- }
-}
View
14 src/uk/co/purplemonkeys/spengler/Preferences.java
@@ -0,0 +1,14 @@
+package uk.co.purplemonkeys.spengler;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class Preferences extends PreferenceActivity
+{
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+}
View
203 src/uk/co/purplemonkeys/spengler/ShareLink.java
@@ -1,8 +1,32 @@
package uk.co.purplemonkeys.spengler;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.json.JSONObject;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import uk.co.purplemonkeys.common.Common;
+import uk.co.purplemonkeys.common.XmlResponseParser;
+import uk.co.purplemonkeys.common.http.HttpCommon;
import android.app.Activity;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
@@ -11,6 +35,8 @@
public class ShareLink extends Activity
{
+ private final String TAG = "ShareLink";
+
@Override
public void onCreate(Bundle savedInstanceState)
{
@@ -28,6 +54,8 @@ public void onCreate(Bundle savedInstanceState)
String url = extras.getString(Intent.EXTRA_TEXT);
final EditText submitLinkUrl = (EditText) findViewById(R.id.submit_link_url);
submitLinkUrl.setText(url);
+ final EditText submitLinkTitle = (EditText) findViewById(R.id.submit_link_title);
+ submitLinkTitle.setText( fetchHtmlTitle(url) );
}
}
@@ -39,12 +67,14 @@ public void onClick(View v)
if (validateLinkForm())
{
final EditText submitLinkUrl = (EditText) findViewById(R.id.submit_link_url);
+ final EditText submitLinkTitle = (EditText) findViewById(R.id.submit_link_title);
final EditText submitLinkDescription = (EditText) findViewById(R.id.submit_link_description);
final EditText submitLinkKeywords = (EditText) findViewById(R.id.submit_link_keywords);
- new ShareLinkTask(
- submitLinkUrl.getText().toString(),
- submitLinkDescription.getText().toString(),
- submitLinkKeywords.getText().toString()).execute();
+ new ShareLinkTask(submitLinkUrl.getText().toString(),
+ submitLinkDescription.getText().toString(),
+ submitLinkKeywords.getText().toString(),
+ submitLinkTitle.getText().toString()
+ ).execute();
}
}
});
@@ -55,10 +85,173 @@ private boolean validateLinkForm()
final EditText urlText = (EditText) findViewById(R.id.submit_link_url);
if ("".equals(urlText.getText()))
{
- Common.showErrorToast("Please provide a URL.", Toast.LENGTH_LONG, this);
+ Common.ShowErrorToast(getApplicationContext(), "Please provide a URL.", Toast.LENGTH_LONG);
return false;
}
return true;
}
+
+ public final String fetchHtmlTitle(String url)
+ {
+ HttpGet get = new HttpGet(url);
+ DefaultHttpClient mHttpClient = HttpCommon.createGzipHttpClient();
+ HttpEntity e;
+ try
+ {
+ HttpResponse resp = mHttpClient.execute(get);
+ e = resp.getEntity();
+ }
+ catch (Throwable t) {
+ Log.d(TAG, "HTTP request failed", t);
+ return null;
+ }
+
+ XmlResponseParser<String> titleParser = new XmlResponseParser<String>(e)
+ {
+ @Override
+ public boolean onXmlEvent(XmlPullParser parser, int eventType) throws XmlPullParserException, IOException {
+ switch(eventType) {
+ case XmlPullParser.START_TAG:
+ String tagName = parser.getName().toLowerCase();
+ if ("title".equals(tagName))
+ {
+ // Handle HTML
+ setResult(parser.nextText());
+ return false;
+ }
+ else if ("card".equals(tagName))
+ {
+ // Handle WML - XXX - check that this is proper semantics
+ setResult(parser.getAttributeValue(null, "title"));
+ return false;
+ }
+ break;
+ }
+
+ return true;
+ }
+ };
+
+ return titleParser.parse();
+ }
+
+ private class ShareLinkTask extends AsyncTask<Void, Void, Object>
+ {
+ private final static String TAG = "SharedLinkTask";
+
+ private String _url;
+ private String _description;
+ private String _keywords;
+ private String _title;
+ private DefaultHttpClient mClient = HttpCommon.createGzipHttpClient();
+
+ ShareLinkTask(String url, String description, String keywords, String title)
+ {
+ _url = url;
+ _description = description;
+ _keywords = keywords;
+ _title = title;
+ }
+
+ @Override
+ public Object doInBackground(Void... unused_params)
+ {
+ HttpEntity entity = null;
+
+ try
+ {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+ String url = prefs.getString("pref_url", "http://localhost:3000");
+ String auth_code = prefs.getString("pref_auth_code", "abc123");
+
+ // Construct data
+ JSONObject post_params = new JSONObject();
+ post_params.put("auth_code", auth_code);
+
+ JSONObject sub = new JSONObject();
+ sub.put("url", _url);
+ sub.put("description", _description);
+ sub.put("keywords", _keywords);
+ sub.put("title", _title);
+
+ post_params.put("links", sub);
+
+ HttpPost httppost = new HttpPost(url + "/links");
+
+ // The progress dialog is non-cancelable, so set a shorter timeout than system's
+ HttpParams params = httppost.getParams();
+ HttpConnectionParams.setConnectionTimeout(params, 30000);
+ HttpConnectionParams.setSoTimeout(params, 30000);
+
+ StringEntity s = new StringEntity(post_params.toString());
+ s.setContentEncoding("UTF-8");
+ s.setContentType("application/json");
+ params.setParameter("authentication-token", auth_code);
+ httppost.setEntity(s);
+
+ // Perform the HTTP POST request
+ HttpResponse response = mClient.execute(httppost);
+ String status = response.getStatusLine().toString();
+ if (!status.contains("OK"))
+ {
+ throw new HttpException(status);
+ }
+
+ entity = response.getEntity();
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(entity.getContent()));
+ String line = in.readLine();
+ in.close();
+ if (line == null || "".equals(line))
+ {
+ throw new HttpException("No content returned from reply POST");
+ }
+
+ entity.consumeContent();
+
+ Common.ShowAlertMessage(getBaseContext(), "Success");
+
+ // TODO: Return something more meaningful later.
+ return new Object();
+ }
+ catch (Exception e)
+ {
+ if (entity != null)
+ {
+ try
+ {
+ entity.consumeContent();
+ }
+ catch (Exception e2) {
+ Log.e(TAG, "entity.consumeContent()", e2);
+ }
+ }
+
+ Log.e(TAG, "ShareLinkTask", e);
+ }
+
+ return null;
+ }
+
+ @Override
+ public void onPreExecute()
+ {
+ }
+
+ @Override
+ public void onPostExecute(Object result)
+ {
+ finish();
+
+ if (result != null)
+ {
+ Common.ShowErrorToast(getApplicationContext(), "Spengalised", Toast.LENGTH_SHORT);
+ }
+ else
+ {
+ Common.ShowErrorToast(getApplicationContext(), "Spengalisation failed!", Toast.LENGTH_LONG);
+ }
+ }
+ }
}
View
185 src/uk/co/purplemonkeys/spengler/ShareLinkTask.java
@@ -1,185 +0,0 @@
-package uk.co.purplemonkeys.spengler;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.http.Header;
-import org.apache.http.HeaderElement;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.entity.HttpEntityWrapper;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.HttpContext;
-import org.json.JSONObject;
-
-import android.os.AsyncTask;
-import android.util.Log;
-
-class ShareLinkTask extends AsyncTask<Void, Void, Object>
-{
- private final static String TAG = "SharedLinkTask";
-
- private String _url;
- private String _description;
- private String _keywords;
- private DefaultHttpClient mClient = createGzipHttpClient();
-
- String _mUserError = "Error creating submission. Please try again.";
-
- ShareLinkTask(String url, String description, String keywords)
- {
- _url = url;
- _description = description;
- _keywords = keywords;
- }
-
- @Override
- public Void doInBackground(Void... unused_params)
- {
- HttpEntity entity = null;
-
- try
- {
- // Construct data
- JSONObject post_params = new JSONObject();
- post_params.put("auth_code", "abc123");
-
- JSONObject sub = new JSONObject();
- sub.put("url", _url);
- sub.put("description", _description);
- sub.put("keywords", _keywords);
-
- post_params.put("links", sub);
-
- HttpPost httppost = new HttpPost("http://192.168.230.178:3000/links");
-
- // The progress dialog is non-cancelable, so set a shorter timeout than system's
- HttpParams params = httppost.getParams();
- HttpConnectionParams.setConnectionTimeout(params, 30000);
- HttpConnectionParams.setSoTimeout(params, 30000);
-
- StringEntity s = new StringEntity(post_params.toString());
- s.setContentEncoding("UTF-8");
- s.setContentType("application/json");
- httppost.setEntity(s);
-
- // Perform the HTTP POST request
- HttpResponse response = mClient.execute(httppost);
- String status = response.getStatusLine().toString();
- if (!status.contains("OK"))
- throw new HttpException(status);
-
- entity = response.getEntity();
-
- BufferedReader in = new BufferedReader(new InputStreamReader(entity.getContent()));
- String line = in.readLine();
- in.close();
- if (line == null || "".equals(line)) {
- throw new HttpException("No content returned from reply POST");
- }
-
- entity.consumeContent();
- }
- catch (Exception e) {
- if (entity != null) {
- try {
- entity.consumeContent();
- }
- catch (Exception e2) {
- Log.e(TAG, "entity.consumeContent()", e2);
- }
- }
-
- Log.e(TAG, "ShareLinkTask", e);
- }
-
- return null;
- }
-
- @Override
- public void onPreExecute()
- {
- }
-
- @Override
- public void onPostExecute(Object result)
- {
- // TODO: We need to dismiss the dialog at this point...
- }
-
- private static DefaultHttpClient createGzipHttpClient() {
- BasicHttpParams params = new BasicHttpParams();
- SchemeRegistry schemeRegistry = new SchemeRegistry();
- schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
-
- DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);
-
- httpclient.addRequestInterceptor(new HttpRequestInterceptor()
- {
- public void process(final HttpRequest request,
- final HttpContext context) throws HttpException, IOException {
- if (!request.containsHeader("Accept-Encoding")) {
- request.addHeader("Accept-Encoding", "gzip");
- }
- }
- });
-
- httpclient.addResponseInterceptor(new HttpResponseInterceptor()
- {
- public void process(final HttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- HttpEntity entity = response.getEntity();
- Header ceheader = entity.getContentEncoding();
- if (ceheader != null) {
- HeaderElement[] codecs = ceheader.getElements();
- for (int i = 0; i < codecs.length; i++) {
- if (codecs[i].getName().equalsIgnoreCase("gzip")) {
- response.setEntity(
- new GzipDecompressingEntity(response.getEntity()));
- return;
- }
- }
- }
- }
- });
-
- return httpclient;
- }
-
- static class GzipDecompressingEntity extends HttpEntityWrapper {
- public GzipDecompressingEntity(final HttpEntity entity) {
- super(entity);
- }
-
- @Override
- public InputStream getContent() throws IOException, IllegalStateException {
- // the wrapped entity's getContent() decides about repeatability
- InputStream wrappedin = wrappedEntity.getContent();
- return new GZIPInputStream(wrappedin);
- }
-
- @Override
- public long getContentLength() {
- // length of ungzipped content is not known
- return -1;
- }
- }
-}
View
30 src/uk/co/purplemonkeys/spengler/SpengApp.java
@@ -0,0 +1,30 @@
+package uk.co.purplemonkeys.spengler;
+
+import org.acra.ACRA;
+import org.acra.ReportingInteractionMode;
+import org.acra.annotation.ReportsCrashes;
+
+import android.app.Application;
+
+@ReportsCrashes(formKey = "dEZjRVlHWUJBQ2tKYXoxZTVTQXRfZUE6MQ",
+ mode = ReportingInteractionMode.NOTIFICATION,
+ resNotifTickerText = R.string.crash_notif_ticker_text,
+ resNotifTitle = R.string.crash_notif_title,
+ resNotifText = R.string.crash_notif_text,
+ resNotifIcon = android.R.drawable.stat_notify_error, // optional. default is a warning sign
+ resDialogText = R.string.crash_dialog_text,
+ resDialogIcon = android.R.drawable.ic_dialog_info, //optional. default is a warning sign
+ resDialogTitle = R.string.crash_dialog_title, // optional. default is your application name
+ resDialogCommentPrompt = R.string.crash_dialog_comment_prompt, // optional. when defined, adds a user text field input with this text resource as a label
+ resDialogOkToast = R.string.crash_dialog_ok_toast // optional. displays a Toast message when the user accepts to send a report.
+ )
+
+public class SpengApp extends Application
+{
+ @Override
+ public void onCreate() {
+ // The following line triggers the initialization of ACRA
+ ACRA.init(this);
+ super.onCreate();
+ }
+}
View
145 src/uk/co/purplemonkeys/spengler/SpengDroid.java
@@ -1,13 +1,156 @@
package uk.co.purplemonkeys.spengler;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+import uk.co.purplemonkeys.common.Common;
import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.FeedException;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.XmlReader;
-public class SpengDroid extends Activity {
+public class SpengDroid extends Activity
+{
+ private final static String TAG = "SpengDroid";
+ private SharedPreferences preferences;
+ private String version_info;
+ private ArrayAdapter<String> adapter = null;
+ private ListView listView;
+ private Button goButton;
+
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
+
+ // Initialise preferences
+ preferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+ try
+ {
+ PackageManager pm = getPackageManager();
+ PackageInfo pi = pm.getPackageInfo("uk.co.purplemonkeys.spengler", 0);
+ version_info = "SpengDroid " + pi.versionName;
+ }
+ catch (NameNotFoundException e)
+ {
+ version_info = "Couldn't determine version info.";
+ }
+
+ goButton = (Button) this.findViewById(R.id.goButton);
+ goButton.setOnClickListener(new OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ getRSS();
+ }
+ });
+
+ listView = (ListView) this.findViewById(R.id.ListView);
+ adapter = new ArrayAdapter<String>(this, R.layout.main, R.id.ListView);
+ listView.setAdapter(adapter);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.spengdroid, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch (item.getItemId())
+ {
+ case R.id.preferences_menu_id:
+ startActivity(new Intent(this, Preferences.class));
+ return true;
+ case R.id.about_menu_id:
+ Common.ShowAlertMessage(this, version_info);
+ return true;
+ case R.id.refresh_feed_menu_id:
+ getRSS();
+ return true;
+ default:
+ break;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void getRSS()
+ {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+ String url = prefs.getString("pref_url", "http://localhost:3000");
+ String auth_code = prefs.getString("pref_auth_code", "abc123");
+
+ String rss = url + "/user/feed/" + auth_code;
+
+ Common.ShowErrorToast(getApplicationContext(), "Retrieving user feed", Toast.LENGTH_SHORT);
+ URL feedUrl;
+
+ try
+ {
+ Log.d("DEBUG", "Entered:" + rss);
+ feedUrl = new URL(rss);
+ SyndFeedInput input = new SyndFeedInput();
+ SyndFeed feed = input.build(new XmlReader(feedUrl));
+ List entries = feed.getEntries();
+ Toast.makeText(this, "#Feeds retrieved: " + entries.size(), Toast.LENGTH_SHORT);
+ Iterator iterator = entries.listIterator();
+ while (iterator.hasNext())
+ {
+ SyndEntry ent = (SyndEntry) iterator.next();
+ String title = ent.getTitle();
+ adapter.add(title);
+ }
+ adapter.notifyDataSetChanged();
+ }
+ catch (MalformedURLException e)
+ {
+ Toast.makeText(this, "MalformedURLException", Toast.LENGTH_SHORT);
+ Log.e(TAG, e.toString());
+ }
+ catch (IllegalArgumentException e)
+ {
+ Toast.makeText(this, "IllegalArgumentException", Toast.LENGTH_SHORT);
+ Log.e(TAG, e.toString());
+ }
+ catch (FeedException e)
+ {
+ Toast.makeText(this, "FeedException", Toast.LENGTH_SHORT);
+ Log.e(TAG, e.toString());
+ }
+ catch (IOException e)
+ {
+ Toast.makeText(this, "IOException", Toast.LENGTH_SHORT);
+ Log.e(TAG, e.toString());
+ }
}
}

No commit comments for this range

Something went wrong with that request. Please try again.