Book类
package cd.itcast.read.domain;
import java.util.Date;
public class Book {
//_ID
privateint _id;
//书名:
privateString name;
//作者
privateString author;
//密码
privateString password;
//文件路径
privateString filePath;
//简介
privateString descs;
//最后阅读时间
privateDate lastReadTime;
//文件总的大小
privatelong fileSize;
//阅读文件进度:字节
privateint start;
publicint getId() {
return_id;
}
publicvoid setId(int _id) {
this._id= _id;
}
publicString getName() {
returnname;
}
publicvoid setName(String name) {
this.name= name;
}
publicString getAuthor() {
returnauthor;
}
publicvoid setAuthor(String author) {
this.author= author;
}
publicString getPassword() {
returnpassword;
}
publicvoid setPassword(String password) {
this.password= password;
}
publicString getFilePath() {
returnfilePath;
}
publicvoid setFilePath(String filePath) {
this.filePath= filePath;
}
publicString getDescs() {
returndescs;
}
publicvoid setDescs(String descs) {
this.descs= descs;
}
publicDate getLastReadTime() {
returnlastReadTime;
}
publicvoid setLastReadTime(Date lastReadTime) {
this.lastReadTime= lastReadTime;
}
publiclong getFileSize() {
returnfileSize;
}
publicvoid setFileSize(long fileSize) {
this.fileSize= fileSize;
}
publicint getStart() {
returnstart;
}
publicvoid setStart(int start) {
this.start= start;
}
@Override
publicString toString() {
return"Book [_id=" + _id + ", name=" + name + ",author=" + author
+", password=" + password + ", filePath=" + filePath
+", descs=" + descs + ", lastReadTime=" + lastReadTime
+", fileSize=" + fileSize + ", start=" + start +"]";
}
}
===========================================================================================================================================
工具类DatabaseHelper对sqlite进行操作
完善建表操作
package cd.itcast.read.util;
import android.content.Context;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extendsSQLiteOpenHelper {
privatestatic final String DB_NAME = "read.db";
privatestatic final int DB_VERSION = 1;
publicDatabaseHelper(Context context) {
super(context,DB_NAME, null, DB_VERSION);
}
//建表
@Override
publicvoid onCreate(SQLiteDatabase db) {
StringBuilderbuilder = new StringBuilder();
builder.append("createtable book(");
builder.append("_idinteger primary key,");//一定要_id
builder.append("nametext,");
builder.append("authortext,");
builder.append("passwordtext,");
builder.append("descstext,");
builder.append("filePathtext,");
builder.append("fileSizeinteger,");
builder.append("startinteger,");
builder.append("lastReadTimetext");
builder.append(")");
db.execSQL(builder.toString());
}
//当应用程序升级的时间,可能表的信息的就改变:alert table
@Override
publicvoid onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
=========================================================================================================================================
完善bookmanager对图书进行增删查改
package cd.itcast.read.manager;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
importandroid.database.sqlite.SQLiteDatabase;
import cd.itcast.read.domain.Book;
import cd.itcast.read.util.DatabaseHelper;
public class BookManager {
privateDatabaseHelper helper;
publicBookManager(Context context) {
helper= new DatabaseHelper(context);
}
publiclong save(Book book) {
SQLiteDatabasedb = helper.getWritableDatabase();
//返回是null
//write.execSQL(sql)
//返回是long,插入的主键
//定义出来java本地方法,通过java native interface调用c/c++方法通过andriod
//ndk打包成一个.so文件(windows,.dll动态链接库)来实现
//private final native long native_executeInsert();
//write.insert(table, nullColumnHack, values)
ContentValuesvalues = new ContentValues();
bookToContentValues(book,values);
longres = db.insert("book", null, values);
db.close();
returnres;
}
publiclong update(Book book) {
SQLiteDatabasedb = helper.getWritableDatabase();
ContentValuesvalues = new ContentValues();
bookToContentValues(book,values);
longres = db.update("book", values, "_id=?",
newString[] { String.valueOf(book.getId()) });
db.close();
returnres;
}
publicint delete(int id) {
SQLiteDatabasedb = helper.getWritableDatabase();
intres = db.delete("book", "_id=?",
newString[] { String.valueOf(id) });
db.close();
returnres;
}
publicBook get(int id) {
SQLiteDatabasedb = helper.getReadableDatabase();
Bookbook = new Book();
//db.query(table,columns, selection, selectionArgs, groupBy, having, orderBy)
Cursorcursor = db.rawQuery("select * from book where _id=?",
newString[] { String.valueOf(id) });
if(cursor.moveToFirst()) {
cursorToBook(cursor,book);
}
db.close();
returnbook;
}
publicList<Book> getAll() {
List<Book>books = new ArrayList<Book>();
SQLiteDatabasedb = helper.getReadableDatabase();
Cursorcursor = db.rawQuery(
"select* from book order by lastReadTime desc", null);
while(cursor.moveToNext()) {
Bookbook = new Book();
cursorToBook(cursor,book);
books.add(book);
}
db.close();
returnbooks;
}
//从实体类book到ContentValues之间的转换
privatevoid bookToContentValues(Book book, ContentValues values) {
values.put("author",book.getAuthor());
values.put("descs",book.getDescs());
values.put("filePath",book.getFilePath());
values.put("fileSize",book.getFileSize());
values.put("start",book.getStart());
if(book.getLastReadTime() != null) {
//保存的是long类型,因为Cursor里面没有getDate getTime的方法
values.put("lastReadTime",book.getLastReadTime().getTime());
}
values.put("name",book.getName());
values.put("password",book.getPassword());
}
//从ContentValues到实体类book之间的转换
privatevoid cursorToBook(Cursor cursor, Book book) {
book.setId(cursor.getInt(cursor.getColumnIndex("_id")));
book.setName(cursor.getString(cursor.getColumnIndex("name")));
book.setAuthor(cursor.getString(cursor.getColumnIndex("author")));
book.setFilePath(cursor.getString(cursor.getColumnIndex("filePath")));
book.setDescs(cursor.getString(cursor.getColumnIndex("descs")));
book.setPassword(cursor.getString(cursor.getColumnIndex("password")));
book.setFileSize(cursor.getInt(cursor.getColumnIndex("fileSize")));
book.setStart(cursor.getInt(cursor.getColumnIndex("start")));
LongvisitTime = cursor.getLong(cursor.getColumnIndex("lastReadTime"));
if(visitTime != null) {
book.setLastReadTime(newDate(visitTime));
}
}
}
=======================================================================================================================================
BookManagerTest测试类
package cd.itcast.read.manager;
import java.util.Date;
import java.util.List;
import android.test.AndroidTestCase;
import android.util.Log;
import cd.itcast.read.domain.Book;
public class BookManagerTest extendsAndroidTestCase {
privatestatic final String TAG = "read";
privateBookManager bookManager;
//错误的写法,
//public BookManagerTest() {
//bookManager = new BookManager(getContext());
//}
@Override
protectedvoid setUp() throws Exception {
bookManager= new BookManager(getContext());
}
publicvoid testSave() {
Bookbook = new Book();
book.setAuthor("金庸");
book.setDescs("金庸的武侠世界");
book.setFilePath("test.txt");
book.setLastReadTime(newDate());
book.setName("笑傲江湖");
book.setStart(100);
book.setFileSize(1024);
book.setPassword("");
Log.i(TAG,bookManager.save(book) + "");
}
publicvoid testGet() {
Bookbook = bookManager.get(1);
Log.i(TAG,book.toString());
}
publicvoid testUpdate() {
Bookbook = bookManager.get(1);
book.setAuthor("my");
book.setDescs("my的武侠世界");
book.setFilePath("test.txt");
book.setLastReadTime(newDate());
book.setName("my的笑傲江湖");
book.setPassword("xyz");
book.setStart(10);
book.setFileSize(2046);
Log.i(TAG,bookManager.update(book) + "");
}
publicvoid testDelete() {
Log.i(TAG,bookManager.delete(2) + "");
}
publicvoid testGetAll() {
List<Book>books = bookManager.getAll();
for(Book book : books) {
Log.i(TAG,book.toString());
}
}
}
==============================================================================================================================================
MainActivity主界面
package cd.itcast.read.ui;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
importandroid.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.SimpleAdapter;
import cd.itcast.read.domain.Book;
import cd.itcast.read.manager.BookManager;
import cd.itcast.read.util.L;
public class MainActivity extendsListActivity {
privatestatic final SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd");
privateBookManager bookManager;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bookManager= new BookManager(this);
loads();
}
privatevoid loads() {
List<Map<String,String>> data = new ArrayList<Map<String, String>>();
List<Book>books = bookManager.getAll();
L.d("booksSize:"+ books.size());//引用util中的L类
for(Book book : books) {
Map<String,String> map = new HashMap<String, String>();
map.put("name",book.getName());
///
map.put("start",book.getStart() + "");
map.put("time",sdf.format(book.getLastReadTime()));
//最后加入到list
data.add(map);
}
String[]from = new String[] { "name", "start", "time" };
int[]to = new int[] { R.id.name, R.id.start, R.id.time };
SimpleAdapteradapter = new SimpleAdapter(this, data,
R.layout.main_item,from, to);
//<ListView
//android:id="@android:id/list"
//android:layout_width="fill_parent"
//android:layout_height="fill_parent" >
//</ListView>
//把数据放到ListView
getListView().setAdapter(adapter);
}
//创建上下文菜单
@Override
publicvoid onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfomenuInfo) {
//TODO Auto-generated method stub
super.onCreateContextMenu(menu,v, menuInfo);
}
//创建选项菜单
@Override
publicboolean onCreateOptionsMenu(Menu menu) {
MenuInflaterinflater = getMenuInflater();
inflater.inflate(R.menu.main_menu,menu);
returntrue;
}
//处理选项菜单的点击事件
@Override
publicboolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
caseR.id.menuAdd:
Intentintent = new Intent(this, AddBookActivity.class);
startActivity(intent);
returntrue;
default:
returnsuper.onOptionsItemSelected(item);
}
}
}
=====================================================================================================================================
Util中写L类用于打印
package cd.itcast.read.util;
import android.util.Log;
public class L {
privatestatic final String TAG = "read";
publicstatic void d(String msg) {
Log.d(TAG,msg);
}
publicstatic void i(String msg) {
Log.i(TAG,msg);
}
publicstatic void w(String msg) {
Log.w(TAG,msg);
}
publicstatic void e(String msg) {
Log.e(TAG,msg);
}
}
=====================================================================================================================================
Main.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/title_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/title_start" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/title_time" />
</LinearLayout>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
=====================================================================================================================================
Main_item.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
=================================================================================================================================================
Strings.xml
<?xml version="1.0"encoding="utf-8"?>
<resources>
<string name="hello">Hello World,MainActivity!</string>
<string name="app_name">Read</string>
<string name="title_name">书名</string>
<string name="title_author">作者</string>
<string name="title_password">密码</string>
<string name="title_filePath">文件路径</string>
<string name="title_descs">简介</string>
<string name="title_start">进度</string>
<string name="title_time">上次阅读时间</string>
<string name="btn_save">保存</string>
<string name="btn_go">跳转</string>
<string name="btn_cancel">取消</string>
<string name="btn_selectFile">选择图书</string>
<string name="menu_add">添加图书</string>
</resources>
=====================================================================================================================================================
手机端menu呈现出菜单
在read\res\menu下创建main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menuxmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menuAdd"
android:icon="@drawable/add"
android:title="@string/menu_add"/>
</menu>
====================================================================================================================================================
从其他mybook.apk反编译
http://code.google.com/p/android-apktool/
运行方式:
D:\read\android-apktool>apktool d"abc.apk" "temp"
反编译到temp目录
Res中新建drawable,将反编译的相同目录res/drawable/add.png拷贝到本项目
======================================================================================================================
创建点击添加图书菜单类AddBookActivity,注意新建一个activity是需要在Android Manifest.xml注册的
package cd.itcast.read.ui;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class AddBookActivity extendsActivity implements OnClickListener {
privatestatic final int SELECT_BOOK = 1;
privateEditText name, author, password, filePath, descs;
privateButton save, cancel, selectFile;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_book);
init();
}
privatevoid init() {
name= (EditText) findViewById(R.id.name);
author= (EditText) findViewById(R.id.author);
password= (EditText) findViewById(R.id.password);
filePath= (EditText) findViewById(R.id.filePath);
descs= (EditText) findViewById(R.id.descs);
save= (Button) findViewById(R.id.btnSave);
cancel= (Button) findViewById(R.id.btnCancel);
selectFile= (Button) findViewById(R.id.btnSelectFile);
save.setOnClickListener(this);
cancel.setOnClickListener(this);
selectFile.setOnClickListener(this);
}
@Override
publicvoid onClick(View v) {
switch(v.getId()) {
caseR.id.btnSave:
break;
caseR.id.btnCancel:
finish();
break;
caseR.id.btnSelectFile:
Intentintent = new Intent(this, SelectBookActivity.class);
startActivityForResult(intent,SELECT_BOOK);
break;
default:
break;
}
}
@Override
protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) {
//请求是从当前的Activity到SelectBookActivity,SelectBookActivity处理之后返回了RESULT_OK给当前的Activity,并且从Intent data回传一个filePath的路径
if(requestCode == SELECT_BOOK && resultCode == RESULT_OK) {
Stringpath = data.getStringExtra("filePath");
filePath.setText(path);
}
}
}
==================================================================================================================
AndroidManifest.xml中对activity文件注册
<?xml version="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="cd.itcast.read.ui"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activityandroid:name=".AddBookActivity"/>
<activityandroid:name=".SelectBookActivity"/>
<uses-library android:name="android.test.runner"/>
</application>
<!--注意修改包名 -->
<instrumentationandroid:name="android.test.InstrumentationTestRunner"
android:targetPackage="cd.itcast.read.ui"android:label="MyTest" />
</manifest>
=======================================================================================================================
add_book.xml 添加图书表单
<?xml version="1.0"encoding="utf-8"?>
<TableLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_name" />
<EditText
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_author" />
<EditText
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_password" />
<EditText
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_filePath" />
<EditText
android:id="@+id/filePath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/btnSelectFile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_selectFile" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_descs" />
<EditText
android:id="@+id/descs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" >
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_save" />
<Button
android:id="@+id/btnCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_cancel" />
</TableRow>
</TableLayout>