imported eclipse project

master
Evan Leybourn 2010-04-21 21:07:43 +10:00
parent 97028c2950
commit fe04e4f16c
74 changed files with 3099 additions and 0 deletions

32
AndroidManifest.xml Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eleybourn.bookcatalogue"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name" android:icon="@drawable/logo_bc">
<activity android:name=".BookCatalogue"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
</activity>
<activity android:name=".BookEdit" android:label="@string/edit_title"></activity>
<activity android:name=".BookCatalogueTitle" android:label="@string/sort_title"></activity>
<activity android:name=".BookISBNSearch" android:label="@string/title_isbn_search"></activity>
<activity android:name=".Bookshelf" android:label="@string/title_manage_bs"></activity>
<activity android:name=".BookshelfEdit" android:label="@string/title_edit_bs"></activity>
</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
</manifest>

BIN
bin/BookCatalogue.apk Normal file

Binary file not shown.

BIN
bin/classes.dex Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/resources.ap_ Normal file

Binary file not shown.

13
default.properties Normal file
View File

@ -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-7

View File

@ -0,0 +1,117 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.eleybourn.bookcatalogue;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int expander_group=0x7f020000;
public static final int expander_ic_maximized=0x7f020001;
public static final int expander_ic_minimized=0x7f020002;
public static final int ic_menu_bookshelves=0x7f020003;
public static final int ic_menu_collapse=0x7f020004;
public static final int ic_menu_expand=0x7f020005;
public static final int ic_menu_insert_barcode=0x7f020006;
public static final int icon=0x7f020007;
public static final int logo_bc=0x7f020008;
}
public static final class id {
public static final int author=0x7f060001;
public static final int bookshelf=0x7f060008;
public static final int bookshelf_label=0x7f06000f;
public static final int bookshelf_name=0x7f060010;
public static final int cancel=0x7f06000d;
public static final int confirm=0x7f06000c;
public static final int date_published=0x7f060007;
public static final int isbn=0x7f060003;
public static final int pages=0x7f060009;
public static final int publisher=0x7f060006;
public static final int rating=0x7f06000b;
public static final int read=0x7f06000a;
public static final int row_author=0x7f060016;
public static final int row_bookshelf=0x7f060018;
public static final int row_family=0x7f060011;
public static final int row_given=0x7f060012;
public static final int row_img=0x7f060000;
public static final int row_publisher=0x7f060017;
public static final int row_series=0x7f060014;
public static final int row_series_num=0x7f060015;
public static final int row_title=0x7f060013;
public static final int search=0x7f06000e;
public static final int series=0x7f060004;
public static final int series_num=0x7f060005;
public static final int spinnerTarget=0x7f060019;
public static final int title=0x7f060002;
}
public static final class layout {
public static final int edit_book=0x7f030000;
public static final int edit_bookshelf=0x7f030001;
public static final int isbn_search=0x7f030002;
public static final int list_authors=0x7f030003;
public static final int list_books=0x7f030004;
public static final int list_bookshelves=0x7f030005;
public static final int main=0x7f030006;
public static final int row_authors=0x7f030007;
public static final int row_authors_books=0x7f030008;
public static final int row_books=0x7f030009;
public static final int row_bookshelf=0x7f03000a;
public static final int spinner_frontpage=0x7f03000b;
}
public static final class string {
public static final int all_books=0x7f050023;
public static final int app_name=0x7f050001;
public static final int author=0x7f050004;
public static final int book_exists=0x7f050028;
public static final int book_not_found=0x7f05002b;
public static final int bookshelf=0x7f05000a;
public static final int bookshelf_label=0x7f050022;
public static final int cancel=0x7f050019;
public static final int confirm_add=0x7f05000e;
public static final int confirm_add_bs=0x7f05001d;
public static final int confirm_save=0x7f05001a;
public static final int confirm_save_bs=0x7f05001f;
public static final int date_published=0x7f050008;
public static final int delete_1st_bs=0x7f050021;
public static final int edit_title=0x7f050015;
public static final int hello=0x7f050000;
public static final int isbn=0x7f050006;
public static final int isbn_found=0x7f050024;
public static final int menu_bookshelf=0x7f05001e;
public static final int menu_delete=0x7f050003;
public static final int menu_delete_bs=0x7f050020;
public static final int menu_insert=0x7f050002;
public static final int menu_insert_barcode=0x7f050017;
public static final int menu_insert_bs=0x7f05001c;
public static final int menu_insert_isbn=0x7f050016;
public static final int menu_sort_by_author=0x7f050010;
public static final int menu_sort_by_author_collapsed=0x7f050013;
public static final int menu_sort_by_author_expanded=0x7f050011;
public static final int menu_sort_by_title=0x7f050012;
public static final int nobooks=0x7f05000f;
public static final int nobookshelves=0x7f05001b;
public static final int pages=0x7f05000d;
public static final int publisher=0x7f050007;
public static final int rating=0x7f050009;
public static final int read=0x7f05000b;
public static final int search=0x7f050018;
public static final int search_hint=0x7f05002a;
public static final int search_label=0x7f050029;
public static final int series=0x7f05000c;
public static final int series_num=0x7f05002c;
public static final int sort_title=0x7f050014;
public static final int title=0x7f050005;
public static final int title_edit_bs=0x7f050027;
public static final int title_isbn_search=0x7f050025;
public static final int title_manage_bs=0x7f050026;
public static final int unable_to_connect=0x7f05002d;
}
public static final class xml {
public static final int searchable=0x7f040000;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
res/drawable-hdpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

BIN
res/drawable-ldpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
res/drawable-mdpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_expanded="true"
android:drawable="@drawable/expander_ic_maximized" />
<item
android:drawable="@drawable/expander_ic_minimized" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

137
res/layout/edit_book.xml Executable file
View File

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10sp">
<ImageView android:id="@+id/row_img"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<AutoCompleteTextView android:id="@+id/author"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/author"
android:inputType="textCapWords"
android:completionThreshold="2"
/>
<EditText android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/title"
android:inputType="textCapWords"
/>
<EditText android:id="@+id/isbn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/isbn"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<AutoCompleteTextView android:id="@+id/series"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:hint="@string/series"
android:inputType="textCapWords"
android:completionThreshold="2"
/>
<EditText android:id="@+id/series_num"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:hint="@string/series_num"
android:numeric="decimal"
/>
</LinearLayout>
<AutoCompleteTextView android:id="@+id/publisher"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/publisher"
android:inputType="textCapWords"
android:completionThreshold="2"
/>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/date_published"
android:textSize="16sp" />
<DatePicker android:id="@+id/date_published"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<Spinner android:id="@+id/bookshelf"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/bookshelf"
/>
<EditText android:id="@+id/pages"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/pages"
android:numeric="decimal"
/>
<CheckBox android:id="@+id/read"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/read"
/>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/rating"
android:textSize="16sp" />
<RatingBar android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:numStars="5"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<Button android:id="@+id/confirm"
android:text="@string/confirm_add"
android:width="150sp"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<Button android:id="@+id/cancel"
android:text="@string/cancel"
android:width="150sp"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
</LinearLayout>
</LinearLayout>
</ScrollView>

38
res/layout/edit_bookshelf.xml Executable file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10sp">
<EditText android:id="@+id/bookshelf"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/bookshelf"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<Button android:id="@+id/confirm"
android:text="@string/confirm_add_bs"
android:width="150sp"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<Button android:id="@+id/cancel"
android:text="@string/cancel"
android:width="150sp"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
</LinearLayout>
</LinearLayout>
</ScrollView>

27
res/layout/isbn_search.xml Executable file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText android:id="@+id/isbn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/isbn"
android:inputType="number"
android:digits="0123456789Xx"
/>
<Button android:id="@+id/search"
android:text="@string/search"
android:layout_width="fill_parent"
android:width="150sp"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,37 @@
<?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:paddingLeft="5sp"
android:background="#2d2d2d">
<TextView android:id="@+id/bookshelf_label"
android:layout_width="wrap_content"
android:layout_height="32sp"
android:text="@+string/bookshelf_label"
android:textAppearance="?android:attr/textAppearanceLarge"
android:background="#2d2d2d"
android:paddingRight="5sp"
/>
<Spinner android:id="@+id/bookshelf_name"
android:layout_width="fill_parent"
android:layout_height="32sp"
android:layout_toRightOf="@id/bookshelf_label"
android:paddingBottom="2sp"
android:background="#2d2d2d"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/bookshelf_label">
<ExpandableListView android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp" />
<TextView android:id="@+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@+string/nobooks"
android:textSize="16sp" />
</LinearLayout>
</RelativeLayout>

34
res/layout/list_books.xml Normal file
View File

@ -0,0 +1,34 @@
<?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">
<TextView android:id="@+id/bookshelf_label"
android:layout_width="wrap_content"
android:layout_height="32sp"
android:text="@+string/bookshelf_label"
android:textAppearance="?android:attr/textAppearanceLarge"
android:background="#333333"
android:paddingRight="5sp"
/>
<Spinner android:id="@+id/bookshelf_name"
android:layout_width="fill_parent"
android:layout_height="32sp"
android:background="#333333"
android:layout_toRightOf="@id/bookshelf_label"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/bookshelf_label">
<ListView android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="16sp" />
<TextView android:id="@+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@+string/nobooks"
android:textSize="16sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="16sp" />
<TextView android:id="@+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@+string/nobookshelves"
android:textSize="16sp" />
</LinearLayout>

12
res/layout/main.xml Normal file
View File

@ -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>

21
res/layout/row_authors.xml Executable file
View File

@ -0,0 +1,21 @@
<?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="?android:attr/listPreferredItemHeight"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:gravity="center_vertical"
>
<TextView android:id="@+id/row_family"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
<TextView android:id="@+id/row_given"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_toRightOf="@+id/row_family"
/>
</RelativeLayout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
<ImageView android:id="@+id/row_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<TextView android:id="@+id/row_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
/>
<TextView android:id="@+id/row_series"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
/>
<TextView android:id="@+id/row_series_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>

38
res/layout/row_books.xml Executable file
View File

@ -0,0 +1,38 @@
<?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="wrap_content"
android:padding="10dp" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView android:id="@+id/row_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
<TextView android:id="@+id/row_series"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
/>
<TextView android:id="@+id/row_series_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<TextView android:id="@+id/row_author"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
/>
<TextView android:id="@+id/row_publisher"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
/>
</LinearLayout>

13
res/layout/row_bookshelf.xml Executable file
View File

@ -0,0 +1,13 @@
<?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="wrap_content"
android:padding="10dp" >
<TextView android:id="@+id/row_bookshelf"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
</LinearLayout>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/spinnerTarget"
android:textColor="#FFFFFF"
/>

49
res/values/strings.xml Normal file
View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Book Catalogue!</string>
<string name="app_name">Book Catalogue</string>
<string name="menu_insert">Add Book</string>
<string name="menu_delete">Delete Book</string>
<string name="author">Author</string>
<string name="title">Title</string>
<string name="isbn">ISBN</string>
<string name="publisher">Publisher</string>
<string name="date_published">Date Published</string>
<string name="rating">Rating</string>
<string name="bookshelf">Bookshelf</string>
<string name="read">Have you read this book?</string>
<string name="series">Series</string>
<string name="pages">Pages</string>
<string name="confirm_add">Add Book</string>
<string name="nobooks">There are no books in this Bookshelf. Please add some using the menu at the bottom of this screen.</string>
<string name="menu_sort_by_author">Sort by Author</string>
<string name="menu_sort_by_author_expanded">Expand</string>
<string name="menu_sort_by_title">Sort By Title</string>
<string name="menu_sort_by_author_collapsed">Collapse</string>
<string name="sort_title">Book Catalogue (by Title)</string>
<string name="edit_title">Book Catalogue (Edit Book)</string>
<string name="menu_insert_isbn">Add by ISBN</string>
<string name="menu_insert_barcode">Add by Barcode</string>
<string name="search">Search</string>
<string name="cancel">Cancel</string>
<string name="confirm_save">Save Book</string>
<string name="nobookshelves">You have not created any bookshelves yet. Please add some using the menu at the bottom of this screen.</string>
<string name="menu_insert_bs">Create Bookshelf</string>
<string name="confirm_add_bs">Add Bookshelf</string>
<string name="menu_bookshelf">Bookshelves</string>
<string name="confirm_save_bs">Save Bookshelf</string>
<string name="menu_delete_bs">Delete Bookshelf</string>
<string name="delete_1st_bs">Cannot Delete the 1st Bookshelf</string>
<string name="bookshelf_label">Bookshelf: </string>
<string name="all_books">All Books</string>
<string name="isbn_found">ISBN Scanned. Searching Internet.</string>
<string name="title_isbn_search">Book Catalogue (ISBN Search)</string>
<string name="title_manage_bs">Book Catalogue (Manage Bookshelves)</string>
<string name="title_edit_bs">Book Catalogue (Edit Bookshelf)</string>
<string name="book_exists">The book you are trying to add already exists. Skipping.</string>
<string name="search_label">Search for Books</string>
<string name="search_hint">Start typing in the author or title</string>
<string name="book_not_found">The scanned book was not found. Please enter the details manually.</string>
<string name="series_num">#</string>
<string name="unable_to_connect">Unable to Connect to Google Books</string>
</resources>

4
res/xml/searchable.xml Normal file
View File

@ -0,0 +1,4 @@
<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/search_label"
android:hint="@string/search_hint" />

View File

@ -0,0 +1,526 @@
/*
* @copyright 2010 Evan Leybourn
*/
package com.eleybourn.bookcatalogue;
//import android.R;
import android.app.ExpandableListActivity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnGroupClickListener;
/*
* A book catalogue application that integrates with Google Books.
*/
public class BookCatalogue extends ExpandableListActivity {
private static final int ACTIVITY_CREATE=0;
private static final int ACTIVITY_EDIT=1;
private static final int ACTIVITY_SORT=2;
private static final int ACTIVITY_ISBN=3;
private static final int ACTIVITY_SCAN=4;
private static final int ACTIVITY_BOOKSHELF=5;
private CatalogueDBAdapter mDbHelper;
private int mGroupIdColumnIndex;
private static final int SORT_BY_AUTHOR_EXPANDED = Menu.FIRST + 1;
private static final int SORT_BY_AUTHOR_COLLAPSED = Menu.FIRST + 2;
private static final int SORT_BY_TITLE = Menu.FIRST + 3;
private static final int INSERT_ID = Menu.FIRST + 4;
private static final int INSERT_ISBN_ID = Menu.FIRST + 5;
private static final int INSERT_BARCODE_ID = Menu.FIRST + 6;
private static final int DELETE_ID = Menu.FIRST + 7;
private static final int BOOKSHELVES = Menu.FIRST + 8;
private static final int SORT_BY_AUTHOR = Menu.FIRST + 9;
public String bookshelf = "";
private ArrayAdapter<String> spinnerAdapter;
private Menu optionsMenu;
public int sort = 0;
public int numAuthors = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
setContentView(R.layout.list_authors);
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
bookshelf = getString(R.string.all_books);
bookshelf();
//fillData();
registerForContextMenu(getExpandableListView());
} catch (Exception e) {
Log.e("Book Catalogue", "Unknown Exception - BC onCreate - " + e.getMessage() );
}
}
private void bookshelf() {
// Setup the Bookshelf Spinner
Spinner mBookshelfText = (Spinner) findViewById(R.id.bookshelf_name);
spinnerAdapter = new ArrayAdapter<String>(this, R.layout.spinner_frontpage);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mBookshelfText.setAdapter(spinnerAdapter);
/* Add the default All Books bookshelf */
spinnerAdapter.add(getString(R.string.all_books));
Cursor bookshelves = mDbHelper.fetchAllBookshelves();
if (bookshelves.moveToFirst()) {
do {
spinnerAdapter.add(bookshelves.getString(1));
}
while (bookshelves.moveToNext());
}
mBookshelfText.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parentView, View view, int position, long id) {
bookshelf = spinnerAdapter.getItem(position);
fillData();
}
public void onNothingSelected(AdapterView<?> parentView) {
// Do Nothing
}
});
}
private void fillData() {
if (sort == 1) {
fillDataTitle();
} else {
fillDataAuthor();
}
}
private void fillDataAuthor() {
Intent intent = getIntent();
// base the layout and the query on the sort order
int layout = R.layout.row_authors;
int layout_child = R.layout.row_authors_books;
// Get all of the rows from the database and create the item list
Cursor BooksCursor = null;
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
BooksCursor = mDbHelper.searchAuthors(query, bookshelf);
} else {
BooksCursor = mDbHelper.fetchAllAuthors(bookshelf);
}
numAuthors = BooksCursor.getCount();
mGroupIdColumnIndex = BooksCursor.getColumnIndexOrThrow("_id");
startManagingCursor(BooksCursor);
// Create an array to specify the fields we want to display in the list
String[] from = new String[]{CatalogueDBAdapter.KEY_FAMILY_NAME, CatalogueDBAdapter.KEY_GIVEN_NAMES};
String[] exp_from = new String[]{CatalogueDBAdapter.KEY_TITLE, CatalogueDBAdapter.KEY_SERIES, CatalogueDBAdapter.KEY_SERIES_NUM};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.row_family, R.id.row_given};
int[] exp_to = new int[]{R.id.row_title, R.id.row_series, R.id.row_series_num};
ExpandableListAdapter books = new AuthorBookListAdapter(BooksCursor, this, layout, layout_child, from, to, exp_from, exp_to);
/* Handle the click event. Do not open, but goto the book edit page */
ExpandableListView expandableList = getExpandableListView();
expandableList.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
return false;
}
});
/* Hide the default expandable icon */
Drawable indicator = this.getResources().getDrawable(R.drawable.expander_group);
expandableList.setGroupIndicator(indicator);
setListAdapter(books);
}
private void fillDataTitle() {
Intent intent = getIntent();
// base the layout and the query on the sort order
int layout = R.layout.row_books;
int layout_child = R.layout.row_books;
// Get all of the rows from the database and create the item list
Cursor BooksCursor = null;
String order = CatalogueDBAdapter.KEY_TITLE + ", " + CatalogueDBAdapter.KEY_FAMILY_NAME;
//TODO: Title Search
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
BooksCursor = mDbHelper.searchBooks(query, order, bookshelf);
} else {
BooksCursor = mDbHelper.fetchAllBooks(order, bookshelf);
}
numAuthors = BooksCursor.getCount();
mGroupIdColumnIndex = BooksCursor.getColumnIndexOrThrow("_id");
startManagingCursor(BooksCursor);
// Create an array to specify the fields we want to display in the list
String[] from = new String[]{CatalogueDBAdapter.KEY_AUTHOR, CatalogueDBAdapter.KEY_TITLE, CatalogueDBAdapter.KEY_PUBLISHER, CatalogueDBAdapter.KEY_SERIES, CatalogueDBAdapter.KEY_SERIES_NUM};
String[] exp_from = new String[]{};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.row_author, R.id.row_title, R.id.row_publisher, R.id.row_series, R.id.row_series_num};
int[] exp_to = new int[]{};
ExpandableListAdapter books = new BooksBookListAdapter(BooksCursor, this, layout, layout_child, from, to, exp_from, exp_to);
/* Handle the click event. Do not open, but goto the book edit page */
ExpandableListView expandableList = getExpandableListView();
/* Hack. So we can pass the current context into the onGroupClick event */
final BookCatalogue pthis = this;
expandableList.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Intent i = new Intent(pthis, BookEdit.class);
i.putExtra(CatalogueDBAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
return true;
}
});
/* Hide the default expandable icon */
Drawable indicator = new BitmapDrawable();
indicator.setVisible(false, true);
expandableList.setGroupIndicator(indicator);
setListAdapter(books);
}
public class AuthorBookListAdapter extends SimpleCursorTreeAdapter {
boolean series = false;
public AuthorBookListAdapter(Cursor cursor, Context context, int groupLayout, int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom, int[] childrenTo) {
super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom, childrenTo);
}
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
return mDbHelper.fetchAllBooksByAuthor(groupCursor.getInt(mGroupIdColumnIndex), bookshelf);
}
@Override
public void setViewText(TextView v, String text) {
if (v.getId() == R.id.row_series) {
if (text.equals("")) {
series = false;
} else {
series = true;
text = "(" + text;
}
} else if (v.getId() == R.id.row_series_num) {
if (series == false) {
text = "";
} else if (series == true) {
if (text.equals("")) {
text = ")";
} else {
text = " #" + text + ")";
}
}
} else if (v.getId() == R.id.row_family) {
text = text + ", ";
}
v.setText(text);
}
}
public class BooksBookListAdapter extends SimpleCursorTreeAdapter {
boolean series = false;
public BooksBookListAdapter(Cursor cursor, Context context, int groupLayout, int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom, int[] childrenTo) {
super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom, childrenTo);
}
@Override
public void setViewText(TextView v, String text) {
if (v.getId() == R.id.row_series) {
if (text.equals("")) {
series = false;
} else {
series = true;
text = "(" + text;
}
} else if (v.getId() == R.id.row_series_num) {
if (series == false) {
text = "";
} else if (series == true) {
if (text.equals("")) {
text = ")";
} else {
text = " #" + text + ")";
}
}
}
v.setText(text);
}
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
optionsMenu = menu;
if (sort == 0) {
MenuItem collapse = menu.add(0, SORT_BY_AUTHOR_EXPANDED, 0, R.string.menu_sort_by_author_collapsed);
collapse.setIcon(R.drawable.ic_menu_collapse);
MenuItem expand = menu.add(0, SORT_BY_AUTHOR_COLLAPSED, 1, R.string.menu_sort_by_author_expanded);
expand.setIcon(R.drawable.ic_menu_expand);
}
MenuItem insert = menu.add(1, INSERT_ID, 2, R.string.menu_insert);
insert.setIcon(android.R.drawable.ic_menu_add);
MenuItem insertBC = menu.add(1, INSERT_BARCODE_ID, 3, R.string.menu_insert_barcode);
insertBC.setIcon(R.drawable.ic_menu_insert_barcode);
MenuItem insertISBN = menu.add(1, INSERT_ISBN_ID, 4, R.string.menu_insert_isbn);
insertISBN.setIcon(android.R.drawable.ic_menu_zoom);
if (sort == 0) {
MenuItem title = menu.add(2, SORT_BY_TITLE, 4, R.string.menu_sort_by_title);
title.setIcon(android.R.drawable.ic_menu_sort_alphabetically);
} else {
MenuItem title = menu.add(2, SORT_BY_AUTHOR, 4, R.string.menu_sort_by_author);
title.setIcon(android.R.drawable.ic_menu_sort_alphabetically);
}
MenuItem bookshelf = menu.add(2, BOOKSHELVES, 4, R.string.menu_bookshelf);
bookshelf.setIcon(R.drawable.ic_menu_bookshelves);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case SORT_BY_AUTHOR_COLLAPSED:
expandAll();
return true;
case SORT_BY_AUTHOR_EXPANDED:
collapseAll();
return true;
case SORT_BY_TITLE:
sortByTitle();
return true;
case SORT_BY_AUTHOR:
sortByAuthor();
return true;
case INSERT_ID:
//createDemoBook();
//fillData();
createBook();
return true;
case INSERT_ISBN_ID:
createBookISBN();
return true;
case INSERT_BARCODE_ID:
createBookScan();
return true;
case BOOKSHELVES:
manageBookselves();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
/*
* Expand all Author Groups
*/
public void expandAll() {
int i = 0;
while (i < numAuthors) {
ExpandableListView view = this.getExpandableListView();
boolean expand = view.expandGroup(i);
if (!expand) {
break;
}
i++;
}
}
/*
* Collapse all Author Groups
*/
public void collapseAll() {
int i = 0;
while (i < numAuthors) {
ExpandableListView view = this.getExpandableListView();
boolean expand = view.collapseGroup(i);
if (!expand) {
break;
}
i++;
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
try {
// Only delete titles, not authors
if (ExpandableListView.getPackedPositionType(info.packedPosition) == 1) {
MenuItem delete = menu.add(0, DELETE_ID, 0, R.string.menu_delete);
delete.setIcon(android.R.drawable.ic_menu_delete);
}
} catch (NullPointerException e) {
// do nothing
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();
mDbHelper.deleteBook(info.id);
fillData();
return true;
}
return super.onContextItemSelected(item);
}
/*
* Load the BookCatalogueTitle Activity
*
* return void
*/
private void sortByTitle() {
//Intent i = new Intent(this, BookCatalogueTitle.class);
//startActivityForResult(i, ACTIVITY_SORT);
sort = 1;
optionsMenu.clear();
onCreateOptionsMenu(optionsMenu);
fillData();
}
/*
* Load the BookCatalogueTitle Activity
*
* return void
*/
private void sortByAuthor() {
sort = 0;
optionsMenu.clear();
onCreateOptionsMenu(optionsMenu);
fillData();
}
/*
* Load the BookEdit Activity
*
* return void
*/
private void createBook() {
Intent i = new Intent(this, BookEdit.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
/*
* Load the BookEdit Activity
*
* return void
*/
private void createBookISBN() {
Intent i = new Intent(this, BookISBNSearch.class);
startActivityForResult(i, ACTIVITY_ISBN);
}
/*
* Load the BookEdit Activity
*
* return void
*/
private void createBookScan() {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
//intent.putExtra("SCAN_MODE", "EAN_13");
startActivityForResult(intent, ACTIVITY_SCAN);
}
/*
* Load the BookEdit Activity
*
* return void
*/
private void manageBookselves() {
Intent i = new Intent(this, Bookshelf.class);
startActivityForResult(i, ACTIVITY_BOOKSHELF);
}
@Override
public boolean onChildClick(ExpandableListView l, View v, int position, int childPosition, long id) {
boolean result = super.onChildClick(l, v, position, childPosition, id);
if (sort == 0) {
Intent i = new Intent(this, BookEdit.class);
i.putExtra(CatalogueDBAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}
return result;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch(requestCode) {
case ACTIVITY_SCAN:
try {
String contents = intent.getStringExtra("SCAN_RESULT");
Toast.makeText(this, R.string.isbn_found, Toast.LENGTH_LONG).show();
Intent i = new Intent(this, BookISBNSearch.class);
i.putExtra("isbn", contents);
startActivityForResult(i, ACTIVITY_ISBN);
} catch (NullPointerException e) {
// This is not a scan result, but a normal return
fillData();
}
break;
case ACTIVITY_CREATE:
case ACTIVITY_EDIT:
case ACTIVITY_SORT:
case ACTIVITY_ISBN:
case ACTIVITY_BOOKSHELF:
fillData();
break;
}
}
}

View File

@ -0,0 +1,220 @@
/*
* @copyright 2010 Evan Leybourn
*/
package com.eleybourn.bookcatalogue;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemSelectedListener;
/*
* A book catalogue application that integrates with Google Books.
*/
public class BookCatalogueTitle extends ListActivity {
private static final int ACTIVITY_CREATE=0;
private static final int ACTIVITY_EDIT=1;
private static final int ACTIVITY_SORT=2;
private CatalogueDBAdapter mDbHelper;
private static final int SORT_BY_AUTHOR = Menu.FIRST;
private static final int INSERT_ID = Menu.FIRST + 1;
private static final int DELETE_ID = Menu.FIRST + 2;
private static final int INSERT_ISBN_ID = Menu.FIRST + 3;
private static final int INSERT_BARCODE_ID = Menu.FIRST + 4;
private static final int BOOKSHELVES = Menu.FIRST + 5;
public String bookshelf = "";
private ArrayAdapter<String> spinnerAdapter;
public int sort = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_books);
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
bookshelf();
//fillBooks();
registerForContextMenu(getListView());
}
private void bookshelf() {
// Setup the Bookshelf Spinner
Spinner mBookshelfText = (Spinner) findViewById(R.id.bookshelf_name);
spinnerAdapter = new ArrayAdapter<String>(this, R.layout.spinner_frontpage);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mBookshelfText.setAdapter(spinnerAdapter);
/* Add the default All Books bookshelf */
spinnerAdapter.add(getString(R.string.all_books));
Cursor bookshelves = mDbHelper.fetchAllBookshelves();
if (bookshelves.moveToFirst()) {
do {
spinnerAdapter.add(bookshelves.getString(1));
}
while (bookshelves.moveToNext());
}
mBookshelfText.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parentView, View view, int position, long id) {
bookshelf = spinnerAdapter.getItem(position);
fillBooks();
}
public void onNothingSelected(AdapterView<?> parentView) {
// TODO Auto-generated method stub
}
});
}
private void fillBooks() {
// base the layout and the query on the sort order
int layout = R.layout.row_books;
String order = CatalogueDBAdapter.KEY_TITLE + ", " + CatalogueDBAdapter.KEY_FAMILY_NAME;
// Get all of the rows from the database and create the item list
Cursor BooksCursor = mDbHelper.fetchAllBooks(order, bookshelf);
startManagingCursor(BooksCursor);
// Create an array to specify the fields we want to display in the list
String[] from = new String[]{CatalogueDBAdapter.KEY_AUTHOR, CatalogueDBAdapter.KEY_TITLE, CatalogueDBAdapter.KEY_PUBLISHER};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.row_author, R.id.row_title, R.id.row_publisher};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter books = new SimpleCursorAdapter(this, layout, BooksCursor, from, to);
setListAdapter(books);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuItem author = menu.add(0, SORT_BY_AUTHOR, 0, R.string.menu_sort_by_author);
author.setIcon(android.R.drawable.ic_menu_sort_alphabetically);
MenuItem insert = menu.add(1, INSERT_ID, 2, R.string.menu_insert);
insert.setIcon(android.R.drawable.ic_menu_add);
MenuItem insertBC = menu.add(1, INSERT_BARCODE_ID, 3, R.string.menu_insert_barcode);
insertBC.setIcon(R.drawable.ic_menu_insert_barcode);
MenuItem insertISBN = menu.add(1, INSERT_ISBN_ID, 4, R.string.menu_insert_isbn);
insertISBN.setIcon(android.R.drawable.ic_menu_zoom);
MenuItem bookshelf = menu.add(2, BOOKSHELVES, 4, R.string.menu_bookshelf);
bookshelf.setIcon(R.drawable.ic_menu_bookshelves);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case SORT_BY_AUTHOR:
sort = SORT_BY_AUTHOR;
sortByAuthor();
return true;
case INSERT_ID:
createBook();
return true;
case INSERT_ISBN_ID:
case INSERT_BARCODE_ID:
createBookISBN();
return true;
case BOOKSHELVES:
manageBookselves();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
/*
* Load the BookEdit Activity
*
* return void
*/
private void createBookISBN() {
Intent i = new Intent(this, BookISBNSearch.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
/*
* Load the BookEdit Activity
*
* return void
*/
private void manageBookselves() {
Intent i = new Intent(this, Bookshelf.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
/*
* Load the BookCatalogueTitle Activity
*
* return void
*/
private void sortByAuthor() {
//Intent i = new Intent(this, BookCatalogue.class);
//startActivityForResult(i, ACTIVITY_SORT);
finish();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
mDbHelper.deleteBook(info.id);
fillBooks();
return true;
}
return super.onContextItemSelected(item);
}
private void createBook() {
Intent i = new Intent(this, BookEdit.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, BookEdit.class);
i.putExtra(CatalogueDBAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
fillBooks();
}
}

View File

@ -0,0 +1,316 @@
package com.eleybourn.bookcatalogue;
import java.io.File;
import java.util.ArrayList;
import android.app.Activity;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.Spinner;
import android.widget.Toast;
public class BookEdit extends Activity {
private AutoCompleteTextView mAuthorText;
private EditText mTitleText;
private EditText mIsbnText;
private AutoCompleteTextView mPublisherText;
private DatePicker mDate_publishedText;
private RatingBar mRatingText;
private Spinner mBookshelfText;
private ArrayAdapter<String> spinnerAdapter;
private CheckBox mReadText;
private AutoCompleteTextView mSeriesText;
private EditText mSeriesNumText;
private EditText mPagesText;
private Button mConfirmButton;
private Button mCancelButton;
private Long mRowId;
private CatalogueDBAdapter mDbHelper;
private ImageView mImageView;
protected void getRowId() {
/* Get any information from the extras bundle */
Bundle extras = getIntent().getExtras();
mRowId = extras != null ? extras.getLong(CatalogueDBAdapter.KEY_ROWID) : null;
}
protected ArrayList<String> getAuthors() {
ArrayList<String> author_list = new ArrayList<String>();
Cursor author_cur = mDbHelper.fetchAllAuthors("All Books");
startManagingCursor(author_cur);
while (author_cur.moveToNext()) {
String family = author_cur.getString(author_cur.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_FAMILY_NAME));
String given = author_cur.getString(author_cur.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_GIVEN_NAMES));
author_list.add(family + ", " + given);
}
return author_list;
}
protected ArrayList<String> getSeries() {
ArrayList<String> series_list = new ArrayList<String>();
Cursor series_cur = mDbHelper.fetchAllSeries();
startManagingCursor(series_cur);
while (series_cur.moveToNext()) {
String series = series_cur.getString(series_cur.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_SERIES));
Log.e("BC", series + "...");
series_list.add(series);
}
return series_list;
}
protected ArrayList<String> getPublishers() {
ArrayList<String> publisher_list = new ArrayList<String>();
Cursor publisher_cur = mDbHelper.fetchAllPublishers();
startManagingCursor(publisher_cur);
while (publisher_cur.moveToNext()) {
String publisher = publisher_cur.getString(publisher_cur.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_PUBLISHER));
publisher_list.add(publisher);
}
return publisher_list;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
setContentView(R.layout.edit_book);
ArrayAdapter<String> author_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, getAuthors());
mAuthorText = (AutoCompleteTextView) findViewById(R.id.author);
mAuthorText.setAdapter(author_adapter);
mTitleText = (EditText) findViewById(R.id.title);
mIsbnText = (EditText) findViewById(R.id.isbn);
ArrayAdapter<String> publisher_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, getPublishers());
mPublisherText = (AutoCompleteTextView) findViewById(R.id.publisher);
mPublisherText.setAdapter(publisher_adapter);
mDate_publishedText = (DatePicker) findViewById(R.id.date_published);
mRatingText = (RatingBar) findViewById(R.id.rating);
mReadText = (CheckBox) findViewById(R.id.read);
ArrayAdapter<String> series_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, getSeries());
mSeriesText = (AutoCompleteTextView) findViewById(R.id.series);
mSeriesText.setAdapter(series_adapter);
mSeriesNumText = (EditText) findViewById(R.id.series_num);
mPagesText = (EditText) findViewById(R.id.pages);
mConfirmButton = (Button) findViewById(R.id.confirm);
mCancelButton = (Button) findViewById(R.id.cancel);
mImageView = (ImageView) findViewById(R.id.row_img);
/* Setup the Bookshelf Spinner */
mBookshelfText = (Spinner) findViewById(R.id.bookshelf);
spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mBookshelfText.setAdapter(spinnerAdapter);
Cursor bookshelves = mDbHelper.fetchAllBookshelves();
if (bookshelves.moveToFirst()) {
do {
spinnerAdapter.add(bookshelves.getString(1));
}
while (bookshelves.moveToNext());
}
mRowId = savedInstanceState != null ? savedInstanceState.getLong(CatalogueDBAdapter.KEY_ROWID) : null;
if (mRowId == null) {
getRowId();
}
populateFields();
mConfirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
saveState();
setResult(RESULT_OK);
finish();
}
});
mCancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setResult(RESULT_OK);
finish();
}
});
} catch (Exception e) {
Log.e("Book Catalogue", "Unknown error " + e.toString());
}
}
private void populateFields() {
Bundle extras = getIntent().getExtras();
if (mRowId == null) {
getRowId();
}
if (mRowId != null && mRowId > 0) {
// From the database (edit)
Cursor book = mDbHelper.fetchBook(mRowId);
startManagingCursor(book);
mAuthorText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_AUTHOR)));
mTitleText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_TITLE)));
mIsbnText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_ISBN)));
mPublisherText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_PUBLISHER)));
String[] date = book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_DATE_PUBLISHED)).split("-");
int yyyy = Integer.parseInt(date[0]);
int mm = Integer.parseInt(date[1]);
int dd = Integer.parseInt(date[2]);
mDate_publishedText.updateDate(yyyy, mm, dd);
mRatingText.setRating(book.getFloat(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_RATING)));
String bs = book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_BOOKSHELF));
mBookshelfText.setSelection(spinnerAdapter.getPosition(bs));
//mBookshelfText.setSelection(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_BOOKSHELF)));
mReadText.setChecked((book.getInt(book.getColumnIndex(CatalogueDBAdapter.KEY_READ))==0? false:true) );
mSeriesText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_SERIES)));
mSeriesNumText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_SERIES_NUM)));
mPagesText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_PAGES)));
mConfirmButton.setText(R.string.confirm_save);
String thumbFilename = Environment.getExternalStorageDirectory() + "/" + CatalogueDBAdapter.LOCATION + "/" + mRowId + ".jpg";
mImageView.setImageBitmap(BitmapFactory.decodeFile(thumbFilename));
} else if (extras != null) {
// From the ISBN Search (add)
String[] book = extras.getStringArray("book");
mAuthorText.setText(book[0]);
mTitleText.setText(book[1]);
mIsbnText.setText(book[2]);
mPublisherText.setText(book[3]);
try {
String[] date = book[4].split("-");
int yyyy = Integer.parseInt(date[0]);
int mm = Integer.parseInt(date[1]);
int dd = Integer.parseInt(date[2]);
mDate_publishedText.updateDate(yyyy, mm, dd);
} catch (ArrayIndexOutOfBoundsException e) {
//do nothing
} catch (NumberFormatException e) {
//do nothing
}
mRatingText.setRating(Float.valueOf(book[5]));
mBookshelfText.setSelection(spinnerAdapter.getPosition(book[6]));
String read = book[7];
if (read == "true") {
mReadText.setChecked(true);
} else {
mReadText.setChecked(false);
}
mSeriesText.setText(book[8]);
mSeriesNumText.setText(book[10]);
mPagesText.setText(book[9]);
mConfirmButton.setText(R.string.confirm_add);
String tmpThumbFilename = Environment.getExternalStorageDirectory() + "/" + CatalogueDBAdapter.LOCATION + "/tmp.jpg";
mImageView.setImageBitmap(BitmapFactory.decodeFile(tmpThumbFilename));
} else {
// Manual Add
mConfirmButton.setText(R.string.confirm_add);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(CatalogueDBAdapter.KEY_ROWID, mRowId);
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
populateFields();
}
private void saveState() {
String author = mAuthorText.getText().toString();
/* Move "The, A, An" to the end of the string */
String title = mTitleText.getText().toString();
String[] title_words = title.split(" ");
try {
if (title_words[0].matches("a|A|an|An|the|The")) {
title = "";
for (int i = 1; i < title_words.length; i++) {
if (i != 1) {
title += " ";
}
title += title_words[i];
}
title += ", " + title_words[0];
}
} catch (Exception e) {
//do nothing. Title stays the same
}
String isbn = mIsbnText.getText().toString();
String publisher = mPublisherText.getText().toString();
int yyyy = mDate_publishedText.getYear();
int mm = mDate_publishedText.getMonth();
int dd = mDate_publishedText.getDayOfMonth();
String date_published = yyyy + "-" + mm + "-" + dd;
float rating = mRatingText.getRating();
String bookshelf = mBookshelfText.getAdapter().getItem(mBookshelfText.getSelectedItemPosition()).toString();
//.getText().toString();
Boolean read = mReadText.isChecked();
String series = mSeriesText.getText().toString();
String series_num = mSeriesNumText.getText().toString();
int pages = 0;
try {
pages = Integer.parseInt(mPagesText.getText().toString());
} catch (NumberFormatException e) {
pages = 0;
}
if (mRowId == null || mRowId == 0) {
/* Check if the book currently exists */
if (!isbn.equals("")) {
Cursor book = mDbHelper.fetchBookByISBN(isbn);
int rows = book.getCount();
if (rows != 0) {
Toast.makeText(this, R.string.book_exists, Toast.LENGTH_LONG).show();
return;
}
}
long id = mDbHelper.createBook(author, title, isbn, publisher, date_published, rating, bookshelf, read, series, pages, series_num);
if (id > 0) {
mRowId = id;
String tmpThumbFilename = Environment.getExternalStorageDirectory() + "/" + CatalogueDBAdapter.LOCATION + "/tmp.jpg";
String realThumbFilename = Environment.getExternalStorageDirectory() + "/" + CatalogueDBAdapter.LOCATION + "/" + id + ".jpg";
File thumb = new File(tmpThumbFilename);
File real = new File(realThumbFilename);
thumb.renameTo(real);
}
} else {
mDbHelper.updateBook(mRowId, author, title, isbn, publisher, date_published, rating, bookshelf, read, series, pages, series_num);
}
return;
}
}

View File

@ -0,0 +1,559 @@
package com.eleybourn.bookcatalogue;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class BookISBNSearch extends Activity {
private EditText mIsbnText;
private CatalogueDBAdapter mDbHelper;
private static String ID = "id";
private static String TOTALRESULTS = "totalResults";
private static String AUTHOR = "creator";
private static String TITLE = "title";
private static String ISBN = "identifier";
private static String ENTRY = "entry";
private static String DATE_PUBLISHED = "date";
private static String PUBLISHER = "publisher";
private static String PAGES = "format";
private static String THUMBNAIL = "link";
public String author;
public String title;
public String isbn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras != null) {
//ISBN has been passed by another component
isbn = extras.getString("isbn");
String[] book = search(isbn);
createBook(book);
setResult(RESULT_OK);
finish();
} else {
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
setContentView(R.layout.isbn_search);
mIsbnText = (EditText) findViewById(R.id.isbn);
Button confirmButton = (Button) findViewById(R.id.search);
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String mIsbn = mIsbnText.getText().toString();
String[] book = search(mIsbn);
createBook(book);
setResult(RESULT_OK);
finish();
}
});
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
private String[] search(String mIsbn) {
String path = "http://books.google.com/books/feeds/volumes?q=ISBN";
URL url;
//String[] book = {author, title, isbn, publisher, date_published, rating, bookshelf, read, series, pages, series_num};
String[] book = {"", "", mIsbn, "", "", "0", "", "", "", "", ""};
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser;
GoogleBooksHandler handler = new GoogleBooksHandler();
GoogleBooksEntryHandler entryHandler = new GoogleBooksEntryHandler();
try {
url = new URL(path+mIsbn);
parser = factory.newSAXParser();
int count = 0;
try {
parser.parse(getInputStream(url), handler);
count = handler.getCount();
} catch (RuntimeException e) {
Toast.makeText(this, R.string.unable_to_connect, Toast.LENGTH_LONG).show();
}
if (count > 0) {
String id = handler.getId();
url = new URL(id);
parser = factory.newSAXParser();
try {
parser.parse(getInputStream(url), entryHandler);
book = entryHandler.getBook();
} catch (RuntimeException e) {
Toast.makeText(this, R.string.unable_to_connect, Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, R.string.book_not_found, Toast.LENGTH_LONG).show();
}
return book;
} catch (MalformedURLException e) {
Log.e("Book Catalogue", "Malformed URL " + e.getMessage());
} catch (ParserConfigurationException e) {
Log.e("Book Catalogue", "SAX Parsing Error " + e.getMessage());
} catch (SAXException e) {
Log.e("Book Catalogue", "SAX Exception " + e.getMessage());
} catch (IOException e) {
Log.e("Book Catalogue", "SAX IO Exception " + e.getMessage());
}
return null;
}
protected InputStream getInputStream(URL url) {
try {
return url.openConnection().getInputStream();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/*
* An XML handler for the Google Books return
*
* An example response looks like;
* <?xml version='1.0' encoding='UTF-8'?>
* <feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gbs='http://schemas.google.com/books/2008' xmlns:dc='http://purl.org/dc/terms' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>
* <id>http://www.google.com/books/feeds/volumes</id>
* <updated>2010-02-28T03:28:09.000Z</updated>
* <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/books/2008#volume'/>
* <title type='text'>Search results for ISBN9780006483830</title>
* <link rel='alternate' type='text/html' href='http://www.google.com'/>
* <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes'/>
* <link rel='self' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes?q=ISBN9780006483830'/>
* <author>
* <name>Google Books Search</name>
* <uri>http://www.google.com</uri>
* </author>
* <generator version='beta'>Google Book Search data API</generator>
* <openSearch:totalResults>1</openSearch:totalResults>
* <openSearch:startIndex>1</openSearch:startIndex>
* <openSearch:itemsPerPage>1</openSearch:itemsPerPage>
* <entry>
* <id>http://www.google.com/books/feeds/volumes/A4NDPgAACAAJ</id>
* <updated>2010-02-28T03:28:09.000Z</updated>
* <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/books/2008#volume'/>
* <title type='text'>The trigger</title>
* <link rel='http://schemas.google.com/books/2008/info' type='text/html' href='http://books.google.com/books?id=A4NDPgAACAAJ&amp;dq=ISBN9780006483830&amp;ie=ISO-8859-1&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/preview' type='text/html' href='http://books.google.com/books?id=A4NDPgAACAAJ&amp;dq=ISBN9780006483830&amp;ie=ISO-8859-1&amp;cd=1&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/annotation' type='application/atom+xml' href='http://www.google.com/books/feeds/users/me/volumes'/>
* <link rel='alternate' type='text/html' href='http://books.google.com/books?id=A4NDPgAACAAJ&amp;dq=ISBN9780006483830&amp;ie=ISO-8859-1'/>
* <link rel='self' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes/A4NDPgAACAAJ'/>
* <gbs:embeddability value='http://schemas.google.com/books/2008#not_embeddable'/>
* <gbs:openAccess value='http://schemas.google.com/books/2008#disabled'/>
* <gbs:viewability value='http://schemas.google.com/books/2008#view_no_pages'/>
* <dc:creator>Arthur Charles Clarke</dc:creator>
* <dc:creator>Michael P. Kube-McDowell</dc:creator>
* <dc:date>2000-01-01</dc:date>
* <dc:format>550 pages</dc:format>
* <dc:format>book</dc:format>
* <dc:identifier>A4NDPgAACAAJ</dc:identifier>
* <dc:identifier>ISBN:0006483836</dc:identifier>
* <dc:identifier>ISBN:9780006483830</dc:identifier>
* <dc:subject>Fiction</dc:subject>
* <dc:title>The trigger</dc:title>
* </entry>
* </feed>
*
* <?xml version='1.0' encoding='UTF-8'?>
* <feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gbs='http://schemas.google.com/books/2008' xmlns:dc='http://purl.org/dc/terms' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>
* <id>http://www.google.com/books/feeds/volumes</id>
* <updated>2010-03-01T07:27:49.000Z</updated>
* <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/books/2008#volume'/>
* <title type='text'>Search results for ISBN9780307450340</title>
* <link rel='alternate' type='text/html' href='http://www.google.com'/>
* <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes'/>
* <link rel='self' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes?q=ISBN9780307450340'/>
* <author>
* <name>Google Books Search</name>
* <uri>http://www.google.com</uri>
* </author>
* <generator version='beta'>Google Book Search data API</generator>
* <openSearch:totalResults>1</openSearch:totalResults>
* <openSearch:startIndex>1</openSearch:startIndex>
* <openSearch:itemsPerPage>1</openSearch:itemsPerPage>
* <entry>
* <id>http://www.google.com/books/feeds/volumes/lf2EMetoLugC</id>
* <updated>2010-03-01T07:27:49.000Z</updated>
* <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/books/2008#volume'/>
* <title type='text'>The Geeks' Guide to World Domination</title>
* <link rel='http://schemas.google.com/books/2008/thumbnail' type='image/x-unknown' href='http://bks3.books.google.com/books?id=lf2EMetoLugC&amp;printsec=frontcover&amp;img=1&amp;zoom=5&amp;sig=ACfU3U1hcfy_NvWZbH46OzWwmQQCDV46lA&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/info' type='text/html' href='http://books.google.com/books?id=lf2EMetoLugC&amp;dq=ISBN9780307450340&amp;ie=ISO-8859-1&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/preview' type='text/html' href='http://books.google.com/books?id=lf2EMetoLugC&amp;dq=ISBN9780307450340&amp;ie=ISO-8859-1&amp;cd=1&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/annotation' type='application/atom+xml' href='http://www.google.com/books/feeds/users/me/volumes'/>
* <link rel='alternate' type='text/html' href='http://books.google.com/books?id=lf2EMetoLugC&amp;dq=ISBN9780307450340&amp;ie=ISO-8859-1'/>
* <link rel='self' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes/lf2EMetoLugC'/>
* <gbs:embeddability value='http://schemas.google.com/books/2008#not_embeddable'/>
* <gbs:openAccess value='http://schemas.google.com/books/2008#disabled'/>
* <gbs:viewability value='http://schemas.google.com/books/2008#view_no_pages'/>
* <dc:creator>Garth Sundem</dc:creator>
* <dc:date>2009-03-10</dc:date>
* <dc:description>And here, for you pathetic nongeeks, is the last chance to save yourselves: Love thisbook, live this book, and you too can join us in the experience of total ...</dc:description>
* <dc:format>245 pages</dc:format>
* <dc:format>book</dc:format>
* <dc:identifier>lf2EMetoLugC</dc:identifier>
* <dc:identifier>ISBN:0307450341</dc:identifier>
* <dc:identifier>ISBN:9780307450340</dc:identifier>
* <dc:publisher>Three Rivers Pr</dc:publisher>
* <dc:subject>Humor</dc:subject>
* <dc:title>The Geeks' Guide to World Domination</dc:title>
* <dc:title>Be Afraid, Beautiful People</dc:title>
* </entry>
* </feed>
*
*
* <?xml version='1.0' encoding='UTF-8'?>
* <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gbs='http://schemas.google.com/books/2008' xmlns:dc='http://purl.org/dc/terms' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>
* <id>http://www.google.com/books/feeds/volumes/A4NDPgAACAAJ</id>
* <updated>2010-02-28T10:49:24.000Z</updated>
* <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/books/2008#volume'/>
* <title type='text'>The trigger</title>
* <link rel='http://schemas.google.com/books/2008/info' type='text/html' href='http://books.google.com/books?id=A4NDPgAACAAJ&amp;ie=ISO-8859-1&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/annotation' type='application/atom+xml' href='http://www.google.com/books/feeds/users/me/volumes'/>
* <link rel='alternate' type='text/html' href='http://books.google.com/books?id=A4NDPgAACAAJ&amp;ie=ISO-8859-1'/>
* <link rel='self' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes/A4NDPgAACAAJ'/>
* <gbs:embeddability value='http://schemas.google.com/books/2008#not_embeddable'/>
* <gbs:openAccess value='http://schemas.google.com/books/2008#disabled'/>
* <gbs:viewability value='http://schemas.google.com/books/2008#view_no_pages'/>
* <dc:creator>Arthur Charles Clarke</dc:creator>
* <dc:creator>Michael P. Kube-McDowell</dc:creator>
* <dc:date>2000-01-01</dc:date>
* <dc:format>Dimensions 11.0x18.0x3.6 cm</dc:format>
* <dc:format>550 pages</dc:format>
* <dc:format>book</dc:format>
* <dc:identifier>A4NDPgAACAAJ</dc:identifier>
* <dc:identifier>ISBN:0006483836</dc:identifier>
* <dc:identifier>ISBN:9780006483830</dc:identifier>
* <dc:language>en</dc:language>
* <dc:publisher>Voyager</dc:publisher>
* <dc:subject>Fiction / Science Fiction / General</dc:subject>
* <dc:subject>Fiction / Technological</dc:subject>
* <dc:subject>Fiction / War &amp; Military</dc:subject>
* <dc:title>The trigger</dc:title>
* </entry>
*
* <?xml version='1.0' encoding='UTF-8'?>
* <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gbs='http://schemas.google.com/books/2008' xmlns:dc='http://purl.org/dc/terms' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>
* <id>http://www.google.com/books/feeds/volumes/lf2EMetoLugC</id>
* <updated>2010-03-01T07:31:23.000Z</updated>
* <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/books/2008#volume'/>
* <title type='text'>The Geeks' Guide to World Domination</title>
* <link rel='http://schemas.google.com/books/2008/thumbnail' type='image/x-unknown' href='http://bks3.books.google.com/books?id=lf2EMetoLugC&amp;printsec=frontcover&amp;img=1&amp;zoom=5&amp;sig=ACfU3U1hcfy_NvWZbH46OzWwmQQCDV46lA&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/info' type='text/html' href='http://books.google.com/books?id=lf2EMetoLugC&amp;ie=ISO-8859-1&amp;source=gbs_gdata'/>
* <link rel='http://schemas.google.com/books/2008/annotation' type='application/atom+xml' href='http://www.google.com/books/feeds/users/me/volumes'/>
* <link rel='alternate' type='text/html' href='http://books.google.com/books?id=lf2EMetoLugC&amp;ie=ISO-8859-1'/>
* <link rel='self' type='application/atom+xml' href='http://www.google.com/books/feeds/volumes/lf2EMetoLugC'/>
* <gbs:embeddability value='http://schemas.google.com/books/2008#not_embeddable'/>
* <gbs:openAccess value='http://schemas.google.com/books/2008#disabled'/>
* <gbs:viewability value='http://schemas.google.com/books/2008#view_no_pages'/>
* <dc:creator>Garth Sundem</dc:creator>
* <dc:date>2009-03-10</dc:date>
* <dc:description>TUNE IN. TURN ON. GEEK OUT.Sorry, beautiful people. These days, from government to business to technology to Hollywood, geeks rule the world. Finally, heres the book no self-respecting geek can live withouta guide jam-packed with 314.1516 short entries both useful and fun. Science, pop-culture trivia, paper airplanes, and pure geekish nostalgia coexist as happily in these pages as they do in their natural habitat of the geek brain.In short, dear geek, here youll find everything you need to achieve nirvana. And here, for you pathetic nongeeks, is the last chance to save yourselves: Love this book, live this book, and you too can join us in the experience of total world domination. become a sudoku god brew your own beer build a laser beam classify all living things clone your pet exorcise demons find the worlds best corn mazes grasp the theory of relativity have sex on Second Life injure a fish join the Knights Templar kick ass with sweet martial-arts moves learn ludicrous emoticons master the Ocarina of Time pimp your cubicle program a remote control quote He-Man and Che Guevara solve fiendish logic puzzles touch Carl Sagan unmask Linus Torvalds visit Beaver Lick, Kentucky win bar bets write your name in ElvishJoin us or die, you will.Begun, the Geek Wars have</dc:description>
* <dc:format>Dimensions 13.2x20.1x2.0 cm</dc:format>
* <dc:format>288 pages</dc:format>
* <dc:format>book</dc:format>
* <dc:identifier>lf2EMetoLugC</dc:identifier>
* <dc:identifier>ISBN:0307450341</dc:identifier>
* <dc:identifier>ISBN:9780307450340</dc:identifier>
* <dc:language>en</dc:language>
* <dc:publisher>Three Rivers Press</dc:publisher>
* <dc:subject>Curiosities and wonders/ Humor</dc:subject>
* <dc:subject>Geeks (Computer enthusiasts)/ Humor</dc:subject>
* <dc:subject>Curiosities and wonders</dc:subject>
* <dc:subject>Geeks (Computer enthusiasts)</dc:subject>
* <dc:subject>Humor / Form / Parodies</dc:subject>
* <dc:subject>Humor / General</dc:subject>
* <dc:subject>Humor / General</dc:subject>
* <dc:subject>Humor / Form / Comic Strips &amp; Cartoons</dc:subject>
* <dc:subject>Humor / Form / Essays</dc:subject>
* <dc:subject>Humor / Form / Parodies</dc:subject>
* <dc:subject>Reference / General</dc:subject>
* <dc:subject>Reference / Curiosities &amp; Wonders</dc:subject>
* <dc:subject>Reference / Encyclopedias</dc:subject>
* <dc:title>The Geeks' Guide to World Domination</dc:title>
* <dc:title>Be Afraid, Beautiful People</dc:title>
* </entry>
*
*/
public class GoogleBooksHandler extends DefaultHandler {
private StringBuilder builder;
public String id = "";
public int count = 0;
private boolean entry = false;
public String getId(){
return id;
}
public int getCount(){
return count;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
builder.append(ch, start, length);
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
if (localName.equalsIgnoreCase(TOTALRESULTS)){
count = Integer.parseInt(builder.toString());
}
if (entry == true && id == "") {
if (localName.equalsIgnoreCase(ID)){
id = builder.toString();
}
}
builder.setLength(0);
}
@Override
public void startDocument() throws SAXException {
super.startDocument();
builder = new StringBuilder();
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if (localName.equalsIgnoreCase(ENTRY)){
entry = true;
}
}
}
public String properCase(String inputString) {
StringBuilder ff = new StringBuilder();
int wordnum = 0;
for(String f: inputString.split(" ")) {
if(ff.length() > 0) {
ff.append(" ");
}
wordnum++;
String word = f.toLowerCase();
if (word.substring(0,1).matches("[\"\\(\\./\\\\,]")) {
wordnum = 1;
ff.append(word.substring(0,1));
word = word.substring(1,word.length());
}
/* Do not convert 1st char to uppercase in the following situations */
if (wordnum > 1 && word.matches("a|to|at|the|in|and|is|von")) {
ff.append(word);
continue;
}
try {
if (word.substring(0,2).equals("mc")) {
ff.append(word.substring(0,1).toUpperCase());
ff.append(word.substring(1,2));
ff.append(word.substring(2,3).toUpperCase());
ff.append(word.substring(3,word.length()));
continue;
}
} catch (StringIndexOutOfBoundsException e) {
// do nothing and continue;
}
try {
if (word.substring(0,3).equals("mac")) {
ff.append(word.substring(0,1).toUpperCase());
ff.append(word.substring(1,3));
ff.append(word.substring(3,4).toUpperCase());
ff.append(word.substring(4,word.length()));
continue;
}
} catch (StringIndexOutOfBoundsException e) {
// do nothing and continue;
}
try {
ff.append(word.substring(0,1).toUpperCase());
ff.append(word.substring(1,word.length()));
} catch (StringIndexOutOfBoundsException e) {
ff.append(word);
}
}
/* output */
String outputString = ff.toString();
return outputString;
}
public class GoogleBooksEntryHandler extends DefaultHandler {
private StringBuilder builder;
public String title = "";
public String author = "";
public String isbn = "";
public String publisher = "";
public String date_published = "";
public String rating = "0";
public String bookshelf = "";
public String read = "false";
public String series = "";
public String pages = "0";
public String thumbnail = "";
public String series_num = "";
public String[] getBook(){
String[] book = {author, title, isbn, publisher, date_published, rating, bookshelf, read, series, pages, series_num};
return book;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
builder.append(ch, start, length);
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
if (localName.equalsIgnoreCase(TITLE)){
if (title == "") {
title = properCase(builder.toString());
}
} else if (localName.equalsIgnoreCase(ISBN)){
String tmp = builder.toString();
if (tmp.indexOf("ISBN:") == 0) {
tmp = tmp.substring(5);
if (isbn == "" || tmp.length() > isbn.length()) {
isbn = tmp;
}
}
} else if (localName.equalsIgnoreCase(AUTHOR)){
if (author == "") {
author = properCase(builder.toString());
}
} else if (localName.equalsIgnoreCase(PUBLISHER)){
if (publisher == "") {
publisher = properCase(builder.toString());
}
} else if (localName.equalsIgnoreCase(DATE_PUBLISHED)){
if (date_published == "") {
date_published = builder.toString();
}
} else if (localName.equalsIgnoreCase(PAGES)){
String tmp = builder.toString();
int index = tmp.indexOf(" pages");
if (index > -1) {
tmp = tmp.substring(0, index).trim();
pages = tmp;
}
}
builder.setLength(0);
}
@Override
public void startDocument() throws SAXException {
super.startDocument();
builder = new StringBuilder();
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if (localName.equalsIgnoreCase(THUMBNAIL)){
if (attributes.getValue("", "rel").equals("http://schemas.google.com/books/2008/thumbnail")) {
thumbnail = attributes.getValue("", "href");
URL u;
try {
u = new URL(thumbnail);
} catch (MalformedURLException e) {
Log.e("Book Catalogue", "Malformed URL");
return;
}
HttpURLConnection c;
InputStream in = null;
try {
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
in = c.getInputStream();
} catch (IOException e) {
Log.e("Book Catalogue", "Thumbnail cannot be read");
return;
}
FileOutputStream f = null;
try {
f = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + CatalogueDBAdapter.LOCATION + "/tmp.jpg");
} catch (FileNotFoundException e) {
Log.e("Book Catalogue", "Thumbnail cannot be written");
return;
}
try {
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer,0, len1);
}
f.close();
} catch (IOException e) {
Log.e("Book Catalogue", "Error writing thumbnail");
return;
}
}
}
}
}
/*
* Load the BookEdit Activity
*
* return void
*/
private void createBook(String[] book) {
Intent i = new Intent(this, BookEdit.class);
i.putExtra("book", book);
startActivity(i);
}
}

View File

@ -0,0 +1,116 @@
package com.eleybourn.bookcatalogue;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
/*
* A book catalogue application that integrates with Google Books.
*/
public class Bookshelf extends ListActivity {
private static final int ACTIVITY_CREATE=0;
private static final int ACTIVITY_EDIT=1;
private CatalogueDBAdapter mDbHelper;
private static final int INSERT_ID = Menu.FIRST + 0;
private static final int DELETE_ID = Menu.FIRST + 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_bookshelves);
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
fillBookshelves();
registerForContextMenu(getListView());
}
private void fillBookshelves() {
// base the layout and the query on the sort order
int layout = R.layout.row_bookshelf;
// Get all of the rows from the database and create the item list
Cursor BookshelfCursor = mDbHelper.fetchAllBookshelves();
startManagingCursor(BookshelfCursor);
// Create an array to specify the fields we want to display in the list
String[] from = new String[]{CatalogueDBAdapter.KEY_BOOKSHELF, CatalogueDBAdapter.KEY_ROWID};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.row_bookshelf};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter books = new SimpleCursorAdapter(this, layout, BookshelfCursor, from, to);
setListAdapter(books);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, 0, R.string.menu_insert_bs);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case INSERT_ID:
createBookshelf();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete_bs);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
if (info.id == 1) {
Toast.makeText(this, R.string.delete_1st_bs, Toast.LENGTH_LONG).show();
} else {
mDbHelper.deleteBookshelf(info.id);
fillBookshelves();
}
return true;
}
return super.onContextItemSelected(item);
}
private void createBookshelf() {
Intent i = new Intent(this, BookshelfEdit.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, BookshelfEdit.class);
i.putExtra(CatalogueDBAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
fillBookshelves();
}
}

View File

@ -0,0 +1,100 @@
package com.eleybourn.bookcatalogue;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class BookshelfEdit extends Activity {
private EditText mBookshelfText;
private Button mConfirmButton;
private Button mCancelButton;
private Long mRowId;
private CatalogueDBAdapter mDbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
setContentView(R.layout.edit_bookshelf);
mBookshelfText = (EditText) findViewById(R.id.bookshelf);
mConfirmButton = (Button) findViewById(R.id.confirm);
mCancelButton = (Button) findViewById(R.id.cancel);
mRowId = savedInstanceState != null ? savedInstanceState.getLong(CatalogueDBAdapter.KEY_ROWID) : null;
if (mRowId == null) {
Bundle extras = getIntent().getExtras();
mRowId = extras != null ? extras.getLong(CatalogueDBAdapter.KEY_ROWID) : null;
}
populateFields();
mConfirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
saveState();
setResult(RESULT_OK);
finish();
}
});
mCancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setResult(RESULT_OK);
finish();
}
});
} catch (Exception e) {
//do nothing
}
}
private void populateFields() {
if (mRowId != null && mRowId > 0) {
Cursor bookshelf = mDbHelper.fetchBookshelf(mRowId);
startManagingCursor(bookshelf);
mBookshelfText.setText(bookshelf.getString(bookshelf.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_BOOKSHELF)));
mConfirmButton.setText(R.string.confirm_save_bs);
} else {
mConfirmButton.setText(R.string.confirm_add_bs);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(CatalogueDBAdapter.KEY_ROWID, mRowId);
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
populateFields();
}
private void saveState() {
String bookshelf = mBookshelfText.getText().toString();
if (mRowId == null || mRowId == 0) {
long id = mDbHelper.createBookshelf(bookshelf);
if (id > 0) {
mRowId = id;
}
} else {
mDbHelper.updateBookshelf(mRowId, bookshelf);
}
}
}

View File

@ -0,0 +1,631 @@
/*
* @copyright 2010 Evan Leybourn
*/
package com.eleybourn.bookcatalogue;
import java.io.File;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.util.Log;
/**
* Book Catalogue database access helper class. Defines the basic CRUD operations
* for the catalogue (based on the Notepad tutorial) example, and gives the
* ability to list all notes as well as retrieve or modify a specific book.
*/
public class CatalogueDBAdapter {
public static final String KEY_AUTHOR = "author";
public static final String KEY_TITLE = "title";
public static final String KEY_ISBN = "isbn";
public static final String KEY_PUBLISHER = "publisher";
public static final String KEY_DATE_PUBLISHED = "date_published";
public static final String KEY_RATING = "rating";
public static final String KEY_BOOKSHELF = "bookshelf";
public static final String KEY_READ = "read";
public static final String KEY_SERIES = "series";
public static final String KEY_PAGES = "pages";
public static final String KEY_ROWID = "_id";
public static final String KEY_FAMILY_NAME = "family_name";
public static final String KEY_GIVEN_NAMES = "given_names";
public static final String LOCATION = "bookCatalogue";
public static final String KEY_SERIES_NUM = "series_num";
private static final String TAG = "CatalogueDBAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String DATABASE_NAME = "book_catalogue";
private static final String DATABASE_TABLE_BOOKS = "books";
private static final String DATABASE_TABLE_AUTHORS = "authors";
private static final String DATABASE_TABLE_BOOKSHELF = "bookshelf";
private static final int DATABASE_VERSION = 13;
/**
* Database creation sql statement
*/
private static final String DATABASE_CREATE_AUTHORS =
"create table " + DATABASE_TABLE_AUTHORS +
" (_id integer primary key autoincrement, " +
KEY_FAMILY_NAME + " text not null, " +
KEY_GIVEN_NAMES + " text not null" +
")";
private static final String DATABASE_CREATE_BOOKSHELF =
"create table " + DATABASE_TABLE_BOOKSHELF +
" (_id integer primary key autoincrement, " +
KEY_BOOKSHELF + " text not null " +
")";
private static final String DATABASE_CREATE_BOOKSHELF_DATA =
"INSERT INTO " + DATABASE_TABLE_BOOKSHELF +
" (" + KEY_BOOKSHELF + ") VALUES ('Default')";
private static final String DATABASE_CREATE_BOOKS =
"create table " + DATABASE_TABLE_BOOKS +
" (_id integer primary key autoincrement, " +
KEY_AUTHOR + " integer not null REFERENCES " + DATABASE_TABLE_AUTHORS + ", " +
KEY_TITLE + " text not null, " +
KEY_ISBN + " text, " +
KEY_PUBLISHER + " text, " +
KEY_DATE_PUBLISHED + " date, " +
KEY_RATING + " float not null default 0, " +
KEY_BOOKSHELF + " integer REFERENCES " + DATABASE_TABLE_BOOKSHELF + " ON DELETE SET NULL ON UPDATE SET NULL, " +
KEY_READ + " boolean not null default 'f', " +
KEY_SERIES + " text, " +
KEY_PAGES + " int" +
KEY_SERIES_NUM + " text, " +
")";
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE_AUTHORS);
db.execSQL(DATABASE_CREATE_BOOKSHELF);
db.execSQL(DATABASE_CREATE_BOOKS);
db.execSQL(DATABASE_CREATE_BOOKSHELF_DATA);
new File(Environment.getExternalStorageDirectory() + "/" + LOCATION + "/").mkdirs();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", existing data will be saved");
int curVersion = oldVersion;
if (curVersion < 11) {
onCreate(db);
}
if (curVersion == 11) {
db.execSQL("ALTER TABLE " + DATABASE_TABLE_BOOKS + " ADD " + KEY_SERIES_NUM + " text");
db.execSQL("UPDATE " + DATABASE_TABLE_BOOKS + " SET " + KEY_SERIES_NUM + " = ''");
curVersion++;
}
if (curVersion == 12) {
//do nothing except increment
curVersion++;
}
}
}
/**
* Constructor - takes the context to allow the database to be
* opened/created
*
* @param ctx the Context within which to work
*/
public CatalogueDBAdapter(Context ctx) {
this.mCtx = ctx;
}
/**
* Open the notes database. If it cannot be opened, try to create a new
* instance of the database. If it cannot be created, throw an exception to
* signal the failure
*
* @return this (self reference, allowing this to be chained in an
* initialization call)
* @throws SQLException if the database could be neither opened or created
*/
public CatalogueDBAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
/*
* This will return the author id based on the name.
* The name can be in either "family, given" or "given family" format.
*/
public String[] processAuthorName(String name) {
String[] author = {"", ""};
String family = "";
String given = "";
String names[];
int commaIndex = name.indexOf(",");
if (commaIndex > 0) {
family = name.substring(0, commaIndex);
given = name.substring(commaIndex+1);
} else {
names = name.split(" ");
family = names[names.length-1];
for (int i=0; i<names.length-1; i++) {
given += names[i] + " ";
}
}
family = family.trim();
given = given.trim();
author[0] = family;
author[1] = given;
return author;
}
/*
* This will return the author id based on the name.
* The name can be in either "family, given" or "given family" format.
*/
public Cursor getBookshelfByName(String name) {
String sql = "";
sql = KEY_BOOKSHELF + "='" + name + "'";
return mDb.query(DATABASE_TABLE_BOOKSHELF, new String[] {"_id", KEY_BOOKSHELF}, sql, null, null, null, null);
}
/*
* This will return the author id based on the name.
* The name can be in either "family, given" or "given family" format.
*/
public Cursor getAuthorByName(String name) {
String[] names = processAuthorName(name);
String sql = "";
sql = KEY_FAMILY_NAME + "='" + names[0] + "' AND " + KEY_GIVEN_NAMES + "='" + names[1] + "'";
return mDb.query(DATABASE_TABLE_AUTHORS, new String[] {"_id", KEY_FAMILY_NAME, KEY_GIVEN_NAMES}, sql, null, null, null, null);
}
/*
* This will return the author id based on the name.
* The name can be in either "family, given" or "given family" format.
*/
public Cursor getAuthorByName(String[] names) {
String sql = "";
sql = KEY_FAMILY_NAME + "='" + names[0] + "' AND " + KEY_GIVEN_NAMES + "='" + names[1] + "'";
return mDb.query(DATABASE_TABLE_AUTHORS, new String[] {"_id", KEY_FAMILY_NAME, KEY_GIVEN_NAMES}, sql, null, null, null, null);
}
public long createBookshelf(String bookshelf) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_BOOKSHELF, bookshelf);
return mDb.insert(DATABASE_TABLE_BOOKSHELF, null, initialValues);
}
public long createAuthor(String family_name, String given_names) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_FAMILY_NAME, family_name);
initialValues.put(KEY_GIVEN_NAMES, given_names);
return mDb.insert(DATABASE_TABLE_AUTHORS, null, initialValues);
}
/**
* Create a new note using the title and body provided. If the note is
* successfully created return the new rowId for that note, otherwise return
* a -1 to indicate failure.
*
* @param title the title of the note
* @param body the body of the note
* @return rowId or -1 if failed
*/
public long createBook(String author, String title, String isbn, String publisher, String date_published, float rating, String bookshelf, Boolean read, String series, int pages, String series_num) {
ContentValues initialValues = new ContentValues();
String[] names = processAuthorName(author);
Cursor authorId = getAuthorByName(names);
int aRows = authorId.getCount();
if (aRows == 0) {
createAuthor(names[0], names[1]);
authorId.close();
authorId = getAuthorByName(names);
}
authorId.moveToFirst();
int bookshelf_id=1;
if (bookshelf != "") {
Cursor bookshelfId = getBookshelfByName(bookshelf);
int bRows = bookshelfId.getCount();
if (bRows == 0) {
createBookshelf(bookshelf);
bookshelfId.close();
bookshelfId = getBookshelfByName(bookshelf);
}
bookshelfId.moveToFirst();
bookshelf_id = bookshelfId.getInt(0);
bookshelfId.close();
}
initialValues.put(KEY_AUTHOR, authorId.getInt(0));
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_ISBN, isbn);
initialValues.put(KEY_PUBLISHER, publisher);
initialValues.put(KEY_DATE_PUBLISHED, date_published);
initialValues.put(KEY_RATING, rating);
initialValues.put(KEY_BOOKSHELF, bookshelf_id);
initialValues.put(KEY_READ, read);
initialValues.put(KEY_SERIES, series);
initialValues.put(KEY_PAGES, pages);
initialValues.put(KEY_SERIES_NUM, series_num);
authorId.close();
return mDb.insert(DATABASE_TABLE_BOOKS, null, initialValues);
}
/**
* Delete the book with the given rowId
*
* @param rowId id of note to delete
* @return true if deleted, false otherwise
*/
public boolean deleteBook(long rowId) {
boolean success;
success = mDb.delete(DATABASE_TABLE_BOOKS, KEY_ROWID + "=" + rowId, null) > 0;
deleteAuthors();
return success;
}
/**
* Delete the author with the given rowId
*
* @param rowId id of note to delete
* @return true if deleted, false otherwise
*/
public boolean deleteAuthors() {
return mDb.delete(DATABASE_TABLE_AUTHORS, "_id NOT IN (SELECT DISTINCT " + KEY_AUTHOR + " FROM " + DATABASE_TABLE_BOOKS + ")", null) > 0;
}
/**
* Delete the bookshelf with the given rowId
*
* @param rowId id of note to delete
* @return true if deleted, false otherwise
*/
public boolean deleteBookshelf(long rowId) {
boolean deleteSuccess;
String sql = "UPDATE " + DATABASE_TABLE_BOOKS + " SET " + KEY_BOOKSHELF + "=1 WHERE " + KEY_BOOKSHELF + "='" + rowId + "'";
mDb.execSQL(sql);
deleteSuccess = mDb.delete(DATABASE_TABLE_BOOKSHELF, KEY_ROWID + "=" + rowId, null) > 0;
return deleteSuccess;
}
/**
* Return a Cursor over the list of all books in the database
*
* @return Cursor over all notes
*/
public Cursor fetchAllBooks(String order, String bookshelf) {
String where = "";
if (bookshelf.equals("All Books")) {
// do nothing
} else {
where += " AND bs." + KEY_BOOKSHELF + "='" + bookshelf + "'";
}
String sql = "SELECT b." + KEY_ROWID + ", a." + KEY_FAMILY_NAME + " || ', ' || a." + KEY_GIVEN_NAMES + " as " + KEY_AUTHOR + ", b." + KEY_TITLE +
", b." + KEY_ISBN + ", b." + KEY_PUBLISHER + ", b." + KEY_DATE_PUBLISHED + ", b." + KEY_RATING + ", bs." + KEY_BOOKSHELF +
", b." + KEY_READ + ", b." + KEY_SERIES + ", b." + KEY_PAGES + ", b." + KEY_SERIES_NUM +
" FROM " + DATABASE_TABLE_BOOKS + " b, " + DATABASE_TABLE_BOOKSHELF + " bs, " + DATABASE_TABLE_AUTHORS + " a" +
" WHERE bs._id=b." + KEY_BOOKSHELF + " AND a._id=b." + KEY_AUTHOR + where +
" ORDER BY " + order + "";
return mDb.rawQuery(sql, new String[]{});
//return mDb.query(DATABASE_TABLE_BOOKS, new String[] {KEY_ROWID, KEY_AUTHOR, KEY_TITLE, KEY_ISBN, KEY_PUBLISHER,
// KEY_DATE_PUBLISHED, KEY_RATING, KEY_BOOKSHELF, KEY_READ, KEY_SERIES, KEY_PAGES}, null, null, null, null, null);
}
/**
* Return a Cursor over the list of all books in the database by author
*
* @return Cursor over all notes
*/
public Cursor fetchAllBooksByAuthor(int author, String bookshelf) {
String where = "";
if (bookshelf.equals("All Books")) {
// do nothing
} else {
where += " AND bs." + KEY_BOOKSHELF + "='" + bookshelf + "'";
}
String sql = "SELECT b." + KEY_ROWID + ", a." + KEY_FAMILY_NAME + " || ', ' || a." + KEY_GIVEN_NAMES + " as " + KEY_AUTHOR + ", b." + KEY_TITLE +
", b." + KEY_ISBN + ", b." + KEY_PUBLISHER + ", b." + KEY_DATE_PUBLISHED + ", b." + KEY_RATING + ", bs." + KEY_BOOKSHELF +
", b." + KEY_READ + ", b." + KEY_SERIES + ", b." + KEY_PAGES + ", b." + KEY_SERIES_NUM +
" FROM " + DATABASE_TABLE_BOOKS + " b, " + DATABASE_TABLE_BOOKSHELF + " bs, " + DATABASE_TABLE_AUTHORS + " a" +
" WHERE bs._id=b." + KEY_BOOKSHELF + " AND a._id=b." + KEY_AUTHOR + " AND a._id=" + author + where +
" ORDER BY b." + KEY_SERIES + ", substr('0000000000' || b." + KEY_SERIES_NUM + ", -10, 10), b." + KEY_TITLE + " ASC";
return mDb.rawQuery(sql, new String[]{});
}
public Cursor fetchBookByISBN(String isbn) {
String sql = "SELECT b." + KEY_ROWID + ", a." + KEY_FAMILY_NAME + " || ', ' || a." + KEY_GIVEN_NAMES + " as " + KEY_AUTHOR + ", b." + KEY_TITLE +
", b." + KEY_ISBN + ", b." + KEY_PUBLISHER + ", b." + KEY_DATE_PUBLISHED + ", b." + KEY_RATING + ", bs." + KEY_BOOKSHELF +
", b." + KEY_READ + ", b." + KEY_SERIES + ", b." + KEY_PAGES + ", b." + KEY_SERIES_NUM +
" FROM " + DATABASE_TABLE_BOOKS + " b, " + DATABASE_TABLE_BOOKSHELF + " bs, " + DATABASE_TABLE_AUTHORS + " a" +
" WHERE bs._id=b." + KEY_BOOKSHELF + " AND a._id=b." + KEY_AUTHOR + " AND b." + KEY_ISBN + "=" + isbn +
" ORDER BY b." + KEY_TITLE + "";
return mDb.rawQuery(sql, new String[]{});
}
/**
* Return a Cursor over the list of all books in the database
*
* @return Cursor over all notes
*/
public Cursor fetchAllAuthors(String bookshelf) {
String where = "";
if (bookshelf.equals("All Books")) {
// do nothing
} else {
where += " WHERE a." + KEY_ROWID + " IN (SELECT " + KEY_AUTHOR + " FROM " +
DATABASE_TABLE_BOOKS + " b, " + DATABASE_TABLE_BOOKSHELF + " bs WHERE bs." + KEY_ROWID + "=b." + KEY_BOOKSHELF +
" AND bs." + KEY_BOOKSHELF + "='" + bookshelf + "') ";
}
String sql = "SELECT a._id, a." + KEY_FAMILY_NAME + ", a." + KEY_GIVEN_NAMES +
" FROM " + DATABASE_TABLE_AUTHORS + " a" + where +
" ORDER BY " + KEY_FAMILY_NAME + ", " + KEY_GIVEN_NAMES + "";
return mDb.rawQuery(sql, new String[]{});
}
/**
* Return a Cursor over the list of all series in the database
*
* @return Cursor over all notes
*/
public Cursor fetchAllSeries() {
String sql = "SELECT DISTINCT " + KEY_SERIES +
" FROM " + DATABASE_TABLE_BOOKS + "" +
" ORDER BY " + KEY_SERIES + "";
return mDb.rawQuery(sql, new String[]{});
}
/**
* Return a Cursor over the list of all publishers in the database
*
* @return Cursor over all notes
*/
public Cursor fetchAllPublishers() {
String sql = "SELECT DISTINCT " + KEY_PUBLISHER +
" FROM " + DATABASE_TABLE_BOOKS + "" +
" ORDER BY " + KEY_PUBLISHER + "";
return mDb.rawQuery(sql, new String[]{});
}
/**
* Return a Cursor over the list of all books in the database
*
* @return Cursor over all notes
*/
public Cursor searchAuthors(String query, String bookshelf) {
String where = "";
if (bookshelf.equals("All Books")) {
// do nothing
} else {
where += " AND a." + KEY_ROWID + " IN (SELECT " + KEY_AUTHOR + " FROM " +
DATABASE_TABLE_BOOKS + " b, " + DATABASE_TABLE_BOOKSHELF + " bs WHERE bs." + KEY_ROWID + "=b." + KEY_BOOKSHELF +
" AND bs." + KEY_BOOKSHELF + "='" + bookshelf + "') ";
}
String sql = "SELECT a._id, a." + KEY_FAMILY_NAME + ", a." + KEY_GIVEN_NAMES +
" FROM " + DATABASE_TABLE_AUTHORS + " a" + " WHERE " +
" (a." + KEY_FAMILY_NAME + " LIKE '%" + query + "%' OR a." + KEY_GIVEN_NAMES + " LIKE '%" + query + "%' OR " +
"a." + KEY_ROWID + " IN (SELECT " + KEY_AUTHOR + " FROM " + DATABASE_TABLE_BOOKS + " b WHERE b." + KEY_TITLE + " LIKE '%" + query + "%') )" +
where + " ORDER BY " + KEY_FAMILY_NAME + ", " + KEY_GIVEN_NAMES + "";
return mDb.rawQuery(sql, new String[]{});
}
/**
* Return a Cursor over the list of all books in the database
*
* @return Cursor over all notes
*/
public Cursor searchBooks(String query, String order, String bookshelf) {
String where = "";
if (bookshelf.equals("All Books")) {
// do nothing
} else {
where += " AND bs." + KEY_BOOKSHELF + "='" + bookshelf + "'";
}
String sql = "SELECT b." + KEY_ROWID + ", a." + KEY_FAMILY_NAME + " || ', ' || a." + KEY_GIVEN_NAMES + " as " + KEY_AUTHOR + ", b." + KEY_TITLE +
", b." + KEY_ISBN + ", b." + KEY_PUBLISHER + ", b." + KEY_DATE_PUBLISHED + ", b." + KEY_RATING + ", bs." + KEY_BOOKSHELF +
", b." + KEY_READ + ", b." + KEY_SERIES + ", b." + KEY_PAGES + ", b." + KEY_SERIES_NUM +
" FROM " + DATABASE_TABLE_BOOKS + " b, " + DATABASE_TABLE_BOOKSHELF + " bs, " + DATABASE_TABLE_AUTHORS + " a" +
" WHERE bs._id=b." + KEY_BOOKSHELF + " AND a._id=b." + KEY_AUTHOR +
" AND (a." + KEY_FAMILY_NAME + " LIKE '%" + query + "%' OR a." + KEY_GIVEN_NAMES + " LIKE '%" + query + "%' OR " +
" b." + KEY_TITLE + " LIKE '%" + query + "%')" +
where +
" ORDER BY " + order + "";
return mDb.rawQuery(sql, new String[]{});
}
/**
* Return a Cursor over the list of all books in the database
*
* @return Cursor over all notes
*/
public Cursor fetchAllBookshelves() {
String sql = "SELECT b." + KEY_ROWID + ", b." + KEY_BOOKSHELF +
" FROM " + DATABASE_TABLE_BOOKSHELF + " b" +
" ORDER BY " + KEY_BOOKSHELF + "";
return mDb.rawQuery(sql, new String[]{});
}
/**
* Return a Cursor positioned at the books that matches the given rowId
*
* @param rowId id of note to retrieve
* @return Cursor positioned to matching note, if found
* @throws SQLException if note could not be found/retrieved
*/
public Cursor fetchBook(long rowId) throws SQLException {
String sql = "SELECT b." + KEY_ROWID + ", a." + KEY_FAMILY_NAME + " || ', ' || a." + KEY_GIVEN_NAMES + " as " + KEY_AUTHOR +
", b." + KEY_TITLE + ", b." + KEY_ISBN + ", b." + KEY_PUBLISHER + ", b." + KEY_DATE_PUBLISHED + ", b." + KEY_RATING +
", bs." + KEY_BOOKSHELF +
", b." + KEY_READ + ", b." + KEY_SERIES + ", b." + KEY_PAGES + ", b." + KEY_SERIES_NUM +
" FROM " + DATABASE_TABLE_BOOKS + " b, " + DATABASE_TABLE_BOOKSHELF + " bs, " + DATABASE_TABLE_AUTHORS + " a" +
" WHERE bs._id=b." + KEY_BOOKSHELF + " AND a._id=b." + KEY_AUTHOR + " AND b." + KEY_ROWID + "=" + rowId + "";
Cursor mCursor = mDb.rawQuery(sql, new String[]{});
//Cursor mCursor = mDb.query(true, DATABASE_TABLE_BOOKS, new String[] {KEY_ROWID, KEY_AUTHOR, KEY_TITLE, KEY_ISBN, KEY_PUBLISHER,
// KEY_DATE_PUBLISHED, KEY_RATING, KEY_BOOKSHELF, KEY_READ, KEY_SERIES, KEY_PAGES}, KEY_ROWID + "=" + rowId,
// null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Return a Cursor positioned at the books that matches the given rowId
*
* @param rowId id of note to retrieve
* @return Cursor positioned to matching note, if found
* @throws SQLException if note could not be found/retrieved
*/
public Cursor fetchBookshelf(long rowId) throws SQLException {
String sql = "SELECT b." + KEY_ROWID + ", b." + KEY_BOOKSHELF +
" FROM " + DATABASE_TABLE_BOOKSHELF + " b " +
" WHERE b." + KEY_ROWID + "=" + rowId + "";
Cursor mCursor = mDb.rawQuery(sql, new String[]{});
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Return a Cursor positioned at the books that matches the given rowId
*
* @param rowId id of note to retrieve
* @return Cursor positioned to matching note, if found
* @throws SQLException if note could not be found/retrieved
*/
public Cursor fetchAuthor(long rowId) throws SQLException {
String sql = "SELECT a." + KEY_ROWID + ", a." + KEY_FAMILY_NAME + ", a." + KEY_GIVEN_NAMES +
" FROM " + DATABASE_TABLE_AUTHORS + " a " +
" WHERE a." + KEY_ROWID + "=" + rowId + "";
Cursor mCursor = mDb.rawQuery(sql, new String[]{});
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Update the note using the details provided. The note to be updated is
* specified using the rowId, and it is altered to use the title and body
* values passed in
*
* @param rowId id of note to update
* @param title value to set note title to
* @param body value to set note body to
* @return true if the note was successfully updated, false otherwise
*/
public boolean updateBook(long rowId, String author, String title, String isbn, String publisher, String date_published, float rating, String bookshelf, Boolean read, String series, int pages, String series_num) {
boolean success;
ContentValues args = new ContentValues();
String[] names = processAuthorName(author);
Cursor authorId = getAuthorByName(names);
int aRows = authorId.getCount();
if (aRows == 0) {
createAuthor(names[0], names[1]);
authorId.close();
authorId = getAuthorByName(names);
}
int bookshelf_id=1;
if (bookshelf != "") {
Cursor bookshelfId = getBookshelfByName(bookshelf);
int bRows = bookshelfId.getCount();
if (bRows == 0) {
createBookshelf(bookshelf);
bookshelfId.close();
bookshelfId = getBookshelfByName(bookshelf);
}
bookshelfId.moveToFirst();
bookshelf_id = bookshelfId.getInt(0);
bookshelfId.close();
}
authorId.moveToFirst();
args.put(KEY_AUTHOR, authorId.getInt(0));
args.put(KEY_TITLE, title);
args.put(KEY_ISBN, isbn);
args.put(KEY_PUBLISHER, publisher);
args.put(KEY_DATE_PUBLISHED, date_published);
args.put(KEY_RATING, rating);
args.put(KEY_BOOKSHELF, bookshelf_id);
args.put(KEY_READ, read);
args.put(KEY_SERIES, series);
args.put(KEY_PAGES, pages);
args.put(KEY_SERIES_NUM, series_num);
authorId.close();
success = mDb.update(DATABASE_TABLE_BOOKS, args, KEY_ROWID + "=" + rowId, null) > 0;
deleteAuthors();
return success;
}
/**
* Update the note using the details provided. The note to be updated is
* specified using the rowId, and it is altered to use the title and body
* values passed in
*
* @param rowId id of note to update
* @param title value to set note title to
* @param body value to set note body to
* @return true if the note was successfully updated, false otherwise
*/
public boolean updateBookshelf(long rowId, String bookshelf) {
boolean success;
ContentValues args = new ContentValues();
args.put(KEY_BOOKSHELF, bookshelf);
success = mDb.update(DATABASE_TABLE_BOOKSHELF, args, KEY_ROWID + "=" + rowId, null) > 0;
deleteAuthors();
return success;
}
}