Skip to content
Browse files

initial checkin to github

  • Loading branch information...
0 parents commit bfa4b0fbbd6601dc2d7f8595e3fe6004f3a1bd46 @mschoch committed Aug 18, 2011
Showing with 1,008 additions and 0 deletions.
  1. +16 −0 .classpath
  2. +17 −0 .gitignore
  3. +40 −0 .project
  4. +23 −0 AndroidManifest.xml
  5. BIN assets/commons-io-2.0.1.jar
  6. BIN assets/couchbase-1.0-dp-f08f54c.tgz.jpg
  7. BIN assets/httpclient-4.1.2.jar
  8. BIN assets/jackson-core-asl-1.7.9.jar
  9. BIN assets/jackson-mapper-asl-1.7.9.jar
  10. BIN assets/org.ektorp-1.1.1.jar
  11. BIN assets/slf4j-api-1.6.1.jar
  12. BIN assets/slf4j-jdk14-1.6.1.jar
  13. +79 −0 build.xml
  14. +147 −0 couchbase-build.xml
  15. +12 −0 default.properties
  16. +40 −0 proguard.cfg
  17. BIN res/drawable-hdpi/icon.png
  18. BIN res/drawable-ldpi/icon.png
  19. BIN res/drawable-mdpi/icon.png
  20. BIN res/drawable-mdpi/splash.png
  21. BIN res/drawable/.DS_Store
  22. +11 −0 res/drawable/add_item_edittext_rounded_corners.xml
  23. +47 −0 res/drawable/couchbase_progress.xml
  24. +8 −0 res/drawable/couchbase_red_gradient.xml
  25. BIN res/drawable/item_background.png
  26. BIN res/drawable/item_left_background.png
  27. BIN res/drawable/item_right_background.png
  28. BIN res/drawable/list_area___checkbox___checked.png
  29. BIN res/drawable/list_area___checkbox___unchecked.png
  30. +11 −0 res/drawable/rounded_corners.xml
  31. +18 −0 res/layout/grocery_list_item.xml
  32. +12 −0 res/layout/main.xml
  33. +11 −0 res/layout/splashscreen.xml
  34. +7 −0 res/values/strings.xml
  35. +13 −0 res/values/styles.xml
  36. +6 −0 res/xml/preferences.xml
  37. +302 −0 src/com/couchbase/grocerysync/AndroidGrocerySyncActivity.java
  38. +79 −0 src/com/couchbase/grocerysync/CouchChangesAsyncTask.java
  39. +95 −0 src/com/couchbase/grocerysync/CouchListAdapter.java
  40. +14 −0 src/com/couchbase/grocerysync/GrocerySyncPreferencesActivity.java
16 .classpath
@@ -0,0 +1,16 @@
+<?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 exported="true" kind="lib" path="assets/org.ektorp-1.1.1.jar"/>
+ <classpathentry exported="true" kind="lib" path="assets/jackson-core-asl-1.7.9.jar"/>
+ <classpathentry exported="true" kind="lib" path="assets/jackson-mapper-asl-1.7.9.jar"/>
+ <classpathentry exported="true" kind="lib" path="assets/httpclient-4.1.2.jar"/>
+ <classpathentry exported="true" kind="lib" path="assets/slf4j-api-1.6.1.jar"/>
+ <classpathentry exported="true" kind="lib" path="assets/slf4j-jdk14-1.6.1.jar"/>
+ <classpathentry kind="lib" path="/Android-Couchbase/lib/commons-compress-1.0.jar"/>
+ <classpathentry kind="src" path="Android-Couchbase_src"/>
+ <classpathentry exported="true" kind="lib" path="assets/commons-io-2.0.1.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
17 .gitignore
@@ -0,0 +1,17 @@
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+local.properties
+build.properties
40 .project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>AndroidGrocerySync</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>
+ <linkedResources>
+ <link>
+ <name>Android-Couchbase_src</name>
+ <type>2</type>
+ <locationURI>_android_Android_Couchbase_77cf4961/src</locationURI>
+ </link>
+ </linkedResources>
+</projectDescription>
23 AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.couchbase.grocerysync"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="7" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
+ <uses-permission android:name="android.permission.INTERNET"></uses-permission>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
+
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+ <activity android:name=".AndroidGrocerySyncActivity"
+ android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar" android:configChanges="keyboardHidden|orientation">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <service android:name="com.couchbase.libcouch.CouchService" android:enabled="true" android:exported="false"></service>
+ <activity android:name="GrocerySyncPreferencesActivity" android:configChanges="keyboardHidden|orientation"></activity>
+
+ </application>
+</manifest>
BIN assets/commons-io-2.0.1.jar
Binary file not shown.
BIN assets/couchbase-1.0-dp-f08f54c.tgz.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN assets/httpclient-4.1.2.jar
Binary file not shown.
BIN assets/jackson-core-asl-1.7.9.jar
Binary file not shown.
BIN assets/jackson-mapper-asl-1.7.9.jar
Binary file not shown.
BIN assets/org.ektorp-1.1.1.jar
Binary file not shown.
BIN assets/slf4j-api-1.6.1.jar
Binary file not shown.
BIN assets/slf4j-jdk14-1.6.1.jar
Binary file not shown.
79 build.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="AndroidGrocerySyncActivity" default="help">
+
+<!-- The local.properties file is created and updated by the 'android'
+ tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The build.properties file can be created by you and is never touched
+ by the 'android' tool. This is the place to change some of the
+ default property values used by the Ant rules.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="build.properties" />
+
+ <!-- The default.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <property file="default.properties" />
+
+
+ <!-- Required pre-setup import -->
+ <import file="${sdk.dir}/tools/ant/pre_setup.xml" />
+
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+ in between standard targets -->
+<!--
+ <target name="-pre-build">
+ </target>
+ <target name="-pre-compile">
+ </target>
+
+ [This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir}]
+ <target name="-post-compile">
+ </target>
+-->
+
+ <!-- Execute the Android Setup task that will setup some properties
+ specific to the target, and import the build rules files.
+
+ The rules file is imported from
+ <SDK>/tools/ant/
+ Depending on the project type it can be either:
+ - main_rules.xml
+ - lib_rules.xml
+ - test_rules.xml
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <setup> task.
+ - customize it to your needs.
+ - Customize the whole script.
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, *after* the <setup> task
+ - disable the import of the rules by changing the setup task
+ below to <setup import="false" />.
+ - customize to your needs.
+ -->
+ <setup />
+
+</project>
147 couchbase-build.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="couchbase-build" default="all">
+
+ <property file="build.properties" />
+
+ <target name="help">
+ <echo>
+To use this script, please set the property android.couchbase.dir in your build.properties file to
+point to the location you installed Android-Couchbase.
+
+The following targets are available:
+
+add-couchbase-android-library-reference - Check/Add requried Android-Couchbase library reference
+update-couchbase-android-assets - Check/Update required Android-Couchbase assets
+check-manifest-permissions - Check/Suggest required permissions in AndroidManifest.xml
+suggest-manifest-service - Check/Suggest required service definition in AndroidManifest.xml
+
+all - Run all checks
+ </echo>
+
+ </target>
+
+ <target name="all" depends="add-couchbase-android-library-reference,update-classpath,update-couchbase-android-assets,check-manifest-permissions,suggest-manifest-service">
+ </target>
+
+ <!-- Library Reference -->
+
+ <target name="check-couchbase-android-library-reference" depends="_init">
+ <condition property="contains.android.library.reference">
+ <resourcecontains resource="${basedir}/default.properties" substring="Android-Couchbase"/>
+ </condition>
+ </target>
+
+ <target name="add-couchbase-android-library-reference" depends="check-couchbase-android-library-reference" unless="contains.android.library.reference">
+ <!-- Convert the path to a relative path -->
+ <property name="rel.android.couchbase.dir" location="${android.couchbase.dir}" relative="true"/>
+ <exec executable="${sdk.dir}/tools/android">
+ <arg value="update"/>
+ <arg value="project"/>
+ <arg value="--path"/>
+ <arg value="${basedir}"/>
+ <arg value="--library"/>
+ <arg value="${rel.android.couchbase.dir}"/>
+ </exec>
+ </target>
+
+ <!-- Assets -->
+
+ <target name="check-couchbase-android-assets" depends="_init">
+ <uptodate property="android.couchbase.assets.uptodate">
+ <srcfiles dir= "${android.couchbase.dir}/assets" includes="**/*"/>
+ <mapper type="glob" from="couchbase-*.tgz.jpg"
+ to="${basedir}/assets/couchbase-*.tgz.jpg"/>
+ </uptodate>
+ </target>
+
+ <target name="update-couchbase-android-assets" depends="check-couchbase-android-assets" unless="android.couchbase.assets.uptodate">
+ <copy todir="${basedir}/assets/">
+ <fileset dir="${android.couchbase.dir}/assets" includes="**/*.tgz.jpg"/>
+ <globmapper from="*" to="*"/>
+ </copy>
+ <echo>Your Android-Couchbase assets have been updated, you may remove the old assets.</echo>
+ </target>
+
+ <!-- Permissions -->
+
+ <target name="check-manifest-permissions" depends="suggest-manifest-permission.ACCESS_NETWORK_STATE,suggest-manifest-permission.INTERNET,suggest-manifest-permission.WRITE_EXTERNAL_STORAGE">
+
+ </target>
+
+ <target name="suggest-manifest-permission.ACCESS_NETWORK_STATE"
+ depends="check-manifest-permission.ACCESS_NETWORK_STATE"
+ unless="permission.ACCESS_NETWORK_STATE">
+ <!-- backup existing AndroidManifest.xml -->
+ <copy file="AndroidManifest.xml" tofile="AndroidManifest.xml.orig.p1"/>
+ <xslt style="${android.couchbase.dir}/script/permission-ACCESS_NETWORK_STATE.xsl" in="AndroidManifest.xml.orig.p1" out="AndroidManifest.xml" force="true"></xslt>
+ </target>
+
+ <target name="check-manifest-permission.ACCESS_NETWORK_STATE" depends="_init">
+ <condition property="permission.ACCESS_NETWORK_STATE">
+ <resourcecontains resource="${basedir}/AndroidManifest.xml" substring="android.permission.ACCESS_NETWORK_STATE"/>
+ </condition>
+ </target>
+
+ <target name="suggest-manifest-permission.INTERNET"
+ depends="check-manifest-permission.INTERNET"
+ unless="permission.INTERNET">
+ <!-- backup existing AndroidManifest.xml -->
+ <copy file="AndroidManifest.xml" tofile="AndroidManifest.xml.orig.p2"/>
+ <xslt style="${android.couchbase.dir}/script/permission-INTERNET.xsl" in="AndroidManifest.xml.orig.p2" out="AndroidManifest.xml" force="true"></xslt>
+ </target>
+
+ <target name="check-manifest-permission.INTERNET" depends="_init">
+ <condition property="permission.INTERNET">
+ <resourcecontains resource="${basedir}/AndroidManifest.xml" substring="android.permission.INTERNET"/>
+ </condition>
+ </target>
+
+ <target name="suggest-manifest-permission.WRITE_EXTERNAL_STORAGE"
+ depends="check-manifest-permission.WRITE_EXTERNAL_STORAGE"
+ unless="permission.WRITE_EXTERNAL_STORAGE">
+ <!-- backup existing AndroidManifest.xml -->
+ <copy file="AndroidManifest.xml" tofile="AndroidManifest.xml.orig.p3"/>
+ <xslt style="${android.couchbase.dir}/script/permission-WRITE_EXTERNAL_STORAGE.xsl" in="AndroidManifest.xml.orig.p3" out="AndroidManifest.xml" force="true"></xslt>
+ </target>
+
+ <target name="check-manifest-permission.WRITE_EXTERNAL_STORAGE">
+ <condition property="permission.WRITE_EXTERNAL_STORAGE">
+ <resourcecontains resource="${basedir}/AndroidManifest.xml" substring="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ </condition>
+ </target>
+
+ <!-- Service -->
+ <target name="suggest-manifest-service"
+ depends="check-manifest-service"
+ unless="service.couch.exists">
+ <!-- backup existing AndroidManifest.xml -->
+ <copy file="AndroidManifest.xml" tofile="AndroidManifest.xml.orig.cs"/>
+ <xslt style="${android.couchbase.dir}/script/couchbase-service.xsl" in="AndroidManifest.xml.orig.cs" out="AndroidManifest.xml" force="true"></xslt>
+ </target>
+
+ <target name="check-manifest-service">
+ <condition property="service.couch.exists">
+ <resourcecontains resource="${basedir}/AndroidManifest.xml" substring="com.couchbase.libcouch.CouchService"/>
+ </condition>
+ </target>
+
+ <target name="check-classpath">
+ <condition property="commons.compress.exists">
+ <resourcecontains resource="${basedir}/.classpath" substring="/Android-Couchbase/lib/commons-compress-1.0.jar"/>
+ </condition>
+ </target>
+
+ <target name="update-classpath" depends="check-classpath" unless="commons.compress.exists">
+ <!-- backup existing .classpath -->
+ <copy file=".classpath" tofile=".classpath.orig"/>
+ <xslt style="${android.couchbase.dir}/script/classpath.xsl" in=".classpath.orig" out=".classpath"></xslt>
+ </target>
+
+ <target name="_init">
+ <!-- don't continue if it appears android.couchbase.dir is set incorrectly -->
+ <available file="${android.couchbase.dir}/src/com/couchbase/libcouch/CouchbaseEmbeddedServer.java"
+ property="android.couchbase.dir.valid"/>
+ <fail message="Property android.couchbase.dir does not appear to be set correctly." unless="android.couchbase.dir.valid"/>
+ </target>
+
+</project>
12 default.properties
@@ -0,0 +1,12 @@
+# 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.
+
+# Project target.
+target=android-7
+android.library.reference.1=../../research/clean/Android-Couchbase
40 proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
BIN res/drawable-hdpi/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable-ldpi/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable-mdpi/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable-mdpi/splash.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable/.DS_Store
Binary file not shown.
11 res/drawable/add_item_edittext_rounded_corners.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+
+ <solid android:color="#efefeb"/>
+ <stroke android:width="1dp" android:color="#b4b4b3"/>
+ <padding android:left="5dp" android:top="5dp"
+ android:right="5dp" android:bottom="5dp" />
+ <corners android:radius="7dp" />
+
+</shape>
47 res/drawable/couchbase_progress.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+<item android:id="@android:id/background">
+ <shape>
+ <corners android:radius="5dip" />
+ <gradient
+ android:startColor="#ff9d9e9d"
+ android:centerColor="#ff5a5d5a"
+ android:centerY="0.75"
+ android:endColor="#ff747674"
+ android:angle="270"
+ />
+ </shape>
+</item>
+
+<item android:id="@android:id/secondaryProgress">
+ <clip>
+ <shape>
+ <corners android:radius="5dip" />
+ <gradient
+ android:startColor="#80ffd300"
+ android:centerColor="#80ffb600"
+ android:centerY="0.75"
+ android:endColor="#a0ffcb00"
+ android:angle="270"
+ />
+ </shape>
+ </clip>
+</item>
+<item
+ android:id="@android:id/progress">
+ <clip>
+ <shape>
+ <corners
+ android:radius="5dip" />
+ <gradient
+ android:startColor="@color/CouchbaseRedGradientStart"
+ android:centerY="0.75"
+ android:endColor="@color/CouchbaseRedGradientEnd"
+ android:angle="270"
+ />
+ </shape>
+ </clip>
+</item>
+
+</layer-list>
8 res/drawable/couchbase_red_gradient.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+ <gradient
+ android:startColor="@color/CouchbaseRedGradientStart"
+ android:endColor="@color/CouchbaseRedGradientEnd"
+ android:angle="90" />
+</shape>
BIN res/drawable/item_background.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable/item_left_background.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable/item_right_background.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable/list_area___checkbox___checked.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN res/drawable/list_area___checkbox___unchecked.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 res/drawable/rounded_corners.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+
+ <solid android:color="#efefeb"/>
+ <stroke android:width="1dp" android:color="#b4b4b3"/>
+ <padding android:left="5dp" android:top="2dp"
+ android:right="5dp" android:bottom="2dp" />
+ <corners android:radius="7dp" />
+
+</shape>
18 res/layout/grocery_list_item.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content" android:layout_height="wrap_content">
+ <ImageView android:id="@+id/icon" android:layout_height="fill_parent"
+ android:src="@drawable/list_area___checkbox___unchecked" android:layout_width="52px"
+ android:layout_marginLeft="15px"
+ android:background="#efefeb">
+ </ImageView>
+ <LinearLayout android:layout_height="fill_parent" android:id="@+id/linearLayout1" android:layout_width="wrap_content"
+ android:background="@drawable/item_right_background" android:layout_marginRight="0px">
+ <TextView android:text="@+id/TextView01" android:layout_width="fill_parent"
+ android:layout_height="fill_parent" android:id="@+id/label"
+ android:layout_marginLeft="10px"
+ android:textSize="20px" android:gravity="center_vertical" android:textColor="#808080"
+ ></TextView>
+ </LinearLayout>
+
+</LinearLayout>
12 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"
+ android:background="@android:color/white">
+ <TextView android:textAppearance="?android:attr/textAppearanceLarge" android:layout_height="wrap_content" android:id="@+id/textView1" android:text="@string/app_name" android:layout_width="fill_parent" android:gravity="center_horizontal" android:textStyle="bold" android:background="@drawable/couchbase_red_gradient"></TextView>
+ <EditText android:id="@+id/addItemEditText" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_margin="10px" android:maxLines="1" android:hint="@string/add_item_hint" android:background="@drawable/add_item_edittext_rounded_corners" android:textSize="20px">
+ <requestFocus></requestFocus>
+ </EditText>
+ <ListView android:id="@+id/itemListView" android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/rounded_corners" android:layout_margin="10px"></ListView>
+</LinearLayout>
11 res/layout/splashscreen.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" android:gravity="center_horizontal">
+ <ImageView android:layout_width="wrap_content" android:src="@drawable/splash" android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentLeft="true"></ImageView>
+ <ProgressBar android:id="@+id/splashProgressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_height="wrap_content" android:layout_below="@+id/imageView1" android:layout_centerHorizontal="true" android:layout_width="fill_parent" android:layout_margin="10px" android:progressDrawable="@drawable/couchbase_progress"></ProgressBar>
+ <TextView android:id="@+id/splashProgressMessage" android:layout_height="wrap_content" android:text="TextView" android:layout_below="@+id/imageView1" android:layout_width="fill_parent" android:gravity="center_vertical|center_horizontal" android:textColor="@android:color/white" android:layout_margin="10px"></TextView>
+
+</RelativeLayout>
7 res/values/strings.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">Grocery Sync</string>
+ <string name="startup_message">Starting Couchbase Mobile</string>
+ <string name="installing_message">Installing Couchbase Mobile</string>
+ <string name="add_item_hint">Add Item</string>
+</resources>
13 res/values/styles.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="SplashScreenBackgroundColor">#efeee9</color>
+ <color name="CouchbaseRed">#efeee9</color>
+ <color name="CouchbaseRedGradientStart">#9e0c0c</color>
+ <color name="CouchbaseRedGradientEnd">#c96565</color>
+ <style name="SplashScreenStyle">
+ <item name="android:padding">0dp</item>
+ <item name="android:windowBackground">@color/SplashScreenBackgroundColor</item>
+ <item name="android:windowFrame">@null</item>
+ </style>
+
+</resources>
6 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">
+ <EditTextPreference android:defaultValue="http://couchbase.iriscouch.com/grocery-sync" android:dialogTitle="Sync URL" android:key="sync_url" android:title="Sync URL" android:summary="CouchDB database to sync grocery list" android:dialogMessage="CouchDB database to sync grocery list"></EditTextPreference>
+
+</PreferenceScreen>
302 src/com/couchbase/grocerysync/AndroidGrocerySyncActivity.java
@@ -0,0 +1,302 @@
+package com.couchbase.grocerysync;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.node.ObjectNode;
+import org.ektorp.CouchDbConnector;
+import org.ektorp.CouchDbInstance;
+import org.ektorp.ReplicationCommand;
+import org.ektorp.http.HttpClient;
+import org.ektorp.http.StdHttpClient;
+import org.ektorp.impl.StdCouchDbInstance;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.preference.PreferenceManager;
+import android.text.format.DateFormat;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnKeyListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.couchbase.libcouch.CouchbaseEmbeddedServer;
+import com.couchbase.libcouch.ICouchClient;
+
+public class AndroidGrocerySyncActivity extends Activity {
+
+ //constants
+ public static final String DATABASE_NAME = "grocery-sync";
+
+ //splash screen
+ protected Dialog splashDialog;
+ protected ProgressBar splashProgressBar;
+ protected TextView splashProgressMessage;
+
+ //main screen
+ protected EditText addItemEditText;
+ protected ListView itemListView;
+
+ //couch internals
+ protected ServiceConnection couchServiceConnection;
+
+ //ektorp impl
+ protected CouchDbConnector couchDbConnector;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ showSplashScreen();
+ startCouch();
+
+ setContentView(R.layout.main);
+
+
+ //connect items from layout
+ addItemEditText = (EditText)findViewById(R.id.addItemEditText);
+ itemListView = (ListView)findViewById(R.id.itemListView);
+
+ //connect listeners
+ addItemEditText.setOnKeyListener(new OnKeyListener() {
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if ((event.getAction() == KeyEvent.ACTION_DOWN)
+ && (keyCode == KeyEvent.KEYCODE_ENTER)) {
+
+ String inputText = addItemEditText.getText().toString();
+ if(!inputText.equals("")) {
+
+ createGroceryItem(inputText);
+
+ Toast.makeText(AndroidGrocerySyncActivity.this,
+ inputText, Toast.LENGTH_SHORT)
+ .show();
+
+ }
+ addItemEditText.setText("");
+ return true;
+ }
+ return false;
+ }
+ });
+
+ }
+
+
+
+ protected void onDestroy() {
+ super.onDestroy();
+ try {
+ unbindService(couchServiceConnection);
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ protected ICouchClient couchCallbackHandler = new ICouchClient.Stub() {
+
+ public void installing(int completed, int total) throws RemoteException {
+ if(completed < (total - 1)) {
+ AndroidGrocerySyncActivity.this.updateSplashScreenProgressBar(completed, total);
+ AndroidGrocerySyncActivity.this.updateSplashScreenProgressMessage(getString(R.string.installing_message));
+ }
+ else {
+ AndroidGrocerySyncActivity.this.updateSplashScreenProgressBar(completed, total);
+ AndroidGrocerySyncActivity.this.updateSplashScreenProgressMessage(getString(R.string.startup_message));
+ }
+ }
+
+ public void exit(String error) throws RemoteException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void couchStarted(String host, int port) throws RemoteException {
+ AndroidGrocerySyncActivity.this.removeSplashScreen();
+
+ HttpClient httpClient = new StdHttpClient.Builder().host(host).port(port).build();
+ CouchDbInstance dbInstance = new StdCouchDbInstance(httpClient);
+ couchDbConnector = dbInstance.createConnector(DATABASE_NAME, true);
+ itemListView.setAdapter(new CouchListAdapter(AndroidGrocerySyncActivity.this, couchDbConnector));
+ itemListView.setOnItemClickListener(new OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ JsonNode document = (JsonNode)parent.getItemAtPosition(position);
+ toggleItemChecked(document);
+ }
+
+ });
+
+ itemListView.setOnItemLongClickListener(new OnItemLongClickListener() {
+
+ @Override
+ public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+
+ final JsonNode document = (JsonNode)parent.getItemAtPosition(position);
+ JsonNode textNode = document.get("text");
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(AndroidGrocerySyncActivity.this);
+ AlertDialog alert = builder.setTitle("Delete Item?")
+ .setMessage("Are you sure you want to delete " + textNode.getValueAsText() + "?")
+ .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ deleteGroceryItem(document);
+ }
+ })
+ .setNegativeButton("No", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // Handle Cancel
+ }
+ })
+ .create();
+
+ alert.show();
+
+ return true;
+ }
+
+ });
+
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+
+ ReplicationCommand pushReplication = new ReplicationCommand.Builder()
+ .source(DATABASE_NAME)
+ .target(prefs.getString("sync_url", "http://mschoch.iriscouch.com/grocery-sync"))
+ .continuous(true)
+ .build();
+
+ dbInstance.replicate(pushReplication);
+
+ ReplicationCommand pullReplication = new ReplicationCommand.Builder()
+ .source(prefs.getString("sync_url", "http://mschoch.iriscouch.com/grocery-sync"))
+ .target(DATABASE_NAME)
+ .continuous(true)
+ .build();
+
+ dbInstance.replicate(pullReplication);
+ }
+ };
+
+ protected void startCouch() {
+ CouchbaseEmbeddedServer couch = new CouchbaseEmbeddedServer(getBaseContext(), couchCallbackHandler);
+ couchServiceConnection = couch.startCouchbase();
+ }
+
+ /**
+ * Removes the Dialog that displays the splash screen
+ */
+ protected void removeSplashScreen() {
+ if (splashDialog != null) {
+ splashDialog.dismiss();
+ splashDialog = null;
+ splashProgressBar = null;
+ splashProgressMessage = null;
+ }
+ }
+
+ /**
+ * Update the Splash Screen Progress Bar
+ */
+ protected void updateSplashScreenProgressBar(int progress, int max) {
+ if(splashProgressBar != null) {
+ splashProgressBar.setProgress(progress);
+ splashProgressBar.setMax(max);
+ }
+ }
+
+ /**
+ * Update the Splash Screen Progress Message
+ */
+ protected void updateSplashScreenProgressMessage(String message) {
+ if(splashProgressMessage != null) {
+ splashProgressMessage.setText(message);
+ }
+ }
+
+ /**
+ * Shows the splash screen over the full Activity
+ */
+ protected void showSplashScreen() {
+ splashDialog = new Dialog(this, R.style.SplashScreenStyle);
+ splashDialog.setContentView(R.layout.splashscreen);
+ splashDialog.setCancelable(false);
+ splashDialog.show();
+
+ splashProgressBar = (ProgressBar)splashDialog.findViewById(R.id.splashProgressBar);
+ splashProgressBar.setProgress(0);
+ splashProgressBar.setMax(100);
+
+ splashProgressMessage = (TextView)splashDialog.findViewById(R.id.splashProgressMessage);
+ splashProgressMessage.setText(getString(R.string.startup_message));
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu) {
+ menu.add(Menu.NONE, 0, 0, "Settings");
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case 0:
+ startActivity(new Intent(this, GrocerySyncPreferencesActivity.class));
+ return true;
+ }
+ return false;
+ }
+
+ public void createGroceryItem(String name) {
+ UUID uuid = UUID.randomUUID();
+ Calendar calendar = GregorianCalendar.getInstance();
+ long currentTime = calendar.getTimeInMillis();
+ String currentTimeString = DateFormat.format("EEEE-MM-dd'T'HH:mm:ss.SSS'Z'", calendar).toString();
+
+ String id = currentTime + "-" + uuid.toString();
+
+ Map<String, String> newItem = new HashMap<String, String>();
+ newItem.put("_id", id);
+ newItem.put("text", name);
+ newItem.put("check", Boolean.FALSE.toString());
+ newItem.put("created_at", currentTimeString);
+
+ couchDbConnector.create(newItem);
+ }
+
+ public void toggleItemChecked(JsonNode document) {
+ JsonNode check = document.get("check");
+ if(check.getBooleanValue()) {
+ ObjectNode documentObject = (ObjectNode)document;
+ documentObject.put("check", false);
+ }
+ else {
+ ObjectNode documentObject = (ObjectNode)document;
+ documentObject.put("check", true);
+ }
+
+ couchDbConnector.update(document);
+ }
+
+ public void deleteGroceryItem(JsonNode document) {
+ couchDbConnector.delete(document);
+ }
+
+}
79 src/com/couchbase/grocerysync/CouchChangesAsyncTask.java
@@ -0,0 +1,79 @@
+package com.couchbase.grocerysync;
+
+import org.codehaus.jackson.JsonNode;
+import org.ektorp.CouchDbConnector;
+import org.ektorp.changes.ChangesCommand;
+import org.ektorp.changes.ChangesFeed;
+import org.ektorp.changes.DocumentChange;
+
+import android.os.AsyncTask;
+
+public class CouchChangesAsyncTask extends AsyncTask<Integer, DocumentChange, Void> {
+
+ private CouchListAdapter parent;
+ private CouchDbConnector couchDbConnector;
+ private Integer since;
+ private ChangesFeed feed;
+
+ public CouchChangesAsyncTask(CouchListAdapter parent, CouchDbConnector couchDbConnector, Integer since) {
+ this.parent = parent;
+ this.couchDbConnector = couchDbConnector;
+ this.since = since;
+ }
+
+ protected Void doInBackground(Integer... unused) {
+
+ ChangesCommand cmd = new ChangesCommand.Builder().since(since)
+ .includeDocs(true)
+ .continuous(true)
+ .heartbeat(5000)
+ .build();
+
+ feed = couchDbConnector.changesFeed(cmd);
+
+ while (feed.isAlive()) {
+ try {
+ DocumentChange change = feed.next();
+ publishProgress(change);
+ } catch (InterruptedException e) {
+ cancel(true);
+ }
+
+ }
+
+
+ return null;
+ };
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ protected void onProgressUpdate(DocumentChange... values) {
+ for (DocumentChange documentChange : values) {
+ String id = documentChange.getId();
+ if(documentChange.isDeleted()) {
+ parent.rowMap.remove(id);
+ }
+ else {
+ parent.rowMap.put(id, documentChange.getDocAsNode());
+ }
+ }
+ parent.notifyDataSetChanged();
+ };
+
+ protected void onPostExecute(Void result) {
+ super.onPostExecute(result);
+ };
+
+ @Override
+ protected void onCancelled() {
+ super.onCancelled();
+
+ if(feed != null) {
+ feed.cancel();
+ }
+ }
+
+}
95 src/com/couchbase/grocerysync/CouchListAdapter.java
@@ -0,0 +1,95 @@
+package com.couchbase.grocerysync;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.codehaus.jackson.JsonNode;
+import org.ektorp.CouchDbConnector;
+import org.ektorp.DbInfo;
+import org.ektorp.ViewQuery;
+import org.ektorp.ViewResult;
+import org.ektorp.ViewResult.Row;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class CouchListAdapter extends BaseAdapter {
+
+ protected Context context;
+ //protected List<Row> rows;
+ public HashMap<String, JsonNode> rowMap;
+
+ public CouchListAdapter(Context context, CouchDbConnector couchDbConnector) {
+ this.context = context;
+
+ rowMap = new HashMap<String, JsonNode>();
+
+ DbInfo dbInfo = couchDbConnector.getDbInfo();
+ int lastUpdateSeq = dbInfo.getUpdateSeq();
+
+ ViewResult vr = couchDbConnector.queryView(new ViewQuery().allDocs().includeDocs(true));
+// rows = vr.getRows();
+ Iterator<Row> rowIterator = vr.iterator();
+ while(rowIterator.hasNext()) {
+ Row row = rowIterator.next();
+ rowMap.put(row.getId(), row.getDocAsNode());
+ }
+
+ //create an ansyc task to get updates
+ CouchChangesAsyncTask couchChangesAsyncTask = new CouchChangesAsyncTask(this, couchDbConnector, lastUpdateSeq);
+ couchChangesAsyncTask.execute((Integer[])null);
+ }
+
+ @Override
+ public int getCount() {
+// return rows.size();
+ return rowMap.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+// return rows.get(position);
+ String key = (String)rowMap.keySet().toArray()[position];
+ return rowMap.get(key);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View itemView, ViewGroup parent) {
+ View v = itemView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.grocery_list_item, null);
+ }
+
+// Row row = (Row)rows.get(position);
+ TextView label = (TextView) v.findViewById(R.id.label);
+// JsonNode document = row.getDocAsNode();
+ JsonNode document = (JsonNode)getItem(position);
+ JsonNode textNode = document.get("text");
+ label.setText(textNode.getTextValue());
+
+ JsonNode checkNode = document.get("check");
+ ImageView icon = (ImageView) v.findViewById(R.id.icon);
+ if(checkNode.getBooleanValue()) {
+ icon.setImageResource(R.drawable.list_area___checkbox___checked);
+ }
+ else {
+ icon.setImageResource(R.drawable.list_area___checkbox___unchecked);
+ }
+
+
+ return v;
+ }
+
+}
14 src/com/couchbase/grocerysync/GrocerySyncPreferencesActivity.java
@@ -0,0 +1,14 @@
+package com.couchbase.grocerysync;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class GrocerySyncPreferencesActivity extends PreferenceActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+
+}

0 comments on commit bfa4b0f

Please sign in to comment.
Something went wrong with that request. Please try again.