版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
56/56目录一、前奏篇 4HYPERLINK1.设计背景 42.HYPERLINK作品简介 43.HYPERLINK设计目的与意义 44.HYPERLINK设计要求 5二、开发之UI篇 6HYPERLINK三、开发之业务篇 9四.HYPERLINK总结建议篇 451.HYPERLINK参考文献 452.附录 46一、前奏篇1设计背景得益于科技的日益进步,生活在二十一世纪的我们已然日渐依赖网络。手机不离身,不管到哪里首先问WIFI密码,似乎已经成为了大部分人根深蒂固的日常习惯了。而在社交网络的发展过程中,图形元素也曾早已有3D化的趋势。
比如任天堂的Wii主机中的卡通形象Mii,把平面的形象发展到了3D化,Wii的玩家可以虚拟社区中选择自己的发型、五官,衣服来拼凑出自己的3D形象。[2作品简介演示项目功能;1、每天会有1000-1500行代码量;这几天下来一共就会有1万多行代码量。2、大学软件工程的学生毕业要求3-5万行的代码量。10几天完成三分之一、五分之一;3、版本控制,每一天的代码用版本控制起来,可以看到每天的代码;4、演示程序代码。5、演示功能有:启动页面主页脸萌通讯卫士:(分享到微信、QQ、朋友圈、空间、新浪微博、腾讯微博、人人网、陌陌、唱吧、来往、易信上.软件管理:列出软件多有功能,启动软件、卸载软件失败进程管理:列出软件中正在运行的程序;窗口小部件:添加桌面;流量统计:模拟器并不支持,在真机上才能演示,只做个UI效果;系统优化:清楚系统的垃圾,刚开始运行,没用多余数据;3设计目的及意义这个项目的目的是以学习为中心,面向用户帮助开发者更深刻掌握开发必须具备的技术,从开发架构到测试上线,整个过程都需要自己来做,从客户端到后台服务端,并为用户提供技术支持,不断改进,增强用户体验。在当下互联网迅猛发展的浪潮下,风靡香港的拼脸应用,超多香港明星都在玩
最潮最萌的卡通画风,完全免费的拼脸软件脸萌正在崛起。4设计要求项目基本实现市面上的拼图软件,细分每个模块,每个模块的代码逻辑要清晰、独立,多借鉴安卓源码下的优秀算法,提高代码的质量,每天任务要明确,按时完成计划的任务,按时提交代码到SVN服务器,在有些地方可以导入别人框架实现快速开发,项目完成必须签名,并保管好自己的秘钥,方便下次版本更新。项目规划整个脸萌将要实现主要功能是:拼图、左右滑动、通讯管理、高级工具、进程管理、软件管理、设置,而其中的各个功能又分为几个小功能模块,各个模块之间有联系并且独立,要降低代码之间的耦合度,以便于后期维护开发模式/架构常用的开发模式:1、按照模块,组织代码的包结构。业务之间彼此独立;办公软件--开会。com.itheima.meeting--发放工资。 com.itheima.money--出差。 车载电脑--多媒体 --导航 --领航--obd模块2、按照代码的类型组织包结构;界面 com.itheima.mobilesafe.activies自定义UI com.itheima.mobilesafe.ui业务逻辑代码com.itheima.mobilesafe.engine 数据引擎业务逻辑获取解析数据持久化 com.itheima.mobilesafe.db com.itheima.mobilesafe.db.dao广播接收者com.itheima.mobilesafe.receiver长期在后台运行com.itheima.mobilesafe.service公用的api工具类com.itheima.mobilesafe.utils1、开发环境(1)操作系统:Windows7(2)数据库:SQLite(3)开发工具包:JDK1.7(4)开发平台:Eclipse(5)项目管理工具:SVN(6)文件快速查找工具:Everything(方便查找sdk系统源码文件)2、运行环境(1)服务器:Tomcat6.0(2)安卓模拟器、天语h1c手机安卓4.2.2二、开发之UI篇splash界面的作用1、用来展现产品的Logo;2、应用程序初始化的操作;3、检查应用程序的版本;4、检查当前应用程序是否合法注册;界面设计android:id="@+id/tv_splash_version"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#000000"android:textStyle="bold"android:shadowDx="1"android:shadowDy="1"android:shadowRadius="0.2"android:shadowColor="#ffff00"android:text="版本:1.0"android:textSize="16sp"android:layout_centerInParent="true"动态获取程序的版本名称的方法(请无视logo,logo、图片未来得及加工)/qinjuning/article/details/6867806/** *得到应用程序的版本号 */ publicStringgetAppVersion(){ PackageManagerpm=getPackageManager(); try{ PackageInfoinfo=pm.getPackageInfo(getPackageName(),0); returninfo.versionName; }catch(NameNotFoundExceptione){ e.printStackTrace(); //不可能发生; return""; } }连接服务器获取更新信息升级流程图到webservice里去写json文件:updata.jsonAnddroid工程添加联网权限:android.permission.INTERNET在子线程钟请求服务器代码checkVersion()。请求网络的代码URLurl=newURL(getString(R.string.serviceurl)); HttpURLConnectionconn=(HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000);参照一个解析流的类StreamTools解析JSONJSONObjectobj=newJSONObject(result);//服务器的版本号Stringversion=(String)obj.get("version");description=(String)obj.get("description");apkurl=(String)obj.get("apkurl");用Handler更新信息创建主页面HomeActivity和布局文件写延迟2秒进入主页面代码longstartTime=System.currentTimeMillis();longendTime=System.currentTimeMillis(); longdTime=endTime-startTime; if(dTime<2000){ try{ Thread.sleep(2000-dTime); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } }添加AlphaAnimation动画效果AlphaAnimationaa=newAlphaAnimation(0.3f,1.0f); findViewById(R.id.rl_root_splash).startAnimation(aa);提交代码到SVN服务器图4.3公告管理功能模块图三、开发之业务篇功能列表颜色值:#8866ff00textSize:20sp<GridViewandroid:id="@+id/gv_home_gridview"android:layout_width="match_parent"android:layout_height="match_parent"android:numColumns="3"android:verticalSpacing="15dip"/>Names:拼图、左右滑动、通讯管理、高级工具、进程管理、软件管理、设置中心01、自定义可以滚动TextView写完主页面后Button有文字滚动<Buttonandroid:focusableInTouchMode="true"android:textColor="#000000"android:layout_width="fill_parent"android:singleLine="true"android:layout_height="wrap_content"android:ellipsize="marquee"android:layout_gravity="center_horizontal"android:text="主人稍安勿躁,网络或服务器未开启,无法拉取最新信息,请先试试下面的功能吧!o(╯□╰)oo(╯□╰)o"android:textSize="16sp"/><com.itheima.mobilesafe.ui.FocusedTextViewandroid:textColor="#000000"android:layout_width="fill_parent"android:singleLine="true"android:layout_height="wrap_content"android:ellipsize="marquee"android:layout_gravity="center_horizontal"android:text="主人稍安勿躁,网络或服务器未开启,无法拉取最新信息,请先试试下面的功能吧!o(╯□╰)oo(╯□╰)o"android:textSize="16sp/>02、自动更新的组合控件准备:开启webserver服务器1、每次都升级消耗多余的流量2、在主页面增加点击事件进入设置类;3、创建SettingActivity类,并在功能清单文件配置;4、SettingActivity的布局文件,基于activity_home.xml修改;5、运行可以点击进入设置中心;6、开始写设置里的布局文件了,参照系统的设置里的“位置服务”7、布局文件<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="60dip"android:background="#FFEBCD"><TextViewandroid:id="@+id/tv_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="5dip"android:layout_marginTop="5dip"android:text="更新设置"android:textColor="#000000"android:textSize="22sp"/><TextViewandroid:id="@+id/tv_desc"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/tv_title"android:layout_marginLeft="5dip"android:text="自动升级已经关闭"android:textColor="#88000000"android:textSize="15sp"/><CheckBoxandroid:id="@+id/cb_status"android:layout_centerVertical="true"android:layout_marginRight="10dip"android:layout_alignParentRight="true"android:layout_width="wrap_content"android:layout_height="wrap_content"/><Viewandroid:layout_alignParentBottom="true"android:layout_marginLeft="5dip"android:layout_marginRight="5dip"android:background="#66000000"android:layout_width="fill_parent"android:layout_height="0.2dip"/></RelativeLayout>8、抽取出来单独类SettingItemView9、单独的布局文件setting_item_view.xml12、判断组合控件是否被选中,其实就是CheckBox的状态是否被选中;13、在SettingItemView增加isChecked()、setChecked();方法;并演示14、在SettingItemView增加setDesc()方法;并演示;16、记录选中状态,并在进入的时候读取保存的状态;17、在SplashActivity根据是否开启升级而相应的是否升级;18、延迟两秒进入主页面的代码;//停留2秒后进入主页面; handler.postDelayed(newRunnable(){ @Override publicvoidrun(){ enterHome(); } },2000);03、密码的MD5加密1、知识拓展:Root权限是linux系统的超级管理员权限;模拟器能看到data/data里的数据,是为了方便开发者没有root权限的手机是看不到data/data有root权限的符号:#没有root权限的符号:$查看config.xml命令catconfig.xml2、md5算法不可逆的:原文--》密文、用系统的API可以实现;123456密文1987密文;算法步骤:1、用每个byte去和11111111做与运算并且得到的是int类型的值:byte&11111111;把int类型转成16进制并返回String类型;不满八个二进制位就补全;publicstaticvoidmain(String[]args)throwsNoSuchAlgorithmException{ MessageDigestdigest=MessageDigest.getInstance("md5"); Stringpassword="123456"; byte[]result=digest.digest(password.getBytes()); StringBufferbuffer=newStringBuffer(); for(byteb:result){//0xff是十六进制,十进制为255 intnuber=b&0xff; Stringstr=Integer.toHexString(nuber); if(str.length()==1){ buffer.append("0"); } buffer.append(str); } //这就是MD5加密得到的值 System.out.println(buffer); }04、手机防盗设置向导的第一个界面准备:需要谷歌文档创建LostFindActivity,在HomeActivity激活并可以进入;判断是否用户设置向导,如果没有就进入设置向导;创建Setup1Activity自定义标题样式命名:text_title_style自定义文本样式text_content_style(图片名star_big_on)。小点图片(presence_online、presence_invisible)05、自定义按钮状态背景1、在android-16\data\res\values\styles.xml看一下系统定义的Button样式,看一下低版本和版本的区别2、用美图秀秀自定义按钮背景(50*50),命名:button.xml3、把做好的背景设置到设置密码对话框和输入密码对话框;06、shape形状资源前提:重新进入设置向导控件没点击效果看文档Develop/APIGuides/AppResources/Drawable/ShapeDrawable单词:corners:角;gradient:梯度;solid:固定的;stroke:边框--可以做下划线Rectangle:矩形;dash:破折号gap:间隙;3、拷贝实例代码,文件命名(gradient_box.xml)<?xmlversion="1.0"encoding="utf-8"?><shapexmlns:android="/apk/res/android"android:shape="rectangle"><cornersandroid:radius="5dip"/><gradientandroid:startColor="#ff0000"android:endColor="#00ff0000"/><solidandroid:color="#ffffff"/><strokeandroid:width="3dip"android:color="#000000"android:dashGap="5dip"android:dashWidth="5dip"/></shape>4、默认状态gradient_box.xml<?xmlversion="1.0"encoding="utf-8"?><shapexmlns:android="/apk/res/android"android:shape="rectangle"><cornersandroid:radius="5dip"/><solidandroid:color="#ffffff"/></shape>5、按下去状态状态gradient_box_press.xml<?xmlversion="1.0"encoding="utf-8"?><shapexmlns:android="/apk/res/android"android:shape="rectangle"><cornersandroid:radius="5dip"/><solidandroid:color="#22000000"/></shape>把两个状态整合在shape_bg.xml07、设置向导页面的切换动画1、下一步动画位移动画解释-100%pp:代表父窗体,100%:代表整个窗体,-:代码向左移动;tran_out.xml<?xmlversion="1.0"encoding="utf-8"?><translatexmlns:android="/apk/res/android"android:fromXDelta="100%p"android:toXDelta="0"android:duration="500"android:fromYDelta="0"android:toYDelta="0"></translate>Tran_in.xml<?xmlversion="1.0"encoding="utf-8"?><translatexmlns:android="/apk/res/android"android:fromXDelta="0"android:toXDelta="-100%p"android:duration="500"android:fromYDelta="0"android:toYDelta="0"></translate>2、使用动画:overridePendingTransition(R.anim.tran_in,R.anim.tran_out);上一步动画(旋转动画)rotate_out.xm;<?xmlversion="1.0"encoding="utf-8"?><rotatexmlns:android="/apk/res/android"android:fromDegrees="90"android:toDegrees="0"android:duration="500"android:pivotX="0"android:pivotY="0"></rotate>rotate_in.xm<?xmlversion="1.0"encoding="utf-8"?><rotatexmlns:android="/apk/res/android"android:fromDegrees="0"android:toDegrees="-90"android:duration="500"android:pivotX="0"android:pivotY="0"></rotate>使用动画:overridePendingTransition(R.anim.rotate_in,R.anim.rotate_out);08、绑定SDcard脸萌最核心的就是绑定各种通讯软件;读取SDcard的串口号代码:<!--在SDCard中创建与删除文件权限-->
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!--往SDCard写入数据权限-->
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>siv_setup2_bindsim.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ if(siv_setup2_bindsim.isChecked()){ Editoreditor=sp.edit(); editor.putString("sim",null); mit(); siv_setup2_bindsim.setChecked(false); }else{ //得到SiM卡的串口号 Stringsim=tm.getSimSerialNumber(); Editoreditor=sp.edit(); editor.putString("sim",sim); mit(); siv_setup2_bindsim.setChecked(true); } } });TelephonyManager加权限<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>记录串口号;在基类BaseSetupActivtiy初始化共享偏好;用命令查看数据是否设置成功;在Setup2Activity演示super.onCreate()的作用09、检查手机是否更换SDcard原理:1、SDcard插入一般会拔掉电源,会导致开启重启;2、侧面卡槽也会导致手机重启--重启通讯模块;创建新包com.itheima.mobilesafe.receiver和新类(BootCompleteReceiver)功能清单文件:<receiverandroid:name="com.itheima.mobilesafe.receiver.BootCompleteReceiver"><intent-filter><actionandroid:name="ent.action.BOOT_COMPLETED"/></intent-filter></receiver>2、权限<uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED"/>接收信息publicclassBootCompleteReceiverextendsBroadcastReceiver{ privateSharedPreferencessp; privateTelephonyManagertm; @Override publicvoidonReceive(Contextcontext,Intentintent){ //检查当前的手机sim,读取原来绑定的sim卡,如果发现两个卡不一样,说明手机可能被盗。需要偷偷的发短信报警; sp=context.getSharedPreferences("config",context.MODE_PRIVATE); Stringbindsim=sp.getString("sim","")+"a"; tm=(TelephonyManager)context.getSystemService(context.TELEPHONY_SERVICE); Stringrealsim=tm.getSimSerialNumber(); if(bindsim.equals(realsim)){ //手机卡没有变更,就是你的手机和你的卡; }else{ //sim卡变更了,发送报警信息; System.out.println("sim卡变更了,发送报警信息"); } }}读取手机联系人authorities:到开发环境data/data/目录下viders.contacts/databases/导出到左面contacts2.db用工具打开数据库关心三张表:raw_contacts、data、mimetypes创建一个新的工程去读取联系人SelectContact创建一个得到所有联系人的方法getContactInfos();表的路径List<Map<String,String>>data=newArrayList<Map<String,String>>();ContentResolverresolver=getContentResolver(); Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Uridatauri=Uri.parse("content://com.android.contacts/data");查询raw_contact表取联系人idCursorcursor=resolver.query(uri,newString[]{"contact_id"}, null,null,null);得到联系人的IDwhile(cursor.moveToNext()){ Stringid=cursor.getString(0); System.out.println("联系人的id为:"+id);}查表data表到联系人的姓名和电话号码Map<String,String>map=newHashMap<String,String>();//查询data表把当前联系人的姓名和电话newString[]{"data1","mimetype"}数据给取出来. CursordataCursor=resolver.query(datauri,newString[]{"data1","mimetype"}, "raw_contact_id=?",newString[]{id},null);添加数据到map集合 Stringdata1=dataCursor.getString(0); Stringmimetype=dataCursor.getString(1); if("vnd.android.cursor.item/phone_v2".equals(mimetype)){ System.out.println("电话:"+data1); map.put("phone",data1); }elseif("vnd.android.cursor.item/name".equals(mimetype)){ System.out.println("姓名:"+data1); map.put("name",data1); }读取联系人需要加权限<uses-permissionandroid:name="android.permission.READ_CONTACTS"/>短信指令的广播接收者<receiverandroid:name="com.itheima.mobilesafe.receiver.SmsReceiver"><intent-filterandroid:priority="1000"><actionandroid:name="vider.Telephony.SMS_RECEIVED"/></intent-filter></receiver>配置权限:<uses-permissionandroid:name="android.permission.RECEIVE_SMS"/>代码 Object[]objs=(Object[])intent.getExtras().get("pdus"); for(Objectobj:objs){ SmsMessagesmsMessage=SmsMessage.createFromPdu((byte[])obj);// Stringsender=smsMessage.getOriginatingAddress(); Stringbody=smsMessage.getMessageBody(); if("#*location*#".equals(body)){ //获得手机位置地址 Log.e(TAG,"获得手机位置地址"); abortBroadcast(); }elseif("#*alarm*#".equals(body)){ //手机报警 Log.e(TAG,"手机报警"); abortBroadcast(); }elseif("#*lockscreen*#".equals(body)){ //远程锁屏 Log.e(TAG,"远程锁屏"); abortBroadcast(); }elseif("#*wipedata*#".equals(body)){ //清除手机数据 Log.e(TAG,"清楚数据"); abortBroadcast(); } } 12、播放报警音乐1、创建raw目录拷贝需要用的音乐文件代码:MediaPlayermediaPlayer=MediaPlayer.create(context,R.raw.11); mediaPlayer.setVolume(1.0f,1.0f); mediaPlayer.setLooping(false); mediaPlayer.start(); abortBroadcast();13、代码实现获取手机位置1、创建服务GPSServiceCriteriacriteria=newCriteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); Stringprovider=lm.getBestProvider(criteria,true); lm.requestLocationUpdates(provider,0,0,listener);设置参数细化:criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);//对电量的要求发短信代码Intentgpsintent=newIntent(context,GPSService.class); context.startService(gpsintent); SharedPreferencessp=context.getSharedPreferences("config",Context.MODE_PRIVATE); Stringlastlocation=sp.getString("lastlocation",null); if(TextUtils.isEmpty(lastlocation)){ SmsManager.getDefault().sendTextMessage(sender,null,"locationgetting...",null,null); }else{ SmsManager.getDefault().sendTextMessage(sender,null,lastlocation,null,null); }14、号码归属地查询的UI创建AtoolsActivity类并写布局文件;(ic_menu_camera)<TextViewandroid:background="@drawable/button"android:clickable="true"android:onClick="numberAddressQuery"android:textColor="#000000"android:drawableLeft="@android:drawable/ic_menu_camera"android:textSize="18sp"android:text="电话归属地查询"android:gravity="center_vertical"android:layout_width="match_parent"android:layout_height="wrap_content"/>创建具体查询类NumberAddressActivity并在功能清单文件注册NumberAddressActivity的布局文件并写查询的基本框架,把输入框得到的号码打印出来。15、号码归属地查询的原理号码归属地查询几种做法:第一种:联网查询;第二种:把数据库放在本地;本程序使用的是最新小米数据库并且对其进行优化:address.db去重SQL语句:selectarea,city,cardtypefrominfogroupbyarea,city,cardtype号码归属地的查询实现并且实现了动态查询效果:vibrator=(Vibrator)getSystemService(VIBRATOR_SERVICE); et_phone.addTextChangedListener(newTextWatcher(){ @Override publicvoidonTextChanged(CharSequences,intstart,intbefore,intcount){ if(s.length()>=3){ Stringaddress=NumberAddressQueryUtils.queryNumber(s.toString()); tv_result.setText(address); return; } tv_result.setText(""); } @Override publicvoidbeforeTextChanged(CharSequences,intstart,intcount, intafter){ } @Override publicvoidafterTextChanged(Editables){ } });把数据库拷贝到assets目录并创建包com.itheima.mobilesafe.db.dao包创建该类file:///android_aset/address.db这种无法访问知识回顾:WebView还可以加载图片Stringstr="file:///android_asset/icon.png";AddressDao实现getAddress()方法;publicstaticStringgetAddress(Stringnumber){ //把address.db拷贝到我们的/data/data/包名/files/address.db Stringaddress=number; SQLiteDatabasedatabase= SQLiteDatabase.openDatabase(path,null,SQLiteDatabase.OPEN_READONLY); Cursorcursor=database.rawQuery("selectlocationfromdata2whereid=(selectoutkeyfromdata1whereid=?)", newString[]{number.substring(0,7)}); if(cursor.moveToNext()){ address=cursor.getString(0); } cursor.close(); database.close(); returnaddress; }在SplashActivit页面做从Assets目录拷贝到data/data/com.itheima.moblesafe/files/address.db数据库的代码;privatevoidcopyDB(){ try{ Filefile=newFile(getFilesDir(),"address.db"); if(file.exists()&&file.length()>0){ Log.e(TAG,"数据库文件只需要拷贝一下,如果拷贝了,不需要重新拷贝了"); }else{ //数据库文件只需要拷贝一下,如果拷贝了,不需要重新拷贝了。 AssetManageram=getAssets(); InputStreamis=am.open("address.db"); //创建一个文件/data/data/包名/files/address.db FileOutputStreamfos=newFileOutputStream(file); byte[]buffer=newbyte[1024]; intlen=0; while((len=is.read(buffer))!=-1){ fos.write(buffer,0,len); } is.close(); fos.close(); } }catch(IOExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } }手机号码:我国使用的手机号码为11位,其中各段有不同的编码方向:前3位———网络识别号;第4-7位———地区编码;第8-11位———用户号码。手机号码正则表达式:^1[3458]\\d{9}$publicclassAddressDao{ PrivatestaticStringpath="/data/data/com.itheima.mobilesafe/files/address.db"; publicstaticStringgetAddress(Stringnumber){ //拷贝到到/data/data/包名/files/address.db Stringaddress=number; SQLiteDatabasedb=SQLiteDatabase.openDatabase(path,null,SQLiteDatabase.OPEN_READONLY); //手机号码11位,开头13x、14x、15x、18x; //手机电话号码 if(number.matches("^1[3458]\\d{9}$")){ Cursorcursor=db.rawQuery("selectlocationfromdata2whereid=(selectoutkeyfromdata1whereid=?)", newString[]{number.substring(0,7)}); if(cursor.moveToNext()){ address=cursor.getString(0); } }else{ //119、110 switch(number.length()){ case3: address="特殊号码"; break; case4://5556 address="模拟器"; break; case5: address="客服电话"; break; case7: address="本地电话"; break; case8: address="本地电话"; break; default: if(number.length()>10&&number.startsWith("0")){ //01012345678 Cursorcursor=db.rawQuery("selectlocationfromdata2wherearea=?", newString[]{number.substring(1,3)}); if(cursor.moveToNext()){ Stringlocation=cursor.getString(0); address=location.substring(0,location.length()-2); } cursor.close(); cursor=db.rawQuery("selectlocationfromdata2wherearea=?", newString[]{number.substring(1,4)}); if(cursor.moveToNext()){ Stringlocation=cursor.getString(0); address=location.substring(0,location.length()-2); } cursor.close(); } break; } } returnaddress; }}17、来电号码归属地的显示引入:1、演示打进电话,说明系统的拨号不能改。2、展示土司;创建后台监听来电服务AddressService并在功能清单文件注册;检查是否有权限:<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>在AddressService服务里面注册来电状态(TelephoneManager)tm.listen(listener,PhoneStateListener.LISTEN_CALL_STATE);自定义监听类MyPhoneStateListenerprivateclassMyPhoneStateListenerextendsPhoneStateListener{ /** *当呼叫状态发生改变的时候回调该方法 */ @Override publicvoidonCallStateChanged(intstate,StringincomingNumber){ super.onCallStateChanged(state,incomingNumber); switch(state){ caseTelephonyManager.CALL_STATE_RINGING: Stringaddress=AddressDao.getAddress(incomingNumber); Toast.makeText(getApplicationContext(),address,1).show() break; default: break; } } }取消监听:tm.listen(listener,PhoneStateListener.LISTEN_NONE); listener=null;在SettingActivity设置中心里配置设置,当点击开启的时候就启动服务,否则相反。然后演示;布局文件:<com.itheima.mobilesafe.ui.SettingItemViewandroid:id="@+id/siv_show_address"itheima:title="设置号码归属地显示"itheima:desc_on="号码归属地显示已经打开"itheima:desc_off="号码归属地显示已经关闭"android:layout_width="match_parent"android:layout_height="wrap_content"/>SettingActivity里的代码://设置号码归属地显示 siv_show_address=(SettingItemView)findViewById(R.id.siv_show_address); showAddressIntent=newIntent(this,AddressService.class); siv_show_address.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ if(siv_show_address.isCheck()){ siv_show_address.setCheck(false); stopService(showAddressIntent); //sp共享偏好去保存 }else{ startService(showAddressIntent); siv_show_address.setCheck(true); } } });创建一个类ServiceStatusUtils里面的方法isServiceRunning()校验检查一个服务是否开启;/** *检验一个服务是否还运行,系统所有的 */ publicstaticbooleanisServiceRunning(Contextcontext,StringserviceName){ ActivityManageram=(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); List<RunningServiceInfo>infos=am.getRunningServices(100); for(RunningServiceInfoinfo:infos){ StringclassName=info.service.getClassName(); if(className.equals(serviceName)){ returntrue; } } returnfalse; }18、去电号码归属地的显示创建广播接收者OutCallReceiver并注册;监听电话打出去的广播,需要意图;<receiverandroid:name="com.itheima.mobilesafe.receiver.OutCallReceiver"><intent-filter><actionandroid:name="ent.action.NEW_OUTGOING_CALL"></action></intent-filter></receiver>需要监听具体意图和权限;<uses-permissionandroid:name="android.permission.PROCESS_OUTGOING_CALLS"/>具体代码实现publicclassOutCallReceiverextendsBroadcastReceiver{ privatestaticfinalStringTAG="OutCallReceiver"; @Override publicvoidonReceive(Contextcontext,Intentintent){ Log.e(TAG,"有电话打出去"); Stringphone=getResultData(); Stringaddress=AddressDao.getAddress(phone); Toast.makeText(context,address,0).show(); }}代码注册广播接收者receiver=newOutCallReceiver();IntentFilterfilter=newIntentFilter();filter.addAction("ent.action.NEW_OUTGOING_CALL")registerReceiver(receiver,filter);onDestroy()://代码取消注册一个广播接收者unregisterReceiver(receiver);receiver=null;自定义土司显示归属地实现代码privateWindowManagerwm;publicvoidshowMyToast(Stringaddress){ view=newTextView(this); view.setTextSize(20); view.setTextColor(Color.RED); view.setText(address); WindowManager.LayoutParamsparams=newWindowManager.LayoutParams(); params.height=WindowManager.LayoutParams.WRAP_CONTENT;params.width=WindowManager.LayoutParams.WRAP_CONTENT;params.flags=WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;params.format=PixelFormat.TRANSLUCENT;params.type=WindowManager.LayoutParams.TYPE_TOAST; wm.addView(view,params); }4、处理电话挂断情形caseTelephonyManager.CALL_STATE_IDLE: if(view!=null){ wm.removeView(view); view=null; } break;5、并且为来去电归属地窗口实现了拖拽功能 //为土司注册一个触摸监听器 view.setOnTouchListener(newOnTouchListener(){ privateintstartX; privateintstartY; @Override publicbooleanonTouch(Viewv,MotionEventevent){ switch(event.getAction()){ caseMotionEvent.ACTION_DOWN://按下 startX=(int)event.getRawX(); startY=(int)event.getRawY(); break; caseMotionEvent.ACTION_MOVE://移动 intnewX=(int)event.getRawX(); intnewY=(int)event.getRawY(); intdx=newX-startX; intdy=newY-startY;黑名单拦截用ListView显示数据,在数据加载前为不可见,用进度条给用户友好提示,增强用户体验,并且在加载数据时使用分批加载数据,防止ANR异常程序崩溃<FrameLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"><LinearLayoutandroid:visibility="gone"android:id="@+id/ll_loding"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="center"android:orientation="vertical"><ProgressBarandroid:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="正在加载数据请稍等..."/></LinearLayout><ListViewandroid:id="@+id/lv_callsms_safe"android:layout_width="fill_parent"android:layout_height="fill_parent"/></FrameLayout>黑名单拦截电话功能:、黑名单数据库创建:创建一个数据库帮助类和一个DAO业务类实现增删改查:publicBlackNumberDBOpenHelper(Contextcontext){ super(context,"blacknumber.db",null,1); } //初始化数据库的表结构 @Override publicvoidonCreate(SQLiteDatabasedb){ db.execSQL("createtableblacknumber(_idintegerprimarykeyautoincrement,numbervarchar(20),modevarchar(2))"); }创建服务,在服务里写一个内部广播监听来电绑定广播的生命周期:privateclassMylistenerextendsPhoneStateListener{ @Override publicvoidonCallStateChanged(intstate,StringincomingNumber){ //TODOAuto-generatedmethodstub super.onCallStateChanged(state,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 正负开方术的课程设计
- 文案创作训练课程设计
- 机械原理课程设计示例
- 2024至2030年制板机项目投资价值分析报告
- 2025至2030年中国胶清胶行业投资前景及策略咨询研究报告
- 2025至2030年中国玄驹补肾酒行业投资前景及策略咨询研究报告
- 2025至2030年中国模糊控制角缝清理机行业投资前景及策略咨询研究报告
- 支架套机械加工课程设计
- 幼儿教师面试课程设计
- 2024年制冷剂回收充注机项目可行性研究报告
- 历史人教部编版八年级(上册)22.抗日战争的胜利课件(25张)2024版新教材
- 2024年新北师大版七年级上册数学课件 第六章 6.2 第2课时 样本的选取
- 15《搭船的鸟》(教学设计)2024-2025学年统编版语文三年级上册
- 2024至2030年中国传染病医院产业发展动态及未来前景展望报告
- 知识点填空练习-2024-2025学年统编版道德与法治七年级上册
- 学习使用显微镜 2024-2025学年七年级上册生物同步课件(人教版2024)
- 护理疑难病例讨论课件模板
- 中国近现代史纲要智慧树知到答案2024年北京师范大学等跨校共建
- 别墅群施工组织设计
- JGJ7-2010 空间网格结构技术规程
- 建筑工程代付款协议书
评论
0/150
提交评论