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下有没有我们的数据库文件

如果不存在的话,我们需要通过代码将数据库文件导入到指定目录下!


①先定义我们的数据库名称以及包名常量:

[java]view plaincopyprint?
  1. public static String dbName="my.db";//数据库的名字
  2. private static String DATABASE_PATH="/data/data/com.jay.example.festivalsmshelper/databases/";

②接着定义判断是数据库文件是否存在的方法:

[java]view plaincopyprint?
  1. public boolean checkDataBase(){
  2. SQLiteDatabase checkDB = null;
  3. try{
  4. String databaseFilename = DATABASE_PATH+dbName;
  5. checkDB =SQLiteDatabase.openDatabase(databaseFilename, null,
  6. SQLiteDatabase.OPEN_READONLY);
  7. }catch(SQLiteException e){
  8. }
  9. if(checkDB!=null){
  10. checkDB.close();
  11. }
  12. return checkDB !=null?true:false;
  13. }

③假如数据库文件不存在的话我们需要将数据库文件复制到指定目录下:

[java]view plaincopyprint?
  1. public void copyDataBase() throws IOException{
  2. String databaseFilenames =DATABASE_PATH+dbName;
  3. File dir = new File(DATABASE_PATH);
  4. if(!dir.exists())//判断文件夹是否存在,不存在就新建一个
  5. dir.mkdir();
  6. FileOutputStream os = null;
  7. try{
  8. os = new FileOutputStream(databaseFilenames);//得到数据库文件的写入流
  9. }catch(FileNotFoundException e){
  10. e.printStackTrace();
  11. }
  12. InputStream is = MainActivity.this.getAssets().open("my.db");
  13. byte[] buffer = new byte[4096];
  14. int count = 0;
  15. try{
  16. while((count=is.read(buffer))>0){
  17. os.write(buffer, 0, count);
  18. os.flush();
  19. }
  20. }catch(IOException e){e.printStackTrace();}
  21. is.close();
  22. os.close();
  23. }

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

[java]view plaincopyprint?
  1. boolean dbExist = checkDataBase();
  2. if(dbExist){}
  3. else{//不存在就把assert里的数据库写入手机
  4. try{
  5. copyDataBase();
  6. }catch(IOException e){throw new Error("复制数据库出错");}
  7. }

⑤打开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集合中:

代码如下:

[java]view plaincopyprint?
  1. public static List<Person> getPerson(Context context)
  2. {
  3. List<Person> persons = new ArrayList<Person>();
  4. ContentResolver cr = context.getContentResolver();
  5. Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
  6. while(cursor.moveToNext()){
  7. Person person = new Person();
  8. //获取联系人id
  9. String contatId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
  10. person.setId(Integer.parseInt(contatId));
  11. //获取联系人姓名
  12. String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
  13. person.setName(name);
  14. //因为一个联系人的电话号码可能有几个,但我们这里仅仅是获取一个就够了,所以就不循环遍历了
  15. Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  16. null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contatId, null, null);
  17. phones.moveToFirst();
  18. String num = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
  19. person.setNumber(num);
  20. person.setState(-1);
  21. persons.add(person);
  22. phones.close();
  23. }
  24. cursor.close();
  25. return persons;
  26. }

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

该方法的参数是一个Person的对象,我们使用ContentValues来存储从person取出的不同数据!

再调用db.insert("contacts",null,contentValue)将记录插入到contacts表中

代码:

[java]view plaincopyprint?
  1. public void insert(Person person){
  2. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  3. ContentValues values = new ContentValues();
  4. values.put("_id", person.getId());
  5. values.put("pname", person.getName());
  6. values.put("pnumber", person.getNumber());
  7. values.put("pstate", person.getState());
  8. db.insert("contacts", null, values);
  9. }

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

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

再new一个线程,一秒钟后让进度条消失,第一个界面消失,通过intent跳转

到第二个界面中!

代码:

[java]view plaincopyprint?
  1. //加个进度条,数据太多可能卡住不好,用户看着不爽
  2. final ProgressDialog dialog = ProgressDialog.show(this, "提示", "读取联系人中", false, true);
  3. GetContactsService getContacts = new GetContactsService(getApplicationContext());
  4. List<Person> persons = GetPerson.getPerson(MainActivity.this);
  5. Cursor cursor = getContacts.query("select count(*) from contacts", null);
  6. cursor.moveToFirst();
  7. //判断联系人数目是否发生变更,没变更的话就不用调用下面的for循环了
  8. if(persons.size() != cursor.getInt(0))
  9. {
  10. for(Person p : persons)
  11. {
  12. System.out.println(p.toString());
  13. getContacts.insert(p);
  14. }
  15. }
  16. //设置让圆形进度条过一秒后消失,以及第一个界面消失,跳转到第二个界面
  17. new Thread()
  18. {
  19. public void run()
  20. {
  21. try {
  22. sleep(1000);
  23. } catch (InterruptedException e) {e.printStackTrace();}
  24. dialog.dismiss();
  25. Intent it = new Intent(getApplicationContext(), ChooseActivity.class);
  26. startActivity(it);
  27. finish();
  28. };
  29. }.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();

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

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

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

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

    Android基础整合项目(一) 之节日群发助手part 2 --转载请注明出处:coder-pig 本节引言: 在上一节中我们已经做出了我们群发助手的第一个界面以及完成了联系人的读取以及数据库的 录 ...

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

    Android基础--项目的文件结构(三) 代码源文件夹与资源文件夹 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目中,代码源文件夹有4个 ...

  3. Android Studio实现学生信息管理系统,基础入门项目

    文章目录 一.需求分析 二.开发环境 三.详细设计 3.1 项目结构 3.2 数据库 3.3 登录和注册 3.4 增删改查 四.项目演示 五.项目源码 一.需求分析 该学生信息管理系统具有添加学生信息 ...

  4. Android基础知识【项目实训-实现二级导航“今日活动”及读取数据库】【5】

    [该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材] [项目题目]:校园订餐App设计 ...

  5. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第三章:简单控件

    第 3 章 简单控件 本章介绍了App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图.容纳视图的常用布局.响应点击的按钮控件.显示图片的图像视图等.然后结合本章所学的知识,演示了一个实战项 ...

  6. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第六章:数据存储

    第 6 章 数据存储 本章介绍Android 4种存储方式的用法,包括共享参数SharedPreferences.数据库SQLite.存储卡文 件.App的全局内存,另外介绍Android重要组件-应 ...

  7. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第五章:中级控件

    第 5 章 中级控件 本章介绍App开发常见的几类中级控件的用法,主要包括:如何定制几种简单的图形.如何使用几种选择按钮.如何高效地输入文本.如何利用对话框获取交互信息等,然后结合本章所学的知识,演示 ...

  8. Android基础——项目的文件结构(二)

    Android基础--项目的文件结构(二) AndroidManifest.xml文件分析 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目 ...

  9. 重学Android基础系列篇(五):Android虚拟机指令

    前言 本系列文章主要是汇总了一下大佬们的技术文章,属于Android基础部分,作为一名合格的安卓开发工程师,咱们肯定要熟练掌握java和android,本期就来说说这些~ [非商业用途,如有侵权,请告 ...

  10. 手把手教你扩展个人微信号(2)(微信控制器、群发助手、好友删除检测)...

    现在的日常生活已经离不开微信,本文将会抛砖引玉演示如何使用Python调用微信API做一些有意思的东西. 看完这一系列教程,你就能从头开始实现自己关于微信的想法. 本文为教程的第二部分,主要以微信控制 ...

最新文章

  1. 如何在.NET上处理二维码
  2. in会让mysql索引失效吗_mysql的in会不会让索引失效?
  3. 如何在 Linux 上重命名一组文件
  4. linux关于子网掩码函数,Linux 子网掩码计算, 二进制十进制互相转换
  5. 【Python数据分析】数据挖掘建模——分类与预测——回归分析
  6. Atiitt cdn技术总结 性能提升之道 目录 1. 组成 最简单的CDN网络由一个DNS服务器和几台缓存服务器组成: 1 1.1. CDN是一个经策略性部署的整体系统,包括分布式存储、负载均衡
  7. 【采用】社交网络分析与金融反欺诈应用(知识图谱?)
  8. GridinSoft CHM编辑器3.2.0多语言,轻松快速地翻译CHM电子书
  9. 电脑计算机程序员考证
  10. 2020 CCF BDCI小学数学应用题自动解题解题思路
  11. 一、barrier指令DSB,DMB,ISB,fence——内存屏障,指令屏障
  12. java美团购物车,仿美团详情页与购物车源码-订单页
  13. 王争-算法与数据结构专栏第一期福利笔记(数据结构与算法学习书单)
  14. 如何让IE窗口打开时就自动默认为最大化
  15. mpu6050六轴传感器msp430驱动程序
  16. 手写springboot自动装配 autoConfiguration
  17. 笔记:二元Probit与Logit模型
  18. 全光谱防蓝光护眼灯有用吗?怎么分辨是全光谱灯
  19. Apache配置域名-绑定到指定项目目录
  20. FIR 高级应用 FIR Reload 的使用

热门文章

  1. 此计算机无法连接道家庭组,无法加入家庭组怎么办
  2. 腾飞计算机学校怎么样,合肥腾飞职业技术学校怎么样
  3. Edison重新上手
  4. ed是什么梗_美国大学EA,ED什么意思?
  5. c语言里的u代表什么_c语言中的 %u 什么意思啊?
  6. 如何更改windows桌面图标,更改桌面图标方法
  7. 昨天晚上看了冰川时代三
  8. php变异测试工具,科学网—两种突变检测的matlab代码 - 张凌的博文
  9. ITA和意大利荣耀与共,助力蓝衣军团欧洲杯决赛战胜英格兰!
  10. 专访:InMobi全球CEO Naveen Tewari