2 从列表选择在添加黑名单界面中, 点击 从联系人中添加 按钮时, 会跳转到联系人列表界面, 点击其中的任意一个联系人, 此时该联系人的电话号码和姓名会显示在添加黑名单界面的编辑框中, 点击下方的 添加 按钮, 此时会将该号码添加到黑名单中, 并在主界面中展示, 如图 3-2 所示 图 3-2 从联

Size: px
Start display at page:

Download "2 从列表选择在添加黑名单界面中, 点击 从联系人中添加 按钮时, 会跳转到联系人列表界面, 点击其中的任意一个联系人, 此时该联系人的电话号码和姓名会显示在添加黑名单界面的编辑框中, 点击下方的 添加 按钮, 此时会将该号码添加到黑名单中, 并在主界面中展示, 如图 3-2 所示 图 3-2 从联"

Transcription

1 第 3 章通讯卫士模块 了解通讯卫士模块功能 掌握 SQLite 数据库的使用 掌握如何使用广播接收者拦截电话和短信在日常生活中, 使用手机时经常会被某些电话或短信骚扰, 例如推销保险 中奖信息等, 为此, 我们开发了通讯卫士模块, 该模块可以将骚扰电话或垃圾短信添加到黑名单中, 并对其进行拦截 本章将针对通讯卫士模块进行详细讲解 3.1 模块概述 功能介绍 通讯卫士模块的主要功能是进行黑名单拦截, 根据设置对添加到黑名单中的号码进行电话拦截或短信拦截 在添加黑名单时有两种方式, 一种是直接在编辑框中输入电话号码以及联系人姓名, 另一种是直接从联系人列表中选择, 接下来分别针对这两种方式进行讲解 1 手动添加当没有添加黑名单时, 会展示通讯卫士主界面, 此时点击 添加黑名单 按钮, 会进入添加黑名单界面, 该界面中可以直接输入联系人号码和姓名, 选中电话拦截 短信拦截的 CheckBox 按钮, 然后点击 添加 按钮, 此时会将该号码添加到黑名单数据库中, 并将黑名单信息展示到通信卫士主界面中, 如图 3-1 所示 图 3-1 手动输入黑名单信息 1

2 2 从列表选择在添加黑名单界面中, 点击 从联系人中添加 按钮时, 会跳转到联系人列表界面, 点击其中的任意一个联系人, 此时该联系人的电话号码和姓名会显示在添加黑名单界面的编辑框中, 点击下方的 添加 按钮, 此时会将该号码添加到黑名单中, 并在主界面中展示, 如图 3-2 所示 图 3-2 从联系人列表添加黑名单 开发流程图 通讯卫士模块的开发流程有些复杂, 为了让大家更好的理解该模块的逻辑, 接下来绘制一个流程图, 具体如图 3-3 所示 点击通讯卫士 有 判断有无黑名单 无 展示黑名单 添加黑名单 输入联系人选择联系人 选择 输入 联系人列表 电话拦截短信拦截 添加 添加黑名单 图 3-3 通讯卫士模块流程图 2

3 从图 3-3 可以看出, 当进入通讯卫士界面时, 首先会判断是否有黑名单, 如果有则在主界面中显示黑 名单列表, 否则显示 您还没有添加黑名单 在添加黑名单时有两种方式, 一种是直接添加, 一种是从 联系人列表中选择, 然后指定电话拦截或者短信拦截后添加黑名单, 此时黑名单信息就会展示在主界面中 代码结构 通讯卫士模块代码量较多, 主要逻辑包括两套主界面布局的动态切换 选择联系人 黑名单数据库的 增删查 ListView 的分页查询等, 接下来通过一个图例来展示通讯卫士模块的代码结构, 如图 3-4 所示 图 3-4 chapter03 代码结构下面按照结构顺序依次介绍 chapter03 包中的文件, 具体如下 : BlackContactAdapter.java: 用于填充黑名单的数据适配器 ; ContactAdapter.java: 用于填充手机联系人信息的数据适配器 ; BlackNumberDao.java: 用于对黑名单中的数据进行增 删 查等操作 ; BlackNumberOpenHelper.java: 用于创建黑名单数据库, 继承自 SQLiteOpenHelper; BlackContactInfo.java: 用于储存黑名单信息的实体类, 包括 phonenumber contactname 字段以及拦截模式 ; ContactInfo.java: 联系人信息的实体类, 包括 id name phone 字段 ; InterceptCallReceiver.java: 拦截电话的广播接收者 ; InterceptSmsReceiver.java: 拦截短信的广播接收者 ; TestBlackNumberDao.java: 操作黑名单数据的测试类 ; 3

4 ContactInfoParser.java: 联系人信息的解析器, 用于从系统通讯录中读取联系人信息 ; AddBlackNumberActivity.java: 添加黑名单界面 ; ContactSelectActivity.java: 显示系统联系人界面 ; SecurityPhoneActivity.java: 显示黑名单信息界面 ; 需要注意的是, 通讯卫士模块中的电话拦截功能涉及到了进程间通信, 因此在第 3 章中引入了两个 AIDL 文件 ITelephony.aidl 和 NeighboringCellInfo.aidl, 这两个文件分别位于 android.telephony 包和 com.android.internal.telephony 包中, 在开发电话拦截时, 需要创建这两个包将 AIDL 文件复制到工程中 3.2 黑名单数据库 黑名单中的信息需要长期保存, 为此可以使用 Android 自带的数据库 SQLite 存储黑名单信息, 本节将 针对数据库的创建以及基本操作进行详细讲解 创建数据库 要想实现黑名单拦截功能, 首先需要根据需求设计一个黑名单数据库 (blacknumber.db), 该数据库主要用于存储黑名单中的联系人信息, 创建数据库代码如 文件 3-1 所示 文件 3-1 BlackNumberOpenHelper.java 1 public class BlackNumberOpenHelper extends SQLiteOpenHelper{ 2 public BlackNumberOpenHelper(Context context) { 3 super(context, "blacknumber.db", null, 1); 4 } 6 public void oncreate(sqlitedatabase db) { 7 db.execsql("create table blacknumber (id integer primary key autoincrement 8, number varchar(20), name varchar(255),mode integer)"); 9 } 11 public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { 12 } 13 } 在上述代码中, 创建了一个黑名单数据库 blacknumber.db, 并在数据库中创建 blacknumber 表, 该表包含三个字段分别为 id number name, 其中 id 为自增主键,number 为电话号码,name 为联系人姓名 联系人的实体类 在实现黑名单拦截时, 需要保存黑名单中联系人信息, 因此需要定义一个黑名单联系人的实体类, 该类中包含三个属性, 电话号码 联系人姓名 拦截模式, 具体代码如 文件 3-2 所示 文件 3-2 BlackContackInfo.xml 1 public class BlackContactInfo { 2 /** 黑名单号码 */ 3 public String phonenumber; 4

5 4 /** 黑名单联系人名称 */ 5 public String contactname; 6 /** 黑名单拦截模式 </br> 1 为电话拦截 2 为短信拦截 3 为电话 短信都拦截 */ 7 public int mode; 8 public String getmodestring(int mode){ 9 switch (mode) { 10 case 1: 11 return " 电话拦截 "; 12 case 2: 13 return " 短信拦截 "; 14 case 3: 15 return " 电话 短信拦截 "; 16 } 17 return ""; 18 } 19 } 在上述代码的 getmodestring(int mode) 方法中, 定义了 3 种拦截模式的返回值 由于黑名单拦截模式 有 3 种, 分别为电话拦截 短信拦截以及电话短信全部拦截, 因此在 getmodestring(int mode) 方法中以数 字 分别进行区分, 根据传递的数字不同返回不同的拦截模式 数据库操作类 由于我们经常添加和删除黑名单中的联系人, 因此需要创建一个操作黑名单数据库的工具类, 对黑名单中的数据进行增 删 查等操作, 具体代码如 文件 3-3 所示 文件 3-3 BlackNumberDao.java 1 public class BlackNumberDao { 2 private BlackNumberOpenHelper blacknumberopenhelper; 3 public BlackNumberDao(Context context) { 4 super(); 5 blacknumberopenhelper = new BlackNumberOpenHelper(context); 6 } 7 /*** 8 * 添加数据 9 blackcontactinfo */ 12 public boolean add(blackcontactinfo blackcontactinfo) { 13 SQLiteDatabase db = blacknumberopenhelper.getwritabledatabase(); 14 ContentValues values = new ContentValues(); 15 if (blackcontactinfo.phonenumber.startswith("+86")) { 16 blackcontactinfo.phonenumber = blackcontactinfo.phonenumber 17.substring(3, blackcontactinfo.phonenumber.length()); 18 } 5

6 19 values.put("number", blackcontactinfo.phonenumber); 20 values.put("name", blackcontactinfo.contactname); 21 values.put("mode", blackcontactinfo.mode); 22 long rowid = db.insert("blacknumber", null, values); 23 if (rowid == -1){ // 插入数据不成功 24 return false; 25 }else{ 26 return true; 27 } 28 } 29 /** 30 * 删除数据 31 blackcontactinfo */ 34 public boolean delete(blackcontactinfo blackcontactinfo) { 35 SQLiteDatabase db = blacknumberopenhelper.getwritabledatabase(); 36 int rownumber = db.delete("blacknumber", "number=?", 37 new String[] { blackcontactinfo.phonenumber }); 38 if (rownumber == 0){ 39 return false; // 删除数据不成功 40 }else{ 41 return true; 42 } 43 } 44 /** 45 * 分页查询数据库的记录 46 pagenumber 第几页, 页码从第 0 页开始 47 pagesize 每一个页面的大小 48 */ 49 public List<BlackContactInfo> getpageblacknumber(int pagenumber,int pagesize){ 50 // 得到可读的数据库 51 SQLiteDatabase db = blacknumberopenhelper.getreadabledatabase(); 52 Cursor cursor = db.rawquery("select number,mode,name from blacknumber 53 limit? offset?", new String[] { String.valueOf(pagesize), 54 String.valueOf(pagesize * pagenumber) }); 55 List<BlackContactInfo> mblackcontactinfos = new ArrayList<BlackContactInfo>(); 56 while (cursor.movetonext()) { 57 BlackContactInfo info = new BlackContactInfo(); 58 info.phonenumber = cursor.getstring(0); 59 info.mode = cursor.getint(1); 60 info.contactname = cursor.getstring(2); 61 mblackcontactinfos.add(info); 62 } 6

7 63 cursor.close(); 64 db.close(); 65 SystemClock.sleep(30); 66 return mblackcontactinfos; 67 } 68 /** 69 * 判断号码是否在黑名单中存在 70 number */ 73 public boolean IsNumberExist(String number) { 74 // 得到可读的数据库 75 SQLiteDatabase db = blacknumberopenhelper.getreadabledatabase(); 76 Cursor cursor = db.query("blacknumber", null, "number=?", 77 new String[] { number }, null, null, null); 78 if (cursor.movetonext()) { 79 cursor.close(); 80 db.close(); 81 return true; 82 } 83 cursor.close(); 84 db.close(); 85 return false; 86 } 87 /** 88 * 根据号码查询黑名单信息 89 number */ 92 public int getblackcontactmode(string number) { 93 // 得到可读的数据库 94 SQLiteDatabase db = blacknumberopenhelper.getreadabledatabase(); 95 Cursor cursor = db.query("blacknumber", new String[]{"mode"}, "number=?", 96 new String[] { number }, null, null, null); 97 int mode = 0; 98 if (cursor.movetonext()) { 99 mode = cursor.getint(cursor.getcolumnindex("mode")); 100 } 101 cursor.close(); 102 db.close(); 103 return mode; 104 } 105 /** 7

8 106 * 获取数据库的总条目个数 107 pagenumber 第几页, 页码从第 0 页开始 108 pagesize 每一个页面的大小 109 */ 110 public int gettotalnumber() { 111 // 得到可读的数据库 112 SQLiteDatabase db = blacknumberopenhelper.getreadabledatabase(); 113 Cursor cursor = db.rawquery("select count(*) from blacknumber", null); 114 cursor.movetonext(); 115 int count = cursor.getint(0); 116 cursor.close(); 117 db.close(); 118 return count; 119 } 120 } 第 12~28 行的 add() 方法用于向数据库中添加数据, 首先获取到数据库对象 SQLiteDatabase, 然后创建 ContentValues 对象, 并通过 if 语句判断黑名单号码是否是 +86 开头, 如果是则对电话号码进行截取将 +86 去掉, 最后将电话号码 姓名 拦截模式存入到数据库中, 并返回数据是否插入成功的状态 第 34~43 行的 delete() 方法用于删除数据, 同样先获取数据库对象 SQLiteDatabase 然后调用 delete() 方法, 根据电话号码删除数据, 并返回删除结果 第 49~67 行的 getpageblacknumber() 方法用于分页查询数据库中的黑名单数据 第 73~86 行的 IsNumberExist() 方法根据接收的号码判断当前号码是否在黑名单数据库中 第 92~104 行的 getblackcontactmode() 方法是根据传递进来的号码获取黑名单拦截模式, 判断是电话拦截 短信拦截或者电话和短信都拦截 第 110~119 行的 gettotalnumber() 方法用于获取数据库中存储数据的总条目 测试数据 在程序开发中, 开发者需要对每一个新模块或者方法进行测试, 以保证代码可运行没有 BUG, 由于数据库工具类中操作黑名单数据的方法比较多, 而且这些数据需要填充到主界面中, 为了避免后期出现错误导致调试困难, 最好在使用这些方法之前进行测试 Android 系统自带了测试框架 JUnit, 接下来使用该框架对数据库工具类中的方法进行测试, 首先在清单文件中配置相应信息, 具体代码如 文件 3-4 所示 文件 3-4 AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" package="cn.itcast.mobliesafe" android:versioncode="1" android:versionname="1.0" > <uses-sdk android:minsdkversion="15" android:targetsdkversion="17" /> 8

9 <instrumentation android:name="android.test.instrumentationtestrunner" android:targetpackage="cn.itcast.mobliesafe"/> <application android:allowbackup="true" > <uses-library android:name="android.test.runner" > </uses-library> </application> </manifest> 接下来创建一个测试类 TestBlackNumberDao 继承自 AndroidTestCase, 并对数据库中增加 删除 分页查询等方法进行测试 需要注意的是, 在 JUnit 测试框架中, 测试方法的异常必须抛出, 不能 try-catch, 否则测试框架捕获不到异常 测试类的代码如 文件 3-5 所示 文件 3-5 TestBlackNumberDao.java 1 public class TestBlackNumberDao extends AndroidTestCase { 2 private Context context; 4 protected void setup() throws Exception { 5 context = getcontext(); 6 super.setup(); 7 } 8 /** 9 * 测试添加 10 Exception 11 */ 12 public void testadd() throws Exception { 13 BlackNumberDao dao = new BlackNumberDao(context); 14 Random random = new Random(8979); 15 for (long i = 1; i < 30; i++) { 16 BlackContactInfo info = new BlackContactInfo(); 17 info.phonenumber = l + i + ""; 18 info.contactname = "zhangsan" + i; 19 info.mode = random.nextint(3) + 1; 20 dao.add(info); 21 } 22 } 23 /** 24 * 测试刪除 25 Exception 26 */ 9

10 27 public void testdelete() throws Exception { 28 BlackNumberDao dao = new BlackNumberDao(context); 29 BlackContactInfo info = new BlackContactInfo(); 30 for (long i = 1; i < 5; i++) { 31 info.phonenumber = l + i + ""; 32 dao.delete(info); 33 } 34 } 35 /** 36 * 测试分页查询 37 Exception 38 */ 39 public void testgetpageblacknumber() throws Exception { 40 BlackNumberDao dao = new BlackNumberDao(context); 41 List<BlackContactInfo> list = dao.getpageblacknumber(2, 5); 42 for (int i = 0; i < list.size(); i++) { 43 Log.i("TestBlackNumberDao", list.get(i).phonenumber); 44 } 45 } 46 /** 47 * 测试根据号码查询黑名单信息 48 Exception 49 */ 50 public void testgetblackcontactmode() throws Exception { 51 BlackNumberDao dao = new BlackNumberDao(context); 52 int mode = dao.getblackcontactmode( l + ""); 53 Log.i("TestBlackNumberDao", mode + ""); 54 } 55 /** 56 * 测试数据总条目 57 Exception 58 */ 59 public void testgettotalnumber() throws Exception { 60 BlackNumberDao dao = new BlackNumberDao(context); 61 int total = dao.gettotalnumber(); 62 Log.i("TestBlackNumberDao", " 数据总条目 : " + total); 63 } 64 /** 65 * 测试号码是否在数据库中 66 Exception 67 */ 68 public void testisnumberexist() throws Exception { 69 BlackNumberDao dao = new BlackNumberDao(context); 70 boolean isexist = dao.isnumberexist( l + ""); 10

11 71 if (isexist) { 72 Log.i("TestBlackNumberDao", " 该号码在数据库中 "); 73 } else { 74 Log.i("TestBlackNumberDao", " 该号码不在数据库中 "); 75 } 76 } 77 } 在测试数据时, 首先要测试添加方法, 向数据库中添加 10 条数据, 然后在测试其他方法, 如果测试 通过则在 JUnit 窗口中显示绿条, 如图 3-5 所示 图 3-5 测试成功值得一提的是, 如果在测试这几个方法时,JUnit 窗口的测试结果显示绿条, 说明数据库逻辑没问题测试通过, 可以正常向数据库中添加 删除或者查看数据 3.3 主界面 主界面 UI 当数据库搭建好之后, 开始编写通讯卫士主界面, 该界面有两种展示形式, 一种是当数据库中没有黑 名单数据时, 显示默认图片和文字提示 ; 另一种是当数据库中有黑名单数据时, 将黑名单信息以 ListView 的方式展示在界面中 主界面的图形化界面如图 3-6 所示 11

12 图 3-6 主界面需要注意的是, 图 3-6 中右侧黑名单列表的帧布局是隐藏的, 只有在黑名单中有数据时才显示, 这里为了让编程者看到更直观的效果, 故将 ListView 设置为显示状态, 主界面布局代码如 文件 3-6 所示 文件 3-6 activity_securityphone.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <include /> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="10" > <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="100dp" android:layout_height="100dp" android:layout_centerinparent="true" /> <TextView android:layout_centerhorizontal="true" 12

13 android:layout_margintop="16dp" android:text=" 您还没有添加黑名单 " android:textscalex="1.2" /> </RelativeLayout> </FrameLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" > <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:dividerheight="1dp" android:divider="#ffffff"/> </FrameLayout> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" > <Button android:layout_width="170dp" android:layout_height="40dp" android:layout_gravity="center" android:layout_margin="10dp" /> </LinearLayout> </LinearLayout> 在上述代码中, 主要包含两个 FrameLayout 布局, 这两个布局分别用于显示有黑名单和无黑名单的情况, 当这两个布局在切换时实际上就是控制两个 FrameLayout 的显示与隐藏 当前布局的最下方有一个 Button 按钮, 该按钮的背景图片使用了图片选择器, 在按钮按下与松开时显示不同颜色的图片, 图片选择器的代码如 文件 3-7 所示 文件 3-7 res/ drawable/ add_blacknumber_btn_selector.xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android=" > <item android:state_pressed="true" <item android:state_pressed="false" 13

14 </selector> 从上述代码可以看出, 当按钮处于按下状态时, 使用紫色的背景图片 (add_blackname_btn_p.png), 当按钮抬起时, 使用灰色的背景图片 (add_blackname_btn_n.png) 黑名单 Item 布局 由于主界面的黑名单列表是通过 ListView 控件展示的, 因此需要定义一个黑名单的 Item 布局, 保证 每个条目的布局都是一致的,Item 布局的图形化界面如图 3-7 所示 图 3-7 黑名单 Item 布局图 3-7 黑名单 Item 对应的布局文件如 文件 3-8 所示 文件 3-8 item_list_blackcontact.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="# " android:orientation="vertical" > <View android:layout_width="60dp" android:layout_height="60dp" android:layout_centervertical="true" android:layout_margin="15dp" /> <TextView /> 14

15 <TextView android:layout_margintop="10dp" /> <View android:layout_width="34dp" android:layout_height="40dp" android:layout_alignparentright="true" android:layout_marginright="20dp" android:layout_centervertical="true"/> </RelativeLayout> 上述布局中, 使用了两个 View 对象以及两个 TextView 控件, 其中 View 控件用于表示联系人图标和删除图标,TextView 控件用于显示联系人号码以及拦截方式 主界面逻辑代码 主界面的功能主要包含显示黑名单信息 ( 姓名 电话 拦截模式 ), 点击删除按钮将当前黑名单从界面以及数据库中删除, 接下来编写主界面业务逻辑, 具体代码如 文件 3-9 所示 文件 3-9 SecurityPhoneActivity.java 1 public class SecurityPhoneActivity extends Activity implements OnClickListener { 2 /** 有黑名单时, 显示的帧布局 */ 3 private FrameLayout mhaveblacknumber; 4 /** 没有黑名单时, 显示的帧布局 */ 5 private FrameLayout mnoblacknumber; 6 private BlackNumberDao dao; 7 private ListView mlistview; 8 private int pagenumber = 0; 9 private int pagesize = 15; 10 private int totalnumber; 11 private List<BlackContactInfo> pageblacknumber = new ArrayList<BlackContactInfo>(); 12 private BlackContactAdapter adapter; 14 protected void oncreate(bundle savedinstancestate) { 15 super.oncreate(savedinstancestate); 16 requestwindowfeature(window.feature_no_title); 17 setcontentview(r.layout.activity_securityphone); 18 initview(); 19 filldata(); 15

16 20 } 22 protected void onresume() { 23 super.onresume(); 24 if (totalnumber!= dao.gettotalnumber()) { 25 // 数据发生变化 26 if (dao.gettotalnumber() > 0) { 27 mhaveblacknumber.setvisibility(view.visible); 28 mnoblacknumber.setvisibility(view.gone); 29 } else { 30 mhaveblacknumber.setvisibility(view.gone); 31 mnoblacknumber.setvisibility(view.visible); 32 } 33 pagenumber = 0; 34 pageblacknumber.clear(); 35 pageblacknumber.addall(dao.getpageblacknumber(pagenumber, pagesize)); 36 if (adapter!= null) { 37 adapter.notifydatasetchanged(); 38 } 39 } 40 } 41 /** 42 * 用于填充数据, 重新刷新界面 43 */ 44 private void filldata() { 45 dao = new BlackNumberDao(SecurityPhoneActivity.this); 46 totalnumber = dao.gettotalnumber(); 47 if (totalnumber == 0) { 48 // 数据库中没有黑名单数据 49 mhaveblacknumber.setvisibility(view.gone); 50 mnoblacknumber.setvisibility(view.visible); 51 } else if (totalnumber > 0) { 52 // 数据库中含有黑名单数据 53 mhaveblacknumber.setvisibility(view.visible); 54 mnoblacknumber.setvisibility(view.gone); 55 pagenumber = 0; 56 if (pageblacknumber.size() > 0) { 57 pageblacknumber.clear(); 58 } 59 pageblacknumber.addall(dao.getpageblacknumber(pagenumber, pagesize)); 60 if (adapter == null) { 61 adapter = new BlackContactAdapter(pageBlackNumber, 62 SecurityPhoneActivity.this); 63 adapter.setcallback(new BlackConactCallBack() { 16

17 65 public void DataSizeChanged() { 66 filldata(); 67 } 68 }); 69 mlistview.setadapter(adapter); 70 } else { 71 adapter.notifydatasetchanged(); 72 } 73 } 74 } 75 /** 76 * 对控件进行初始化 77 */ 78 private void initview() { 79 findviewbyid(r.id.rl_titlebar).setbackgroundcolor( 80 getresources().getcolor(r.color.bright_purple)); 81 ImageView mleftimgv = (ImageView) findviewbyid(r.id.imgv_leftbtn); 82 ((TextView) findviewbyid(r.id.tv_title)).settext(" 通讯卫士 "); 83 mleftimgv.setonclicklistener(this); 84 mleftimgv.setimageresource(r.drawable.back); 85 mhaveblacknumber = (FrameLayout) findviewbyid(r.id.fl_haveblacknumber); 86 mnoblacknumber = (FrameLayout) findviewbyid(r.id.fl_noblacknumber); 87 findviewbyid(r.id.btn_addblacknumber).setonclicklistener(this); 88 mlistview = (ListView) findviewbyid(r.id.lv_blacknumbers); 89 mlistview.setonscrolllistener(new OnScrollListener() { 91 public void onscrollstatechanged(abslistview view, int scrollstate) { 92 switch (scrollstate) { 93 case OnScrollListener.SCROLL_STATE_IDLE: // 没有滑动的状态 94 // 获取最后一个可见条目 95 int lastvisibleposition = mlistview.getlastvisibleposition(); 96 // 如果当前条目是最后一个增查询更多的数据 97 if (lastvisibleposition == pageblacknumber.size() - 1) { 98 pagenumber++; 99 if (pagenumber * pagesize >= totalnumber) { 100 Toast.makeText(SecurityPhoneActivity.this, 101 " 没有更多的数据了 ", 0).show(); 102 } else { 103 pageblacknumber.addall(dao.getpageblacknumber( 104 pagenumber, pagesize)); 105 adapter.notifydatasetchanged(); 106 } 17

18 107 } 108 break; 109 } 110 } 112 public void onscroll(abslistview view, int firstvisibleitem, 113 int visibleitemcount, int totalitemcount) { 114 } 115 }); 116 } 118 public void onclick(view v) { 119 switch (v.getid()) { 120 case R.id.imgv_leftbtn: 121 finish(); 122 break; 123 case R.id.btn_addblacknumber: 124 // 跳转至添加黑名单页面 125 startactivity(new Intent(this, AddBlackNumberActivity.class)); 126 break; 127 } 128 } 129 } 第 22~40 行代码重写了 onresume() 方法, 当 Activity 回到前台时调用, 在该方法中判断数据库总 条目是否发生变化, 如果发生变化则将页码置为 0, 清空黑名单中数据重写添加, 并更新数据 其中第 26~32 行代码判断黑名单数据库中有没有数据, 如果没有数据则显示主界面的第一种布 局, 如果有数据则显示第二种布局并将数据以分页的方式显示在界面上 第 78~116 行的 initview() 方法用于初始化控件, 其中第 89~115 行代码是 ListView 的滑动监听事 件, 在 onscrollstatechanged() 方法中主要功能是获取数据库中的数据分页显示在界面上, 每页显 示多少数据由自己定义, 当 ListView 向下滑动时再次加载同样条目的数据 第 118~128 行的 onclick() 方法用于响应界面按钮的点击事件, 当点击左上角的返回按钮时关闭 当前 Activity, 当点击添加黑名单按钮时, 跳转到添加黑名单界面 数据填充 主界面通过 ListView 显示黑名单列表时, 使用了数据适配器 BaseAdapter, 接下来创建该数据适配器类, 具体代码如 文件 3-10 所示 文件 3-10 BlackContactAdapter.java 1 public class BlackContactAdapter extends BaseAdapter { 2 private List<BlackContactInfo> contactinfos; 3 private Context context; 4 private BlackNumberDao dao; 5 private BlackConactCallBack callback; 18

19 6 public void setcallback(blackconactcallback callback) { 7 this.callback = callback; 8 } 9 public BlackContactAdapter(List<BlackContactInfo> systemcontacts, 10 Context context) { 11 super(); 12 this.contactinfos = systemcontacts; 13 this.context = context; 14 dao = new BlackNumberDao(context); 15 } 17 public int getcount() { 18 // TODO Auto-generated method stub 19 return contactinfos.size(); 20 } 22 public Object getitem(int position) { 23 // TODO Auto-generated method stub 24 return contactinfos.get(position); 25 } 27 public long getitemid(int position) { 28 // TODO Auto-generated method stub 29 return position; 30 } 32 public View getview(final int position, View convertview, ViewGroup parent) { 33 ViewHolder holder = null; 34 if (convertview == null) { 35 convertview = View.inflate(context, R.layout.item_list_blackcontact, null); 36 holder = new ViewHolder(); 37 holder.mnametv = (TextView) convertview.findviewbyid(r.id.tv_black_name); 38 holder.mmodetv = (TextView) convertview.findviewbyid(r.id.tv_black_mode); 39 holder.mcontactimgv = convertview.findviewbyid(r.id.view_black_icon); 40 holder.mdeleteview = convertview.findviewbyid(r.id.view_black_delete); 41 convertview.settag(holder); 42 } else { 43 holder = (ViewHolder) convertview.gettag(); 44 } 45 holder.mnametv.settext(contactinfos.get(position).contactname + "(" + 46 contactinfos.get(position).phonenumber + ")"); 47 holder.mmodetv.settext(contactinfos.get(position).getmodestring( 48 contactinfos.get(position).mode)); 19

20 49 holder.mnametv.settextcolor(context.getresources().getcolor( 50 R.color.bright_purple)); 51 holder.mmodetv.settextcolor(context.getresources().getcolor( 52 R.color.bright_purple)); 53 holder.mcontactimgv.setbackgroundresource( 54 R.drawable.brightpurple_contact_icon); 55 holder.mdeleteview.setonclicklistener(new OnClickListener() { 57 public void onclick(view v) { 58 boolean datele = dao.delete(contactinfos.get(position)); 59 if (datele) { 60 contactinfos.remove(contactinfos.get(position)); 61 BlackContactAdapter.this.notifyDataSetChanged(); 62 // 如果数据库中没有数据了, 则执行回调函数 63 if (dao.gettotalnumber() == 0) { 64 callback.datasizechanged(); 65 } 66 } else { 67 Toast.makeText(context, " 删除失败!", 0).show(); 68 } 69 } 70 }); 71 return convertview; 72 } 73 static class ViewHolder { 74 TextView mnametv; 75 TextView mmodetv; 76 View mcontactimgv; 77 View mdeleteview; 78 } 79 public interface BlackConactCallBack { 80 void DataSizeChanged(); 81 } 82 } 第 9~15 行的 BlackContactAdapter() 方法是 Adapter 构造方法, 该方法接收两个参数 List<BlackContactInfo> 和 Context 其中 List<BlackContackInfo> 表示从主界面传递的黑名单数据 集合, 加载到页面上的数据都从该集合中取出 第 55~70 行代码定义了每个条目中删除按钮的点击事件, 当点击删除按钮后, 当前条目在数据库 中被删除, 并刷新当前界面 第 73~78 行的 ViewHolder 是一个静态内部类, 作用是使 ListView 中的控件只加载一次, 优化加 载速度以及内存消耗 第 79~81 行的 BlackConactCallBack 是一个回调接口, 该接口的实现方法在主界面 SecurityPhoneActivity 中 在回调的实现方法中调用了主界面 filldata() 方法重新刷新布局页面 20

21 需要注意的是, 删除按钮的点击事件中 ( 第 64 行代码 ) 调用了 callback.datasizechanged() 方法, 该方 法是一个回调方法, 在点击删除按钮后数据库中没有数据时调用 由于只有将数据库中的数据完全删除之 后才调用回调函数, 因此删除最后一条数据时会显示默认布局, 将 ListView 布局隐藏 3.4 添加黑名单 添加黑名单界面 从功能介绍中可以看出, 添加黑名单界面主要由三部分组成, 第一部分包含两个 EditText, 用于输入要拦截的电话号码以及姓名, 第二部分包含两个 CheckBox, 用于选择拦截模式, 第三部分包含两个按钮, 当点击 添加 按钮时, 直接将输入框中的黑名单号码以及姓名添加到黑名单中, 当点击 从联系人中添加 按钮时, 将跳转到联系人列表界面, 然后选中某个联系人进行添加 添加黑名单的图形化界面如图 3-8 所示 图 3-8 添加黑名单图 3-8 添加黑名单界面对应的布局文件如 文件 3-11 所示 文件 3-11 activity_add_blacknuber.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <include layout="@layout/titlebar" /> <EditText android:id="@+id/et_balcknumber" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_margintop="20dp" 21

22 android:hint=" 请输入要添加的号码 " android:inputtype="phone" android:paddingleft="5dp" android:textsize="16sp" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_margintop="20dp" android:hint=" 请输入名称 " android:paddingleft="5dp" android:textsize="16sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="15dp" android:gravity="center" android:orientation="horizontal" > <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:checked="true" android:paddingleft="40dp" android:text=" 电话拦截 " android:textscalex="1.1" /> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:checked="true" android:paddingleft="40dp" android:text=" 短信拦截 " 22

23 android:textscalex="1.1" android:textsize="16sp" /> </LinearLayout> <Button android:layout_width="170dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_margintop="30dp" /> <Button android:layout_width="170dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_margintop="20dp" </LinearLayout> 在上述代码中, 四个按钮都使用了背景选择器, 接下来分别介绍, 具体如下 : 1)CheckBox 按钮是通过背景选择器控制按钮的选中与未选中的背景图片, 具体代码如 文件 3-12 所示 文件 3-12 res/drawable/checkbox_selector.xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android=" > <item android:state_checked="true" android:drawable="@drawable/brightpurple_checkbox_c"/> <item android:state_checked="false" android:drawable="@drawable/checkbox_n"/> </selector> 2) 添加 按钮的背景选择器是控制按钮按下与弹起的效果, 当按钮按下时显示紫色 (drawable/add_btn_p), 当按钮弹起时显示灰色 (add_btn_n), 具体代码如 文件 3-13 所示 文件 3-13 res/ drawable/ add_btn_selector_securityphone.xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android=" > <item android:state_pressed="true" android:drawable="@drawable/add_btn_p"/> <item android:state_pressed="false" android:drawable="@drawable/add_btn_n"/> </selector> 3) 从联系人添加 按钮的背景选择器同样是控制按钮按下与弹起的效果, 当按钮按下时显示紫色 (add_fromcontact_p), 当按钮弹起时显示灰色 (add_fromcontact_n), 具体代码如 文件 3-14 所示 文件 3-14 res/drawable/add_fromcontact_btn_selector_securityphone.xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android=" > <item android:state_pressed="true" android:drawable="@drawable/add_fromcontact_p"/> 23

24 <item android:state_pressed="false" </selector> 添加黑名单逻辑 添加黑名单主要有两种方式, 第一种是手动输入姓名和手机号码, 第二种是从联系人列表中选择, 当 点击 从联系人中添加 按钮时, 会跳转到联系人列表界面, 然后选择指定的联系人, 此时联系人信息会 显示在添加黑名单界面, 然后点击添加按钮即可, 具体代码如 文件 3-15 所示 文件 3-15 AddBlackNumberActivity.java 1 public class AddBlackNumberActivity extends Activity implements OnClickListener { 2 private CheckBox msmscb; 3 private CheckBox mtelcb; 4 private EditText mnumet; 5 private EditText mnameet; 6 private BlackNumberDao dao; 8 protected void oncreate(bundle savedinstancestate) { 9 super.oncreate(savedinstancestate); 10 requestwindowfeature(window.feature_no_title); 11 setcontentview(r.layout.activity_add_blacknumber); 12 dao = new BlackNumberDao(this); 13 initview(); 14 } 15 private void initview() { 16 findviewbyid(r.id.rl_titlebar).setbackgroundcolor( 17 getresources().getcolor(r.color.bright_purple)); 18 ((TextView) findviewbyid(r.id.tv_title)).settext(" 添加黑名单 "); 19 ImageView mleftimgv = (ImageView) findviewbyid(r.id.imgv_leftbtn); 20 mleftimgv.setonclicklistener(this); 21 mleftimgv.setimageresource(r.drawable.back); 22 msmscb = (CheckBox) findviewbyid(r.id.cb_blacknumber_sms); 23 mtelcb = (CheckBox) findviewbyid(r.id.cb_blacknumber_tel); 24 mnumet = (EditText) findviewbyid(r.id.et_balcknumber); 25 mnameet = (EditText) findviewbyid(r.id.et_blackname); 26 findviewbyid(r.id.add_blacknum_btn).setonclicklistener(this); 27 findviewbyid(r.id.add_fromcontact_btn).setonclicklistener(this); 28 } 30 public void onclick(view v) { 31 switch (v.getid()) { 32 case R.id.imgv_leftbtn: 33 finish(); 34 break; 24

25 35 case R.id.add_blacknum_btn: 36 String number = mnumet.gettext().tostring().trim(); 37 String name = mnameet.gettext().tostring().trim(); 38 if (TextUtils.isEmpty(number) TextUtils.isEmpty(name)) { 39 Toast.makeText(this, " 电话号码和手机号不能为空!", 0).show(); 40 return; 41 } else { 42 // 电话号码和名称都不为空 43 BlackContactInfo blackcontactinfo = new BlackContactInfo(); 44 blackcontactinfo.phonenumber = number; 45 blackcontactinfo.contactname = name; 46 if (msmscb.ischecked() & mtelcb.ischecked()) { 47 // 两种拦截模式都选 48 blackcontactinfo.mode = 3; 49 } else if (msmscb.ischecked() &!mtelcb.ischecked()) { 50 // 短信拦截 51 blackcontactinfo.mode = 2; 52 } else if (!msmscb.ischecked() & mtelcb.ischecked()) { 53 // 电话拦截 54 blackcontactinfo.mode = 1; 55 } else { 56 Toast.makeText(this, " 请选择拦截模式!", 0).show(); 57 return; 58 } 59 if (!dao.isnumberexist(blackcontactinfo.phonenumber)) { 60 dao.add(blackcontactinfo); 61 } else { 62 Toast.makeText(this, " 该号码已经被添加至黑名单 ", 0).show(); 63 } 64 finish(); 65 } 66 break; 67 case R.id.add_fromcontact_btn: 68 startactivityforresult( 69 new Intent(this, ContactSelectActivity.class), 0); 70 break; 71 } 72 } 74 protected void onactivityresult(int requestcode, int resultcode, Intent data){ 75 super.onactivityresult(requestcode, resultcode, data); 76 if (data!= null) { 77 // 获取选中的联系人信息 25

26 78 String phone = data.getstringextra("phone"); 79 String name = data.getstringextra("name"); 80 mnameet.settext(name); 81 mnumet.settext(phone); 82 } 83 } 84 } 第 15~28 行的 initview() 方法用于实现控件的初始化, 并动态设置标题栏的背景颜色以及返回按钮的图片资源, 并为 添加 从联系人中选择 按钮注册监听器 第 30~72 行的 onclick() 方法用于响应按钮的点击事件, 当点击 添加 按钮时, 首先会对输入框进行校验, 只有电话号码和姓名不为空时, 才能选择拦截模式, 然后校验数据库中是否有当前号码, 如果没有将其添加到黑名单中 ; 当点击 从联系人中选择 按钮时, 会跳转到联系人列表界面 (ContactSelectActivity) 第 74~83 行代码的 onactivityresult() 方法是接收联系人列表中选中的联系人信息, 并将该信息展示到文本输入框中 联系人列表 前一小节中使用的联系人列表在第 2 章中讲解过, 因此本章可以将之前的代码拷贝过来直接使用 ( 这样做的目的是保证本章代码的完整性, 如果是实际开发中直接调用这部分代码即可 ) 接下来列举获取联系人列表需要用到布局文件以及逻辑代码, 具体如下 : item_list_contact_select.xml: 联系人列表的 Item 布局 ( 不需要拷贝 ); activity_contact_select.xml: 联系人列表布局 ( 不需要拷贝 ); ContactInfo.java: 联系人信息的实体类 ; ContactInfoParser.java: 解析联系人信息的工具类 ; ContactAdapter.java: 联系人列表的数据适配器 ; ContactSelectActivity.java: 联系人列表的主界面逻辑 ( 记得在 AndroidManifest.xml 文件中注册 ) 由于第 2 章中联系人 Item 布局整体风格是蓝色的, 而本章是紫色的, 因此, 需要在数据适配器的代码中重新指定联系人图标 联系人姓名以及电话号码的文本颜色, 具体代码如 文件 3-16 所示 文件 3-16 ContactAdapter.java 1 public class ContactAdapter extends BaseAdapter{ 2 4 public View getview(int position, View convertview, ViewGroup parent) { 5 ViewHolder holder = null; 6 if(convertview == null){ 7 convertview = View.inflate(context,R.layout.item_list_contact_select, null); 8 holder = new ViewHolder(); 9 holder.mnametv = (TextView) convertview.findviewbyid(r.id.tv_name); 10 holder.mphonetv = (TextView) convertview.findviewbyid(r.id.tv_phone); 11 holder.mcontactimgv = convertview.findviewbyid(r.id.view1); 12 convertview.settag(holder); 13 }else{ 26

27 14 holder = (ViewHolder) convertview.gettag(); 15 } 16 holder.mnametv.settext(contactinfos.get(position).name); 17 holder.mphonetv.settext(contactinfos.get(position).phone); 18 holder.mnametv.settextcolor(context.getresources().getcolor( 19 R.color.bright_purple)); 20 holder.mphonetv.settextcolor(context.getresources(). 21 getcolor(r.color.bright_purple)); 22 holder.mcontactimgv.setbackgroundresource( 23 R.drawable.brightpurple_contact_icon); 24 return convertview; 25 } 26 static class ViewHolder{ 27 TextView mnametv; 28 TextView mphonetv; 29 View mcontactimgv; 30 } 31 } 3.5 黑名单拦截 在 Android 系统中, 当电话或短信到来时都会产生广播, 因此可以利用广播接收者将广播终止, 实现 黑名单拦截功能, 然后将电话和短信记录删除不让其在界面中显示, 本节将针对黑名单拦截功能进行详细 讲解 拦截短信 在进行短信拦截时, 需要在广播中获取到电话号码以及短信内容, 然后查询该号码是否在黑名单数据库中, 如果在则判断是哪种拦截模式, 进行拦截 接下来创建拦截短信的广播接收者, 具体代码如 文件 3-17 所示 文件 3-17 InterceptSmsReciever.java 1 public class InterceptSmsReciever extends BroadcastReceiver { 3 public void onreceive(context context, Intent intent) { 4 SharedPreferences msp = context.getsharedpreferences("config", 5 Context.MODE_PRIVATE); 6 boolean BlackNumStatus = msp.getboolean("blacknumstatus", true); 7 if (!BlackNumStatus) { 8 // 黑名单拦截关闭 9 return; 10 } 11 // 如果是黑名单则终止广播 27

28 12 BlackNumberDao dao = new BlackNumberDao(context); 13 Object[] objs = (Object[]) intent.getextras().get("pdus"); 14 for (Object obj : objs) { 15 SmsMessage smsmessage = SmsMessage.createFromPdu((byte[]) obj); 16 String sender = smsmessage.getoriginatingaddress(); 17 String body = smsmessage.getmessagebody(); 18 if (sender.startswith("+86")) { 19 sender = sender.substring(3, sender.length()); 20 } 21 int mode = dao.getblackcontactmode(sender); 22 if (mode == 2 mode == 3) { 23 // 需要拦截短信, 拦截广播 24 abortbroadcast(); 25 } 26 } 27 } 28 } 第 7~10 行的 if 语句用于判断黑名单拦截功能是否开启 ; 第 13 行代码用于获取接收到的短信信息 ; 第 14~20 行代码获取短信中的内容以及电话号码, 并对 +86 开头的号码进行截取 ; 第 21~25 行代码通过号码查询数据库为哪一种拦截模式, 如果是短信拦截或者全部拦截, 则直接将该条短信进行拦截 ; 为了让广播接收者能够拦截短信, 必须要在 AndroidManifest.xml 文件中注册, 具体代码如下所示 : <!-- 拦截黑名单信息 --> <receiver android:name="cn.itcast.mobliesafe.chapter03.reciever. InterceptSmsReciever" > <intent-filter android:priority=" " > <action android:name="android.provider.telephony.sms_received"/> </intent-filter> </receiver> 上述清单文件中, 定义了接收短信的广播, 并将广播的优先级设置为最高, 这样当有新短信到来时会优先被该广播接收者所接收 拦截电话 当电话铃响时需要手动挂断电话并且不让该记录显示在界面上, 而 Google 工程师为了手机的安全性隐藏了挂断电话的服务方法, 因此要实现挂断电话的操作只能通过反射获取底层服务 接下来创建拦截电话的广播接收者, 具体代码如 文件 3-18 所示 文件 3-18 InterceptCallReceiver.java 1 public class InterceptCallReciever extends BroadcastReceiver { 3 public void onreceive(context context, Intent intent) { 4 SharedPreferences msp = context.getsharedpreferences("config", 28

29 5 Context.MODE_PRIVATE); 6 boolean BlackNumStatus = msp.getboolean("blacknumstatus", true); 7 if (!BlackNumStatus) { 8 // 黑名单拦截关闭 9 return; 10 } 11 BlackNumberDao dao = new BlackNumberDao(context); 12 if (!intent.getaction().equals(intent.action_new_outgoing_call)) { 13 String mincomingnumber = ""; 14 // 如果是来电 15 TelephonyManager tmanager = (TelephonyManager) context 16.getSystemService(Service.TELEPHONY_SERVICE); 17 switch (tmanager.getcallstate()) { 18 case TelephonyManager.CALL_STATE_RINGING: 19 mincomingnumber = intent.getstringextra("incoming_number"); 20 int blackcontactmode = dao.getblackcontactmode(mincomingnumber); 21 if (blackcontactmode == 1 blackcontactmode == 3) { 22 // 观察 ( 另外一个应用程序数据库的变化 ) 呼叫记录的变化, 23 // 如果呼叫记录生成了, 就把呼叫记录给删除掉 24 Uri uri = Uri.parse("content://call_log/calls"); 25 context.getcontentresolver().registercontentobserver( 26 uri, true, new CallLogObserver(new Handler(), 27 mincomingnumber, context)); 28 endcall(context); 29 } 30 break; 31 } 32 } 33 } 34 /** 35 * 通过内容观察者观察数据库变化 36 */ 37 private class CallLogObserver extends ContentObserver { 38 private String incomingnumber; 39 private Context context; 40 public CallLogObserver(Handler handler, String incomingnumber, Context context){ 41 super(handler); 42 this.incomingnumber = incomingnumber; 43 this.context = context; 44 } 45 // 观察到数据库内容变化调用的方法 47 public void onchange(boolean selfchange) { 29

30 48 Log.i("CallLogObserver", " 呼叫记录数据库的内容变化了 "); 49 context.getcontentresolver().unregistercontentobserver(this); 50 deletecalllog(incomingnumber, context); 51 super.onchange(selfchange); 52 } 53 } 54 /** 55 * 清除呼叫记录 56 incomingnumber 57 */ 58 public void deletecalllog(string incomingnumber, Context context) { 59 ContentResolver resolver = context.getcontentresolver(); 60 Uri uri = Uri.parse("content://call_log/calls"); 61 Cursor cursor = resolver.query(uri, new String[] { "_id" }, "number=?", 62 new String[] { incomingnumber }, "_id desc limit 1"); 63 if (cursor.movetonext()) { 64 String id = cursor.getstring(0); 65 resolver.delete(uri, "_id=?", new String[] { id }); 66 } 67 } 68 /** 69 * 挂断电话, 需要复制两个 AIDL 70 */ 71 public void endcall(context context) { 72 try { 73 Class clazz = 74 context.getclassloader().loadclass("android.os.servicemanager"); 75 Method method = clazz.getdeclaredmethod("getservice", String.class); 76 IBinder ibinder = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE); 77 ITelephony itelephony = ITelephony.Stub.asInterface(iBinder); 78 itelephony.endcall(); 79 } catch (Exception e) { 80 e.printstacktrace(); 81 } 82 } 83 } 第 37~53 行的 CallLogObserver 是一个内容观察者, 用于观察系统联系人的数据库, 如果黑名单 中的电话呼入时, 在系统联系人数据库中产生记录时就调用 deletecalllog() 方法清除历史记录 第 58~67 行的 deletecalllog() 方法用于清除历史记录, 当黑名单中的电话呼入时, 手机系统通话 记录中会显示该条记录, 因此需要把通话记录中的黑名单通话记录删除 手机上拨打电话接听电 话等产生的记录都在系统 contacts 应用下的 contacts2.db 数据库中, 使用 ContentResolver 对象查 询并删除数据库中黑名单号码所产生的记录即可 第 71~82 行的 endcall() 方法用于挂断黑名单的呼入电话, 该段代码中首先通过反射获取到 ServiceManager 字节码, 然后通过该字节码获取 getservice() 方法, 该方法接收一个 String 类型的 30

31 参数, 然后通过 invoke() 执行 getservice() 方法, 由于 getservice() 方法是静态的, 因此 invoke() 的第一个参数可以为 null, 第二个参数是 TELEPHONY_SERVICE 由于 getservice() 方法的返回值是一个 IBinder 对象 ( 远程服务的代理类 ), 因此需要使用 AIDL 的规则将其转化为接口类型, 由于我们的操作是挂断电话, 因此需要使用与电话相关的 ITelephony.aidl, 然后调用接口中的 endcall() 方法将电话挂断即可 需要注意的是, 与电话相关的操作一般都使用 TelephonyManager 类, 但是由于挂断电话的方法在 ITelephony 接口中, 而这个接口是隐藏的 (@hide) 在开发时看不到, 因此需要使用 ITelephony.aidl 在使用 ITelephony.aidl 时, 需要创建一个与它包名一致的包 com.android.internal.telephony 然后把系统的 ITelephony.aidl 文件拷贝进来, 同时 ITelephony.aidl 接口关联了 NeighboringCellInfo.aidl, 所以也需要一并拷贝进来 不过要注意的是,NeighboringCellInfo.aidl 所在的的包名是 android.telephony, 因此需要新建一个 android.telephony 包, 然后把 NeighboringCellInfo.aidl 放到包该包中 接下来在 AndroidManifest.xml 文件中注册拦截电话的广播接收者, 并且添加与电话有关的权限, 具体代码如下所示 : <uses-permission android:name="android.permission.call_phone" /> <uses-permission android:name="android.permission.read_call_log" /> <uses-permission android:name="android.permission.write_call_log" /> <application android:allowbackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/apptheme" > <!-- 拦截黑名单电话 --> <receiver android:name="cn.itcast.mobliesafe.chapter03.reciever. InterceptCallReciever" > <intent-filter android:priority=" " > <action android:name="android.intent.action.phone_state" /> <action android:name="android.intent.action.new_outgoing_call" /> </intent-filter> </receiver> </application> 至此, 通讯卫士模块已经全部完成, 接下来对该模块的功能进行完整测试 首先, 在添加黑名单界面手动输入或者从联系人列表中选择一个联系人, 例如张三, 电话号码 , 然后使用张三的手机拨打电话, 并在电话和短信广播的代码中打上 Log 以便观察结果, 这时会看到在 Log 中打印出了电话号码以及短信内容, 但是手机界面上没有任何显示, 说明黑名单拦截功能运行正常 3.6 本章小结 本章主要针对通讯卫士模块进行讲解, 首先针对该模块功能进行介绍, 然后从创建数据库 创建 UI 编写主界面逻辑代码 编写添加黑名单界面逻辑代码到拦截电话和短信进行了详细讲解 该模块功能复杂, 尤其是挂断电话操作使用了 AIDL 进程间通信, 编程者要加强学习, 并要动手完成所有代码, 为学习后面模块的奠定基础 31

32 面试精选 1 请问 Handler 消息机制的原理是什么, 及应用场景 2 请问如何将 SQLite 数据库文件与 apk 文件一起发布 扫描右方二维码, 查看面试题答案! 32

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new

主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new ListView 自訂排版 主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new int[]{r.drawable.dog1, R.drawable.dog2,

More information

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml

res/layout 目录下的 main.xml 源码 : <?xml version=1.0 encoding=utf 8?> <TabHost android:layout_height=fill_parent xml 拓展训练 1- 界面布局 1. 界面布局的重要性做应用程序, 界面是最基本的 Andorid 的界面, 需要写在 res/layout 的 xml 里面, 一般情况下一个 xml 对应一个界面 Android 界面布局有点像写 html( 连注释代码的方式都一样 ), 要先给 Android 定框架, 然后再在框架里面放控件,Android 提供了几种框架,AbsoluteLayout,LinearLayout,

More information

图 6-1 主界面 MainActivity 界面对应的布局文件 (activity_main.xml) 如下所示 : <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="

图 6-1 主界面 MainActivity 界面对应的布局文件 (activity_main.xml) 如下所示 : <?xml version=1.0 encoding=utf-8?> <RelativeLayout xmlns:android= 第 6 章广播接收者 应用案例 案例 6-1 CallRecord( 通话记录 ) 一 案例描述 1 考核知识点 030006001: 广播接收者简介 030006002: 广播接收者的创建 2 练习目标 广播的静态注册和使用 使用广播处理处理事件 3 需求分析手机最重要的功能就是通话功能, 同样储存通话记录也是必不可少的 该案例使用广 播接收者自己实现通话记录的功能 包括呼出电话 已接来电 未接来电以及通话产生的

More information

预览图 : (2) 在 SelectCity.java 中增加控件, 用于绑定 select_city 文件的 ListView, TextView,EditTest 等控件 代码和注释如下 :

预览图 : (2) 在 SelectCity.java 中增加控件, 用于绑定 select_city 文件的 ListView, TextView,EditTest 等控件 代码和注释如下 : EditText 实现城市搜索 1801210778 邹宇航 摘要 : 使用 EditText 实现搜索城市的功能, 以此为依据更新 ListView 1. 效果图 : 2. 主要步骤 (1) 在 select-city.xml 布局文件中中添加 EditText 控件用作搜索框, 然后添加 ListView 控件用来显示城市名字内容 代码如下 : 预览图 : (2) 在 SelectCity.java

More information

Android Service

Android Service Android Service- 播放音樂 建國科技大學資管系 饒瑞佶 2013/7 V1 Android Service Service 是跟 Activity 並行 一個音樂播放程式若沒使用 Service, 即使按 home 鍵畫面離開之後, 音樂還是照播 如果再執行一次程式, 新撥放的音樂會跟先前撥放的一起撥, 最後程式就會出錯 執行中的程式完全看不到! 但是, 寫成 Service 就不同了

More information

RecyclerView and CardVew

RecyclerView and CardVew RecyclerView and CardView 建國科技大學資管系饒瑞佶 2017/10 V1 CardView CardView A CardView is a ViewGroup. Like any other ViewGroup, it can be added to youractivity or Fragment using a layout XML file. To create an

More information

Microsoft Word - 第4章 3D相册.doc

Microsoft Word - 第4章 3D相册.doc 第 4 章 3D 相册 学习目标 u 掌握相册界面的开发, 实现相册的立体与倒影效果 在现实生活中, 我们浏览照片时, 不同的相册软件有不同的浏览效果 本章主要实现了一个 3D 效果的相册, 该相册中的图片可以循环滑动展示 4.1 3D 相册 任务综述 相册界面主要是展示一组图片的立体效果, 并显示每个图片的倒影, 左右滑动可以切换不同的图片到 界面的中间位置, 同时在图片下方显示当前图片的标题,

More information

Android Fragment

Android Fragment Android Fragment 建國科技大學資管系饒瑞佶 2017/10 V1 Android 3.0 後才支援 Fragment 解決部分 App 適應螢幕大小的問題 它類似於 Activity, 可以像 Activity 可以擁有自己的版面設計, 也和 Activity 一樣有自己的生命週期 ( 具備 oncreate() oncreateview() 與 onpause() 方法 ) LifeCycle

More information

建模与图形思考

建模与图形思考 F06_c 观摩 :ContentProvider 基於軟硬整合觀點 架构與 DB 引擎移植方法 ( c) By 高煥堂 4 通用性基类 ContentProvider 基於軟硬整合觀點 的使用范例 刚才的范例里, 我们直接使用 DataPersist 类的接口来与 SQLite 沟通 本节将替 DataPersist 配上 ContentProvider 基类, 让 Client 能透过 ContentProvider

More information

Microsoft Word - weather12 刷新按钮动画+搜索框+bug处理.docx

Microsoft Word - weather12 刷新按钮动画+搜索框+bug处理.docx 一 刷新按钮的动画效果 : 在刷新按钮的位置做两个按钮的布局, 一个是原来的静态图片, 一个是旋转的动画, 然 后控制这两个效果的显示和隐藏 ( 一 ) 刷新按钮的 style: 1. 在 app/src/main/res/values/ styles.xml 文件里添加一个 style: 2. 在 drawable 文件夹下新建一个 title_update_anim.xml, 添加如下内容 注

More information

Android 编程基础 Android 开发教程 & 笔记 1

Android 编程基础 Android 开发教程 & 笔记 1 Android 开发教程 & 笔记 1 多式样 ProgressBar 撰写 : 地狱怒兽 联系 :zyf19870302@126.com 普通圆形 ProgressBar 该类型进度条也就是一个表示运转的过程, 例如发送短信, 连接网络等等, 表示一个过程正 在执行中 一般只要在 XML 布局中定义就可以了

More information

任务实施 (1) 创建项目 图 3-1 欢迎界面 首先创建一个工程, 将其命名为 BoXueGu, 指定包名为 com.boxuegu (2) 导入界面图片将欢迎界面所需要的背景图片 launch_bg.png 导入到 drawable 文件夹中, 项目的 icon 图标 app_icon.png

任务实施 (1) 创建项目 图 3-1 欢迎界面 首先创建一个工程, 将其命名为 BoXueGu, 指定包名为 com.boxuegu (2) 导入界面图片将欢迎界面所需要的背景图片 launch_bg.png 导入到 drawable 文件夹中, 项目的 icon 图标 app_icon.png 第 3 章注册与登录模块 学习目标 掌握欢迎界面的开发, 能够独立制作欢迎界面 ; 掌握注册和登录模块的开发, 能够实现用户登录功能 博学谷项目的注册与登录模块主要用于创建用户账号, 管理用户信息 当用户注册成功后会跳转到登录界面, 用户登录后可以修改密码以及设置密保, 且只有设置过密保的账户才可以找回密码 本章将针对注册与登录模块进行详细讲解 3.1 欢迎界面 任务综述 在实际开发中, 开启应用程序时首先会呈现一个欢迎界面,

More information

Dynamic Layout in Android

Dynamic Layout in Android Dynamic Layout in Android 建國科技大學資管系 饒瑞佶 2013/5 V1 Layout 多半都透過 res/layout/xml 格式設定來達成 Android 是 OOP, 所以可以動態產生 Layout 重點是 Layout 的階層關係 (Hierarchy) 需要處理對應事件 最後一樣用 setcontentview 加入 Layout 一 加入現有 Layout 中

More information

Microsoft Word - 01.DOC

Microsoft Word - 01.DOC 第 1 章 JavaScript 简 介 JavaScript 是 NetScape 公 司 为 Navigator 浏 览 器 开 发 的, 是 写 在 HTML 文 件 中 的 一 种 脚 本 语 言, 能 实 现 网 页 内 容 的 交 互 显 示 当 用 户 在 客 户 端 显 示 该 网 页 时, 浏 览 器 就 会 执 行 JavaScript 程 序, 用 户 通 过 交 互 式 的

More information

建模与图形思考

建模与图形思考 C03_c 基 於 軟 硬 整 合 觀 點 JNI: 从 C 调 用 Java 函 数 ( c) By 高 煥 堂 3 How-to: 基 於 軟 硬 整 合 觀 點 从 C 调 用 Java 函 数 如 果 控 制 点 摆 在 本 地 C 层, 就 会 常 常 1. 从 本 地 C 函 数 去 调 用 Java 函 数 ; 2. 从 本 地 C 函 数 去 存 取 Java 层 对 象 的 属 性

More information

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入 100 年 特 種 考 試 地 方 政 府 公 務 人 員 考 試 試 題 等 別 : 三 等 考 試 類 科 : 資 訊 處 理 科 目 : 系 統 分 析 與 設 計 一 請 參 考 下 列 旅 館 管 理 系 統 的 使 用 案 例 圖 (Use Case Diagram) 撰 寫 預 約 房 間 的 使 用 案 例 規 格 書 (Use Case Specification), 繪 出 入

More information

0511-Android程式之GPS應用_專題週記4

0511-Android程式之GPS應用_專題週記4 逢甲大學通訊工程學系專題研究 Android 程式之 GPS 應用 專題週記 0511 學生姓名 陳彥儒 D0035131 廖元譽 D0077791 指導老師 楊豐瑞老師繳交日期 2014.05.11 1 匯入 GoogleMap 1.1 取得授權步驟 目前進度 取得 Google 授權鑰匙 實作程式尚未成功 1.1.1 建立個人的 keystore 1.1.2 由個人的 keystore 查詢 SHA1

More information

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例 帝国 CMS 下在 PHP 文件中调用数据库类执行 SQL 语句实例 这篇文章主要介绍了帝国 CMS 下在 PHP 文件中调用数据库类执行 SQL 语句实例, 本文还详细介绍了帝国 CMS 数据库类中的一些常用方法, 需要的朋友可以参考下 例 1: 连接 MYSQL 数据库例子 (a.php)

More information

untitled

untitled JavaEE+Android - 6 1.5-2 JavaEE web MIS OA ERP BOSS Android Android Google Map office HTML CSS,java Android + SQL Sever JavaWeb JavaScript/AJAX jquery Java Oracle SSH SSH EJB+JBOSS Android + 1. 2. IDE

More information

_banneradview.setuserkeywords("swimming"); _banneradview.setusercategories("1,3,4"); _banneradview.setusergender(jdbanneradview.gender_male); _bannera

_banneradview.setuserkeywords(swimming); _banneradview.setusercategories(1,3,4); _banneradview.setusergender(jdbanneradview.gender_male); _bannera 京东与 AdView APP 联盟 SDK Android 版接口说明文档 1.5 1. 嵌入 SDK 1.1 添加 SDK Android Studio 环境 : 菜单 New->New Module->Import.jar or.aar package, 然后选中 App 联盟 SDK 所带的 jar 文件 Eclipse+ADT 环境 : 将 App 联盟 SDK 所带的 jar 文件拷贝到

More information

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e Android Studio Debugging 本篇教學除了最基本的中斷點教學之外, 還有條件式中斷的教學 條件式中斷是進階的除錯技巧, 在某些特定情況中, 我們有一個函數可能會被呼叫數次, 但是我們只希望在某種條件成立時才進行中斷, 進而觀察變數的狀態 而條件式中斷這項技巧正是符合這項需求 本教學分兩部分 單步除錯 (Page2~11, 共 10) 條件式中斷點 (Page12~17, 共 6)

More information

Database_001

Database_001 作者 : 林致宇日期 :2011/10/26 主要參考來源 : http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applicat ions/ 問題 : 如在存取一個已經建立好的資料庫? 解答 : 有一些應用程式會需要讀取已經建立好的資料庫, 例如一個試題測驗應用程式, 裡面的試題可能已經於電腦上, 使用任何的

More information

Microsoft Word - 第3章 Activity.doc

Microsoft Word - 第3章 Activity.doc 第 3 章 Activity 学习目标 u 掌握 Activity 的生命周期 u 掌握 Activity 的四种启动模式 u 掌握显式意图和隐式意图的使用 u 学会使用 Intent 传递数据在现实生活中, 经常会使用手机进行打电话 发短信 玩游戏等, 这就需要与手机界面进行交互 在 Android 系统中, 用户与程序的交互是通过 Activity 完成的 同时 Activity 也是 Android

More information

EJB-Programming-4-cn.doc

EJB-Programming-4-cn.doc EJB (4) : (Entity Bean Value Object ) JBuilder EJB 2.x CMP EJB Relationships JBuilder EJB Test Client EJB EJB Seminar CMP Entity Beans Session Bean J2EE Session Façade Design Pattern Session Bean Session

More information

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit Tomcat Web JUnit Cactus JUnit Java Cactus JUnit 26.1 JUnit Java JUnit JUnit Java JSP Servlet JUnit Java Erich Gamma Kent Beck xunit JUnit boolean JUnit Java JUnit Java JUnit Java 26.1.1 JUnit JUnit How

More information

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 -> 目录 1 大概思路... 1 2 创建 WebAPI... 1 3 创建 CrossMainController 并编写... 1 4 Nuget 安装 microsoft.aspnet.webapi.cors... 4 5 跨域设置路由... 4 6 编写 Jquery EasyUI 界面... 5 7 运行效果... 7 8 总结... 7 1 1 大概思路 创建 WebAPI 创建 CrossMainController

More information

用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應

用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應 專題進度 老師 : 趙啟時老師 學生 : 陳建廷 2013/10/13 用手機直接傳值不透過網頁連接, 來當作搖控器控制家電 ( 電視遙控器 ) 按下按鍵發送同時會回傳值來確定是否有送出 問題 :1. 應該是使用了太多 thread 導致在傳值上有問題 2. 一次按很多次按鈕沒辦法即時反應 程式碼 : package com.example.phone; import java.util.arraylist;

More information

Android + NFC

Android + NFC Android + NFC 建國科技大學資管系饒瑞佶 2017/3 v1 讀取 Tag UUID Android 2.3.3 (API Level 10) 才有支援完整的 NFC 功能 只要 NFC 相容都讀的到 (NFC 或 Mifare) 建立新專案修改 AndroidManifest.xml 加入 , 如果有 NFC Tag 進入感測範圍, 本 App 也會變成可處理的

More information

untitled

untitled 1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override

More information

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1

More information

第 5 章 Android 控件进阶操作实战 ArrayAdapter 适配器 ListView 的数据渲染都需要借助适配器来完成, 首先看一下结合最简单的 ArrayAdapter 来实现 ListView 主布局文件 (activity_main.xml) 代码如下 : <?

第 5 章 Android 控件进阶操作实战 ArrayAdapter 适配器 ListView 的数据渲染都需要借助适配器来完成, 首先看一下结合最简单的 ArrayAdapter 来实现 ListView 主布局文件 (activity_main.xml) 代码如下 : <? 108 Android 开发入门百战经典 第 5 章 Android 控件进阶操作实战 5.1 控之经典 ListView ListView 是最经典的控件之一, 虽然现在其江山地位不稳, 将要被 RecylerView 取 代, 但设计理念是很经典的, 而且很多程序员还是习惯了 ListView, 因此我们还需要对 ListView 进行深入学习 ListView 内容非常多, 读者要有足够的耐心进行学习,

More information

Microsoft Word - Hibernate与Struts2和Spring组合指导.doc

Microsoft Word - Hibernate与Struts2和Spring组合指导.doc 1.1 组合 Hibernate 与 Spring 1. 在 Eclipse 中, 新建一个 Web project 2. 给该项目增加 Hibernate 开发能力, 增加 Hibernate 相关类库到当前项目的 Build Path, 同时也提供了 hibernate.cfg.xml 这个配置文件 3. 给该项目增加 Spring 开发能力, 增加 spring 相关类库到当前项目的 Build

More information

内文-2.indd

内文-2.indd 客户端服务端音乐资源信息 : 1. 项目需求从本项目开始, 我们一起开发一个简单的在线音乐播放器, 它具有以下功能 (1) 程序启动时显示一个启动画面, 如图 1-1 所示 (2) 在程序主页面显示服务器上的歌曲列表, 包括歌手名与歌曲名, 单击列表条目可实现在线音乐播放, 单击 播放 暂停 上一曲 下一曲 按钮可实现对应的功能, 进度条可以显示歌曲播放进度, 如图 1-2 所示 图 1-1 程序启动画面

More information

RxJava

RxJava RxJava By 侦跃 & @hi 头 hi RxJava 扩展的观察者模式 处 观察者模式 Observable 发出事件 Subscriber 订阅事件 bus.post(new AnswerEvent(42)); @Subscribe public void onanswer(answerevent event) {! }! Observable observable = Observable.create(new

More information

實作SQLiteOpenHelper類別

實作SQLiteOpenHelper類別 SQLiteOpenHelper 類別存取 SQLite 建國科技大學資管系 饒瑞佶 2013/5 V1 Android 連結資料庫 MySQL SQL Server Web Service 遠端資料庫 Internet Intranet Android SQLite 單機資料庫 Android vs. SQLite 透過 SQLiteOpenHelper 類別來操作 建立資料庫 ( 建構子 ) 建立資料表

More information

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 odps-sdk 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基 开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些

More information

F515_CS_Book.book

F515_CS_Book.book /USB , ( ) / L R 1 > > > 2, / 3 L 1 > > > 2 + - 3, 4 L 1 了解显示屏上显示的图标 Wap 信箱收到一条 Wap push 信息 ( ) GSM 手机已连接到 GSM 网络 指示条越多, 接收质量越好 2 ...........................4.............................. 4 Micro SD (

More information

<android.support.v7.widget.recyclerview android:layout_width="0dp" android:layout_height="0dp" android:layout_marginbottom

<android.support.v7.widget.recyclerview android:layout_width=0dp android:layout_height=0dp android:layout_marginbottom Android 天气预报简单记录 ( 二 ) 主要内容使用 RecyclerView 显示所有城市和未来 4 天天气使用 SearchView 来实现查询基于百度地图 API 实现定位, 更新天气 ViewPager 实现介绍界面使用 RecyclerView 显示所有城市和未来 4 天天气 RecyclerView 是 support.v7 包中的控件, 和 ListView 类似, 十分的灵活,

More information

Guava学习之Resources

Guava学习之Resources Resources 提供提供操作 classpath 路径下所有资源的方法 除非另有说明, 否则类中所有方法的参数都不能为 null 虽然有些方法的参数是 URL 类型的, 但是这些方法实现通常不是以 HTTP 完成的 ; 同时这些资源也非 classpath 路径下的 下面两个函数都是根据资源的名称得到其绝对路径, 从函数里面可以看出,Resources 类中的 getresource 函数都是基于

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Java application Java main applet Web applet Runnable Thread CPU Thread 1 Thread 2 Thread 3 CUP Thread 1 Thread 2 Thread 3 ,,. (new) Thread (runnable) start( ) CPU (running) run ( ) blocked CPU sleep(

More information

Microsoft Word - AEL CH05.doc

Microsoft Word - AEL CH05.doc 5-2 AutoCompleteTextView AutoCompleteTextView 非常類似 EditText, 屬於文字輸入方塊 ; 不過 AutoCompleteTextView 會在使用者輸入幾個字時就會顯示提示文字, 方便使用者選取而無需輸入所有文字, 是一種體貼使用者輸入的設計 AutoCompleteTextView 的提示列表與 Spinner 的選項列表建立方式相同, 需要建立字串陣列來儲存欲提示的文字

More information

概述

概述 OPC Version 1.6 build 0910 KOSRDK Knight OPC Server Rapid Development Toolkits Knight Workgroup, eehoo Technology 2002-9 OPC 1...4 2 API...5 2.1...5 2.2...5 2.2.1 KOS_Init...5 2.2.2 KOS_InitB...5 2.2.3

More information

Microsoft Word - 第1章 Android基本概念.docx

Microsoft Word - 第1章 Android基本概念.docx Android 系 统 下 Java 编 程 详 解 作 者 : 华 清 远 见 第 1 章 Android 基 本 概 念 本 章 简 介 本 章 主 要 介 绍 Android 基 本 概 念 方 面 的 内 容, 包 括 Android 平 台 特 性 Android 系 统 架 构 Android 开 发 框 架 和 Android 开 发 环 境 搭 建 1.1 Android 简 介 Android

More information

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074> 程 序 设 计 实 习 INFO130048 3-2.C++ 面 向 对 象 程 序 设 计 重 载 继 承 多 态 和 聚 合 复 旦 大 学 计 算 机 科 学 与 工 程 系 彭 鑫 pengxin@fudan.edu.cn 内 容 摘 要 方 法 重 载 类 的 继 承 对 象 引 用 和 拷 贝 构 造 函 数 虚 函 数 和 多 态 性 类 的 聚 集 复 旦 大 学 计 算 机 科 学

More information

X713_CS_Book.book

X713_CS_Book.book / / /USB ) ; ; C D ; ; B B 1 >> 2 3 B 1 ( > > ) 了解显示屏上显示的图标 Wap 信箱收到一条 Wap push 信息 GSM GPS ( ) 手机已连接到 GSM 网络 指示条越多, 接收质量越好 GPS 2 ...........................4.............................. 4 Micro SD (

More information

基于ECO的UML模型驱动的数据库应用开发1.doc

基于ECO的UML模型驱动的数据库应用开发1.doc ECO UML () Object RDBMS Mapping.Net Framework Java C# RAD DataSetOleDbConnection DataGrod RAD Client/Server RAD RAD DataReader["Spell"].ToString() AObj.XXX bug sql UML OR Mapping RAD Lazy load round trip

More information

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 本章学习目标 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 配置视图解析器 @RequestMapping 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc 和 Struts2 都属于表现层的框架, 它是 Spring 框架的一部分, 我们可 以从 Spring 的整体结构中看得出来 :

More information

手说TTS开发指南

手说TTS开发指南 手说 TTS 开发指南 v1.3 2011 年 6 月 版权所有 : 手说工作室 shoushuo.com 版本时间作者说明 1.0 2010-11-15 张波 1.1 2010-12-27 在 ondestroy 方法 unbindservice 1.2 2010-12-30 1.3 2011-6-12 去掉 TTS 初始化 ; ttsservice.initialize() 方法调用添加接口方法

More information

小应用 Magic8

小应用 Magic8 胡家威 计研135班 http://hujiaweibujidao.github.io/ 小应用 Magic8 Android 系统简介 Android 应用结构 Android 四大组件 Activity 生命周期 Android 资源管理 UI 组件和容器组件 内容概要 ( 上 ) Android 系统简介 Android 市场份额 Android 是如何诞生的? Android 之父 :Andy

More information

EJB-Programming-3.PDF

EJB-Programming-3.PDF :, JBuilder EJB 2.x CMP EJB Relationships JBuilder EJB Test Client EJB EJB Seminar CMP Entity Beans Value Object Design Pattern J2EE Design Patterns Value Object Value Object Factory J2EE EJB Test Client

More information

Android 开发教程

Android 开发教程 封面 1 文件存取编程基础 文件 文件可以用来存储比使用引用更大数量的数据 Android 提供方法来读 写文件 只有本地文件可以被访问 优点 : 可以存储大容量的数据 缺点 : 文件更新或是格式改变可能会导致巨大的编程工作 文件操作 读文件 Context.openFileInput(String name) 打开一个与应用程序联系的私有文件输入流 当文件不存在时抛出 FileNotFoundException

More information

第一章 Android 简介与开发环境搭建

第一章 Android 简介与开发环境搭建 安卓开发环境与常用布局 第一章 Android 简介与开发环境搭建 本章目标 3G 的概念 Android 的改变 Android 开发环境的搭建编写第一个 Android 程序 Android 程序的目录结构 手机发展史 1. 3G 的概念 3G 全称为 :3rd Generation, 中文含义即为第三代数字通信, 是指将无线通信与国际互联网等多媒体通信结合的新一代移动通信系统 2. 符合 3G

More information

Android Android Android SDK iv

Android Android Android SDK iv Android Market Google Android SDK Apple Google Microsoft b2c b 2010 Internet Android how why iii Android 240... Android Android SDK iv Android Market Google Android SDK Visual C++ Java N-tier J2EE Unix/Linux

More information

建立Android新專案

建立Android新專案 Android 智 慧 型 手 機 程 式 設 計 Android WebService 建 國 科 技 大 學 資 管 系 饒 瑞 佶 2012/4 V1 2012/8 V2 2013/5 V3 2014/10 v4 提 醒 這 節 的 內 容 針 對 的 是 MS 的 Web Service 或 是 使 用 SOAP(Simple Object Access Protocol) 標 準 建 立

More information

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页 第 1 页共 32 页 crm Mobile V1.0 for IOS 用户手册 一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页 二 crm Mobile 界面介绍 : 第 3 页共 32 页 三 新建 (New) 功能使用说明 1 选择产品 第 4 页共 32 页 2 填写问题的简要描述和详细描述 第 5 页共

More information

拦截器(Interceptor)的学习

拦截器(Interceptor)的学习 二 拦截器 (Interceptor) 的学习 拦截器可以监听程序的一个或所有方法 拦截器对方法调用流提供了细粒度控制 可以在无状态会话 bean 有状态会话 bean 和消息驱动 bean 上使用它们 拦截器可以是同一 bean 类中的方法或是一个外部类 下面介绍如何在 Session Bean 类中使用外部拦截器类 @Interceptors 注释指定一个或多个在外部类中定义的拦截器 下面拦截器

More information

<4D6963726F736F667420576F7264202D20BBF9D3DA416E64726F6964C6BDCCA8B5C4B5E7D7D3C5C4C2F4CFB5CDB32E646F63>

<4D6963726F736F667420576F7264202D20BBF9D3DA416E64726F6964C6BDCCA8B5C4B5E7D7D3C5C4C2F4CFB5CDB32E646F63> 基 于 Android 平 台 的 电 子 拍 卖 系 统 摘 要 本 电 子 拍 卖 系 统 其 实 就 是 一 个 电 子 商 务 平 台, 只 要 将 该 系 统 部 署 到 互 联 网 上, 客 户 都 可 以 在 该 系 统 上 发 布 想 出 售 的 商 品, 也 可 以 对 拍 卖 中 的 商 品 参 与 竞 价 整 个 过 程 无 须 人 工 干 预, 由 系 统 自 动 完 成 本

More information

Microsoft Word - Broker.doc

Microsoft Word - Broker.doc Broker 模式 采用 broker 模式对分布式计算进行简单模拟 系统在一个进程内模拟分布式环境, 因此不涉及网络编程和进程间通信,Broker 通过本地函数调用的方式实现 request 和 response 的转发 采用 broker 模式对分布式计算进行简单的模拟, 要求如下 : 设计四个 server, 一个 server 接收两个整数, 求和并返回结果, 一个 server 接收两个整数,

More information

untitled

untitled 1 行 行 行 行.NET 行 行 類 來 行 行 Thread 類 行 System.Threading 來 類 Thread 類 (1) public Thread(ThreadStart start ); Name 行 IsAlive 行 行狀 Start 行 行 Suspend 行 Resume 行 行 Thread 類 (2) Sleep 行 CurrentThread 行 ThreadStart

More information

untitled

untitled 1 .NET 利 [] [] 來 說 切 切 理 [] [ ] 來 說 拉 類 類 [] [ ] 列 連 Web 行流 來 了 不 不 不 流 立 行 Page 類 Load 理 Response 類 Write 料 Redirect URL Response.Write("!! ives!!"); Response.Redirect("WebForm2.aspx"); (1) (2) Web Form

More information

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

Microsoft Word - CX1000-HMI_程序开发_PLC通讯

Microsoft Word - CX1000-HMI_程序开发_PLC通讯 用 VB.Net 开发 CX1000 的 HMI 第二部分和 TwinCAT PLC 通讯 一 TwinCAT 动态库 TwinCAT.Ads.dll The TwinCAT.Ads.dll 是一个.NET 类库, 它提供和 ADS 设备通讯的类 如果 TwinCAT PLC 运行在 IPC 上, 则需要添加的类库是路径 \TwinCAT\ADS Api\.NET\v1.1.4322 下的 TwinCAT.Ads.dll

More information

《大话设计模式》第一章

《大话设计模式》第一章 第 1 章 代 码 无 错 就 是 优? 简 单 工 厂 模 式 1.1 面 试 受 挫 小 菜 今 年 计 算 机 专 业 大 四 了, 学 了 不 少 软 件 开 发 方 面 的 东 西, 也 学 着 编 了 些 小 程 序, 踌 躇 满 志, 一 心 要 找 一 个 好 单 位 当 投 递 了 无 数 份 简 历 后, 终 于 收 到 了 一 个 单 位 的 面 试 通 知, 小 菜 欣 喜

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 第 章.1 Android UI 基本概念 用户界面 (User Interface,UI) 是用户与设备之间进行信息交流的直接媒介, 是决定用户体验最重要的部分 相比于早期的计算机的主要交互界面 批处理界面和命令行界面, 现在更为流行的是更简单直接的用户图形界面 (Graphical User Interface, GUI) GUI 简单易用, 受众面广, 直接推动了个人计算机的发展 目前, 主流大众的操作系统都采用了

More information

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0, http://debut.cis.nctu.edu.tw/~chi Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0, : POSITIVE_INFINITY NEGATIVE_INFINITY

More information

新版 明解C++入門編

新版 明解C++入門編 511!... 43, 85!=... 42 "... 118 " "... 337 " "... 8, 290 #... 71 #... 413 #define... 128, 236, 413 #endif... 412 #ifndef... 412 #if... 412 #include... 6, 337 #undef... 413 %... 23, 27 %=... 97 &... 243,

More information

使用MapReduce读取XML文件

使用MapReduce读取XML文件 使用 MapReduce 读取 XML 文件 XML( 可扩展标记语言, 英语 :extensible Markup Language, 简称 : XML) 是一种标记语言, 也是行业标准数据交换交换格式, 它很适合在系统之间进行数据存储和交换 ( 话说 Hadoop H ive 等的配置文件就是 XML 格式的 ) 本文将介绍如何使用 MapReduce 来读取 XML 文件 但是 Had oop

More information

untitled

untitled 1 Access 料 (1) 立 料 [] [] [ 料 ] 立 料 Access 料 (2) 料 [ 立 料 ] Access 料 (3) 料 料 料 料 料 料 欄 ADO.NET ADO.NET.NET Framework 類 來 料 料 料 料 料 Ex MSSQL Access Excel XML ADO.NET 連 .NET 料.NET 料 料來 類.NET Data Provider

More information

chp6.ppt

chp6.ppt Java 软 件 设 计 基 础 6. 异 常 处 理 编 程 时 会 遇 到 如 下 三 种 错 误 : 语 法 错 误 (syntax error) 没 有 遵 循 语 言 的 规 则, 出 现 语 法 格 式 上 的 错 误, 可 被 编 译 器 发 现 并 易 于 纠 正 ; 逻 辑 错 误 (logic error) 即 我 们 常 说 的 bug, 意 指 编 写 的 代 码 在 执 行

More information

epub83-1

epub83-1 C++Builder 1 C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r 1.1 1.1.1 1-1 1. 1-1 1 2. 1-1 2 A c c e s s P a r a d o x Visual FoxPro 3. / C / S 2 C + + B u i l d e r / C

More information

untitled

untitled 4.1AOP AOP Aspect-oriented programming AOP 來說 AOP 令 理 Cross-cutting concerns Aspect Weave 理 Spring AOP 來 AOP 念 4.1.1 理 AOP AOP 見 例 來 例 錄 Logging 錄 便 來 例 行 留 錄 import java.util.logging.*; public class HelloSpeaker

More information

untitled

untitled 1 LinkButton LinkButton 連 Button Text Visible Click HyperLink HyperLink 來 立 連 Text ImageUrl ( ) NavigateUrl 連 Target 連 _blank _parent frameset _search _self 連 _top 例 sample2-a1 易 連 private void Page_Load(object

More information

百度xx SDK用户手册

百度xx SDK用户手册 社会化分享 Android 组件 用户手册 (1.1.0 版 ) 发布日期 : 2013 年 5 月 10 日 百度开发者中心 ( 版权所有, 翻版必究 ) 目录 第 1 章 概述... 3 第 2 章 运行环境... 3 第 3 章 使用说明... 3 3.1 新建工程... 3 3.2 引入社会化分享 JAR 包... 4 3.3 配置 ANDROIDMANIFEST.XML... 4 3.4

More information

中 文 摘 要 智 慧 型 手 機 由 於 有 強 大 的 功 能, 以 及 優 渥 的 便 利 性, 還 能 與 網 路 保 持 隨 時 的 鏈 結 與 同 步 更 新, 因 此 深 受 廣 大 消 費 者 喜 愛, 當 然, 手 機 遊 戲 也 成 為 現 代 人 不 可 或 缺 的 娛 樂 之

中 文 摘 要 智 慧 型 手 機 由 於 有 強 大 的 功 能, 以 及 優 渥 的 便 利 性, 還 能 與 網 路 保 持 隨 時 的 鏈 結 與 同 步 更 新, 因 此 深 受 廣 大 消 費 者 喜 愛, 當 然, 手 機 遊 戲 也 成 為 現 代 人 不 可 或 缺 的 娛 樂 之 臺 北 市 大 安 高 級 工 業 職 業 學 校 資 訊 科 一 百 零 一 學 年 度 專 題 製 作 報 告 ------ 以 Android 製 作 ------ ----- 連 線 塔 防 遊 戲 ------ Tower defense game using Internet technology 班 級 : 資 訊 三 甲 組 別 : A9 組 組 員 : 葉 冠 麟 (9906129)

More information

Microsoft PowerPoint - ch6 [相容模式]

Microsoft PowerPoint - ch6 [相容模式] UiBinder wzyang@asia.edu.tw UiBinder Java GWT UiBinder XML UI i18n (widget) 1 2 UiBinder HelloWidget.ui.xml: UI HelloWidgetBinder HelloWidget.java XML UI Owner class ( Composite ) UI XML UiBinder: Owner

More information

建立Android新專案

建立Android新專案 經濟部工業局 Android 智慧型手機程式設計實務應用班 Android WebService 建國科技大學資管系 饒瑞佶 2012/4 WebService 需要 ksoap2-android-assembly-2.5.2-jar-withdependencies.jar 或 ksoap2-android-assembly-2.5.2-jar-withdependencies_timeout1.jar

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

untitled

untitled 1 Outline 料 類 說 Tang, Shih-Hsuan 2006/07/26 ~ 2006/09/02 六 PM 7:00 ~ 9:30 聯 ives.net@gmail.com www.csie.ntu.edu.tw/~r93057/aspnet134 度 C# 力 度 C# Web SQL 料 DataGrid DataList 參 ASP.NET 1.0 C# 例 ASP.NET 立

More information

JBuilder Weblogic

JBuilder Weblogic JUnit ( bliu76@yeah.net) < >6 JUnit Java Erich Gamma Kent Beck JUnit JUnit 1 JUnit 1.1 JUnit JUnit java XUnit JUnit 1.2 JUnit JUnit Erich Gamma Kent Beck Erich Gamma Kent Beck XP Extreme Programming CRC

More information

_banneradview.settest(true); _banneradview.setuserkeywords("swimming"); _banneradview.setusercategories("1,3,4"); _banneradview.setusergender(jdbanner

_banneradview.settest(true); _banneradview.setuserkeywords(swimming); _banneradview.setusercategories(1,3,4); _banneradview.setusergender(jdbanner 京东 APP 联盟 SDK Android 版接口说明文档 1.0 1. 嵌入 SDK 1.1 添加 SDK Android Studio 环境 : 菜单 New->New Module->Import.jar or.aar package, 然后选中 App 联盟 SDK 所带的 jar 文件 Eclipse+ADT 环境 : 将 App 联盟 SDK 所带的 jar 文件拷贝到 libs/ 目录下

More information

2 WF 1 T I P WF WF WF WF WF WF WF WF 2.1 WF WF WF WF WF WF

2 WF 1 T I P WF WF WF WF WF WF WF WF 2.1 WF WF WF WF WF WF Chapter 2 WF 2.1 WF 2.2 2. XAML 2. 2 WF 1 T I P WF WF WF WF WF WF WF WF 2.1 WF WF WF WF WF WF WF WF WF WF EDI API WF Visual Studio Designer 1 2.1 WF Windows Workflow Foundation 2 WF 1 WF Domain-Specific

More information

Chapter 1: Introduction

Chapter 1: Introduction 目錄 目錄 IX Part 1 擁抱 Android 單元 01 Android 造時勢或是時勢造 Android... 2 Android 從何而來... 3 Android 的功能 應用和商機... 5 先睹為快 - Android 手機和平板電腦模擬器... 7 單元 02 安裝 Android 程式開發工具... 10 不同作業系統的開發工具版本...10 安裝 Android 程式開發工具的步驟...12

More information

无类继承.key

无类继承.key 无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo aiming@gmail.com https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255

More information

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

Android + WebService

Android + WebService Android + Web Service 建國科技大學資管系饒瑞佶 2017/3 V1 呼叫 OpenData Web Service http://data.taipei/opendata/datalist/apiaccess?scope=resourceaquire& rid=e7c46724-3517-4ce5-844f-5a4404897b7d http://data.taipei/opendata/datalist/apiaccess?scope=resourceaquir

More information

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii 前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii C# 7 More Effective C# C# C# C# C# C# Common Language Runtime CLR just-in-time

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,

More information

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

KillTest 质量更高 服务更好 学习资料   半年免费更新服务 KillTest 质量更高 服务更好 学习资料 http://www.killtest.cn 半年免费更新服务 Exam : 310-055Big5 Title : Sun Certified Programmer for the Java 2 Platform.SE 5.0 Version : Demo 1 / 22 1. 11. public static void parse(string str)

More information

幻灯片 1

幻灯片 1 Delivering accurate maps to Chinese Android users 为中国安卓用户提供准确的地图服务 Work at Mapbox includes: Android apps, demos, starter kits, documentation, support, syncing Android team with other departments, etc.

More information

untitled

untitled 1 Access 料 (1) 立 料 [] [] [ 料 ] 立 料 Access 料 (2) 料 [ 立 料 ] Access 料 (3) 料 料 料 料 料 料 欄 ADO.NET ADO.NET.NET Framework 類 來 料 料 料 料 料 Ex MSSQL Access Excel XML ADO.NET 連 .NET 料.NET 料 料來 類.NET Data Provider

More information

投影片 1

投影片 1 Chapter 13 Android 實戰演練 線上匯率查詢 線上匯率查詢 本節範例將實作一個簡單的線上費率查詢, 利用 Url 查詢台灣銀行的即時匯率, 欲查詢的網址為 http://rate.bot.com.tw/pages/static/uip003.zh- TW.htm 此網頁中每隔幾分鐘會更新一次匯率, 所以範例程式在一開啟時會抓取此網頁並將網頁內容解析後將匯率資料取出 線上匯率查詢 台灣銀行線上即時匯率查詢

More information

1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6

1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6 www.brainysoft.net 1.JasperReport ireport...4 1.1 JasperReport...4 1.2 ireport...4 2....4 2.1 JDK...4 2.1.1 JDK...4 2.1.2 JDK...5 2.1.3 JDK...5 2.2 ant...6 2.2.1 ant...6 2.2.2 ant...6 2.3 JasperReport...7

More information

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6: Chapter 15. Suppressed Exception CH14 Finally Block Java SE 7 try-with-resources JVM cleanup try-with-resources JVM cleanup cleanup Java SE 7 Throwable getsuppressed Throwable[] getsuppressed() Suppressed

More information

单击以编辑母片 Content 标题样式 LinearLayout 排版模式 TableLayout 排版模式 RelativeLayout 排版模式 AbsoluteLayout 排版模式 FrameLayout 排版模式 GridLayout 排版模式 TabWidget 切換卡 Lab 5 2

单击以编辑母片 Content 标题样式 LinearLayout 排版模式 TableLayout 排版模式 RelativeLayout 排版模式 AbsoluteLayout 排版模式 FrameLayout 排版模式 GridLayout 排版模式 TabWidget 切換卡 Lab 5 2 单击以编辑母片标题样式 安卓系统 Android 的排版 授课老师 : 谢兆贤 2016/4/18 1 单击以编辑母片 Content 标题样式 LinearLayout 排版模式 TableLayout 排版模式 RelativeLayout 排版模式 AbsoluteLayout 排版模式 FrameLayout 排版模式 GridLayout 排版模式 TabWidget 切換卡 Lab 5

More information

LEFT, RIGHT // 左 // 右 (2) 当图片移动后, 按钮的坐标发生改变, 此操作通过 setloca tion() 方法实现 setlocation() 方法是从 Component 类继承的, 其定义如下 : public void setlocation(int x, int y

LEFT, RIGHT // 左 // 右 (2) 当图片移动后, 按钮的坐标发生改变, 此操作通过 setloca tion() 方法实现 setlocation() 方法是从 Component 类继承的, 其定义如下 : public void setlocation(int x, int y 拼图游戏 任务说明 本实例实现了拼图游戏的开发 运行程序, 单击 开始 按钮将打乱图片的位置, 效果如图 1 所示, 然后通过鼠标单击图片进行移动, 直到将所有图片都移动到正确位置, 游戏过关, 过关后的效果如图 2 所示 图 1 打乱图片位置的效果图 2 图片移动到正确位置的效果 关键技术 本程序主要通过 Swing 与枚举类实现, 程序将一幅完整的图片平均分成 9 部分, 每一部分为一个正方形,

More information

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2 PowerBuilder 9 PowerBuilder Native Interface(PBNI) PowerBuilder 9 PowerBuilder C++ Java PowerBuilder 9 PBNI PowerBuilder Java C++ PowerBuilder NVO / PowerBuilder C/C++ PowerBuilder 9.0 PowerBuilder Native

More information