Android基础整合项目(一) 之节日群发助手part 1
——转载请注明出处:coder-pig
本节引言:
Android入门系列已经写了大半了,学习了这么多理论知识,不练下手怎么行呢?
在实际的开发中我们会遇到更多的问题,同时也能加固我们的基础知识!鉴于
笔者的水平有限,该项目,面对的是初学者,各位大牛路过不喜勿喷!好吧说下第一个
练手项目吧,前几天中秋节今天又是教师节,各种祝福短信满天飞,手打再群发,条条
短信一个样,没意思!直接用别人弄好的短信群发,别人又不知道你是谁,起码加个:
亲爱的XXX.我是隔壁老王,.....别人起码知道你是谁把!好了,废话不多说,开始app
的开发吧!
ps:目前app的基本功能已经实现,效果图如下,如果有需要可以进行下载
到后面会逐步完善相关功能:
效果图:
参考代码下载:
正文:
创建数据库文件:有两个表,分别为存储联系人的表contacts和存储节日祝福语的表festival
可以直接使用SQLite Expert或者其他SQLite的可视化工具创建表,可以代码创建或者手动创建
代码创建的话执行以下语句生成数据库表:
"CREATE TABLE festival(sentence_id INTEGER PRIMARY KEY AUTOINCREMENT,detail)"
"CREATE TABLE contacts(_id INTEGER PRIMARY KEY,pname,pnumber,pstate)"
接着对节日表进行数据的录入,结束的表结构如下:
festival表:
contacts表:
在完成上述创建数据库的步骤后,接着我们需要把数据库文件复制到assert目录下
这里我们要做什么呢?
在应用启动的时候我们需要判断data/data/<包名>/database下有没有我们的数据库文件
如果不存在的话,我们需要通过代码将数据库文件导入到指定目录下!
①先定义我们的数据库名称以及包名常量:
public static String dbName="my.db";//数据库的名字 private static String DATABASE_PATH="/data/data/com.jay.example.festivalsmshelper/databases/";
②接着定义判断是数据库文件是否存在的方法:
public boolean checkDataBase(){ SQLiteDatabase checkDB = null; try{ String databaseFilename = DATABASE_PATH+dbName; checkDB =SQLiteDatabase.openDatabase(databaseFilename, null, SQLiteDatabase.OPEN_READONLY); }catch(SQLiteException e){ } if(checkDB!=null){ checkDB.close(); } return checkDB !=null?true:false; }
public void copyDataBase() throws IOException{ String databaseFilenames =DATABASE_PATH+dbName; File dir = new File(DATABASE_PATH); if(!dir.exists())//判断文件夹是否存在,不存在就新建一个 dir.mkdir(); FileOutputStream os = null; try{ os = new FileOutputStream(databaseFilenames);//得到数据库文件的写入流 }catch(FileNotFoundException e){ e.printStackTrace(); } InputStream is = MainActivity.this.getAssets().open("my.db"); byte[] buffer = new byte[4096]; int count = 0; try{ while((count=is.read(buffer))>0){ os.write(buffer, 0, count); os.flush(); } }catch(IOException e){e.printStackTrace();} is.close(); os.close(); }
boolean dbExist = checkDataBase(); if(dbExist){} else{//不存在就把assert里的数据库写入手机 try{ copyDataBase(); }catch(IOException e){throw new Error("复制数据库出错");} }
如图就说明数据库文件复制完毕,是仅仅有一个my.db文件而已!后面那个my.do-journal是因为执行了
其他的操作生成的!
这里的话我们读取的仅仅是联系人的目录,并不包括sim卡中的联系人哦!
这块就涉及到了我们前面所学的使用系统提供的ContentProvider了!
我们先把系统提供的联系人的数据库文件找出来瞅瞅吧!
打开文件浏览器:data/data/com.android.providers.contacts/databases
下面的contacts2.db文件就是存储系统联系人的数据库文件了:
导出以后查看几个重要的基本表,以及相关字段:
contacts表
data表
phone_look_up表
raw_contact表
以上四个就是我们要留意的四个表了
好了,说下我们要获取的数据:联系人id,姓名,一个电话号码
于是我们定义一个类GetPhone类并定义一个读取联系人的方法,将读到数据存储到list集合中:
代码如下:
public static List<Person> getPerson(Context context) { List<Person> persons = new ArrayList<Person>(); ContentResolver cr = context.getContentResolver(); Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null); while(cursor.moveToNext()){ Person person = new Person(); //获取联系人id String contatId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); person.setId(Integer.parseInt(contatId)); //获取联系人姓名 String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); person.setName(name); //因为一个联系人的电话号码可能有几个,但我们这里仅仅是获取一个就够了,所以就不循环遍历了 Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contatId, null, null); phones.moveToFirst(); String num = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); person.setNumber(num); person.setState(-1); persons.add(person); phones.close(); } cursor.close(); return persons; }
该方法的参数是一个Person的对象,我们使用ContentValues来存储从person取出的不同数据!
再调用db.insert("contacts",null,contentValue)将记录插入到contacts表中
代码:
public void insert(Person person){ SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("_id", person.getId()); values.put("pname", person.getName()); values.put("pnumber", person.getNumber()); values.put("pstate", person.getState()); db.insert("contacts", null, values); }
怕数据太多,出现卡住的情况,加个进度条,用户看着没那么不爽!
再new一个线程,一秒钟后让进度条消失,第一个界面消失,通过intent跳转
到第二个界面中!
代码:
//加个进度条,数据太多可能卡住不好,用户看着不爽 final ProgressDialog dialog = ProgressDialog.show(this, "提示", "读取联系人中", false, true); GetContactsService getContacts = new GetContactsService(getApplicationContext()); List<Person> persons = GetPerson.getPerson(MainActivity.this); Cursor cursor = getContacts.query("select count(*) from contacts", null); cursor.moveToFirst(); //判断联系人数目是否发生变更,没变更的话就不用调用下面的for循环了 if(persons.size() != cursor.getInt(0)) { for(Person p : persons) { System.out.println(p.toString()); getContacts.insert(p); } } //设置让圆形进度条过一秒后消失,以及第一个界面消失,跳转到第二个界面 new Thread() { public void run() { try { sleep(1000); } catch (InterruptedException e) {e.printStackTrace();} dialog.dismiss(); Intent it = new Intent(getApplicationContext(), ChooseActivity.class); startActivity(it); finish(); }; }.start();
将my.db文件导出后可以看到contacts表的data已经有数据了,就完成了
另外记得还有个Person类别漏了,定义四个属性:id,name,number,state(记录是否已经发送)
这里就不给出了,另外要创建出第二个Activity完成Intent的跳转哦!不然可是会报错的!
1.判断app中的数据库文件是否存在?不存在的话如何使用输入流将文件写入到相应目录下
2.如何获得assert里的文件,从而获得输入流对象;
3.哪里可以找到系统保存联系人的数据库;相关表以及字段的了解!
读取表中我们需要的联系人信息!
4.调用database的insert()方法插入ContentValues类型的数据
5.获得数据库表有多少条记录的方法:
Cursor cursor = getContacts.query("select count(*) from contacts", null);
cursor.moveToFirst();
cursor.getInt(0);
6.获取List集合中的数据元素:list.size();
好了这一节就暂且到这里吧,如果对本文有什么建议,批评的,欢迎指出!
不慎感激!项目的代码会随着后面深入慢慢完善的!
原文地址:http://blog.csdn.net/coder_pig/article/details/39182657