Android基础整合项目之节日群发助手(一)

Android基础整合项目(一) 之节日群发助手part 1

——转载请注明出处:coder-pig

本节引言:

Android入门系列已经写了大半了,学习了这么多理论知识,不练下手怎么行呢?

在实际的开发中我们会遇到更多的问题,同时也能加固我们的基础知识!鉴于

笔者的水平有限,该项目,面对的是初学者,各位大牛路过不喜勿喷!好吧说下第一个

练手项目吧,前几天中秋节今天又是教师节,各种祝福短信满天飞,手打再群发,条条

短信一个样,没意思!直接用别人弄好的短信群发,别人又不知道你是谁,起码加个:

亲爱的XXX.我是隔壁老王,.....别人起码知道你是谁把!好了,废话不多说,开始app

的开发吧!

ps:目前app的基本功能已经实现,效果图如下,如果有需要可以进行下载

到后面会逐步完善相关功能:

效果图:

参考代码下载:

源码下载

正文:

本节要点图:

开发流程详解:

1)创建数据库

创建数据库文件:有两个表,分别为存储联系人的表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表:

2)应用启动时判断数据库文件是否存在

在完成上述创建数据库的步骤后,接着我们需要把数据库文件复制到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();
    }

④在MainActivity的onCreate()方法中加入下面的代码,用于调用上述两个方法:

	boolean dbExist = checkDataBase();
	if(dbExist){}
	else{//不存在就把assert里的数据库写入手机
	try{
	    copyDataBase();
		}catch(IOException e){throw new Error("复制数据库出错");}
	}

⑤打开File Exploer查看数据库文件是否复制完毕:

如图就说明数据库文件复制完毕,是仅仅有一个my.db文件而已!后面那个my.do-journal是因为执行了

其他的操作生成的!

3)读取系统的联系人目录:

这里的话我们读取的仅仅是联系人的目录,并不包括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;
	}

4)定义一个插入数据的方法:

该方法的参数是一个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);
	}

5)在MainActivity中调用获取联系人的方法,插入数据

怕数据太多,出现卡住的情况,加个进度条,用户看着没那么不爽!

再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();

6)运行后的效果查看:

将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();

好了这一节就暂且到这里吧,如果对本文有什么建议,批评的,欢迎指出!

不慎感激!项目的代码会随着后面深入慢慢完善的!

时间: 2024-08-07 12:38:40

Android基础整合项目之节日群发助手(一)的相关文章

Android基础整合项目之节日群发助手(二)

Android基础整合项目(一) 之节日群发助手part 2 --转载请注明出处:coder-pig 本节引言: 在上一节中我们已经做出了我们群发助手的第一个界面以及完成了联系人的读取以及数据库的 录入了,在这一节中将要完成的工作是: 1)自定义我们的ListView的列表项,两个TextView + CheckBox; 2)使用SimpleCursorAdapter将数据显示到ListView上; 3)实现listview的全选与全不选 4)点击重置按钮后,将数据库中的state都重置为-1

Android基础整合项目之节日群发助手(三)

Android基础整合项目(一) 之节日群发助手part 3 --转载请注明出处:coder-pig 本节引言: 在前面两个章节中我们已经完成了群发助手的读联系人,存取数据库;使用 SimpleCursorAdapter绑定数据库与ListView;实现listview的全选与全不选; 也把需要拨打电话号码的id以list集合的形式通过Intent传送到了第三个界面 今天我们就来完成第三个界面的开发,工作如下: 1)完成第三个Activity的布局 2)解析第二个Activity通过Intent

Android基础之项目结构分析

创建了第一个Android项目,用工具开发Android项目,我们有必要熟悉项目的目录结构,清楚各个项目下面放置的是什么东西.展开整个项目,其根目录结构(选用不同版本的SDK文件目录结构会有一些不同,但大致一样)如下图所示: 1. src目录 该目录一个普通的保存java源文件的目录,其和普通java工程中的src目录是一样的. 2. gen目录 此目录用于存放所有由ADT插件自动生成的内容.里面最重要的是名称为R.java的文件,这个java文件含有很多静态类,并对应于下面要介绍的res目录下

Android基础知识【项目实训】【1】

[该项目实训是Android基础知识的一个综合练习] [项目题目]:校园订餐App设计 综合案例 [设计目标] 1.必要功能 ?快餐店浏览,与订餐 ?今天订餐活动查询与订餐,特价饭菜预定 ?分类订餐查询,预定 ?常定饭菜  预定 ?健康餐推荐 ?定时预定,提前预定 ?订单查看, ?餐馆与饭菜打分,评价 ?用户注册与登录 2.扩展选择功能 ?快速拨打电话 ?饮食跟踪,热量估算 ?系统设置 [项目说明] 该项目为实际应用项目的单机 简化版本,只需要完成Android平台App的设计与开发工作. Ap

Android基础知识【项目实训】【2】

[该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材] [项目题目]:校园订餐App设计 综合案例 [目标] 因为项目只涉及基础知识,因此项目中所用数据并不联网,都读取单机数据库.(即将该项目中所用数据,如菜品信息.店铺信息等存入数据库)用户在第一次打开该项目时,会在用户手机上创建这些数据库,并插入测试数据. 1.先制作一个欢迎界面,欢迎的同时,准备数据库 欢迎界面Activity对应

Android基础知识【项目实训】【3】

[该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材] [项目题目]:校园订餐App设计 综合案例 [目标] 欢迎界面过后,应该显示app的主界面了,根据[UI设计指导]中的规划,主界面采用上下两级标签导航.这部分是app开发中比较麻烦的一块. 1.先来看一下,最终的效果吧,这样做起来比较有底: 默认显示的主界面,下部是主导航,上面是二级导航,默认打开的是"促销打折"这一版面

Android基础知识【项目实训】【4】

[该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材] [项目题目]:校园订餐App设计 综合案例 [目标] 主界面的功能确实比较复杂,因此上一篇知识说的周边内容.现在开始说这个界面的代码和布局文件. 1.先看一下项目的组织结构吧,要不然不好说他们的关系: (1)db包中的都是跟 数据库相关的 (2)eatall中放的都是activity或者fragment (3)entity中放的实

Android基础知识【项目实训】【5】

[该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材] [项目题目]:校园订餐App设计 综合案例 [目标] 主界面中包含两个二级子界面,分别是活动界面和账单界面,下面介绍它们的实现代码和布局文件. 1.下面这个是 活动界面的Activity代码,因为这个界面加载时需要 读取数据库中数据了,所有功能的实现上会涉及到 db那个包中一些类. 注意这个Activity也是继承 Activit

Android基础——项目的文件结构(三)

Android基础--项目的文件结构(三) 代码源文件夹与资源文件夹 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目中,代码源文件夹有4个,分别是java.jni.aidl.rs,资源文件夹有3个,分别是assets.res.resources.(这里的文件夹名称是在project视图下的名称,如有疑问可参考Android基础--项目的文件结构(一)Android视图与Project视图对比) 文件夹路径及概要说明如下表所示: Pro