• <em id="6vhwh"><rt id="6vhwh"></rt></em>

    <style id="6vhwh"></style>

    <style id="6vhwh"></style>
    1. <style id="6vhwh"></style>
        <sub id="6vhwh"><p id="6vhwh"></p></sub>
        <p id="6vhwh"></p>
          1. 国产亚洲欧洲av综合一区二区三区 ,色爱综合另类图片av,亚洲av免费成人在线,久久热在线视频精品视频,成在人线av无码免费,国产精品一区二区久久毛片,亚洲精品成人片在线观看精品字幕 ,久久亚洲精品成人av秋霞

            radiogroup(radiogroup什么意思)

            更新時(shí)間:2023-03-01 12:55:22 閱讀: 評(píng)論:0

            來(lái)電短信黑名單攔截演示手機(jī)衛(wèi)士相關(guān)功能創(chuàng)建BlackNumberActivity布局文件

            <RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:background="#8866ff00" ><TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:text="黑名單管理" android:textColor="#000" android:textSize="22sp" /><Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="5dp" android:text="添加" />數(shù)據(jù)庫(kù)創(chuàng)建public class BlackNumberOpenHelper extends SQLiteOpenHelper {

            public BlackNumberOpenHelper(Context ctx) { super(ctx, "blacknumber.db", null, 1);//必須實(shí)現(xiàn)該構(gòu)造方法 } /** * 第一次創(chuàng)建數(shù)據(jù)庫(kù) */ @Override public void onCreate(SQLiteDataba db) { // 創(chuàng)建表, 三個(gè)字段,_id, number(電話號(hào)碼),mode(攔截模式:電話,短信,電話+短信) db.execSQL("create table blacknumber (_id integer primary key autoincrement, number varchar(20), mode integer)"); } /** * 數(shù)據(jù)庫(kù)升級(jí) */ @Override public void onUpgrade(SQLiteDataba db, int oldVersion, int newVersion) { }}單元測(cè)試創(chuàng)建具備單元測(cè)試的Android項(xiàng)目, 拷貝清單文件的相關(guān)代碼File->New->Project->Android Test Project

            <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.itheima.mobilesafeteach" /> <application> <us-library android:name="android.test.runner" /> </application>增刪改查(crud)邏輯實(shí)現(xiàn)

            public class BlackNumberDao { private static BlackNumberDao sInstance; private BlackNumberOpenHelper mHelper; private BlackNumberDao(Context ctx) { mHelper = new BlackNumberOpenHelper(ctx); }; /** * 獲取單例對(duì)象 * @param ctx * @return */ public static BlackNumberDao getInstance(Context ctx) { if (sInstance == null) { synchronized (BlackNumberDao.class) { if (sInstance == null) { sInstance = new BlackNumberDao(ctx); } } } return sInstance; } /** * 增加黑名單 * @param number * @param mode */ public void add(String number, int mode) { SQLiteDataba db = mHelper.getWritableDataba(); ContentValues values = new ContentValues(); values.put("number", number); values.put("mode", mode); db.inrt("blacknumber", null, values); db.clo(); } /** * 刪除黑名單 * @param number */ public void delete(String number) { SQLiteDataba db = mHelper.getWritableDataba(); db.delete("blacknumber", "number=?", new String[] { number }); db.clo(); } /** * 更新黑名單 * @param number * @param mode */ public void update(String number, int mode) { SQLiteDataba db = mHelper.getWritableDataba(); ContentValues values = new ContentValues(); values.put("mode", mode); db.update("blacknumber", values, "number=?", new String[] { number }); db.clo(); } /** * 查找黑名單 * @param number * @return */ public boolean find(String number) { SQLiteDataba db = mHelper.getWritableDataba(); Cursor cursor = db.query("blacknumber", new String[] { "number", "mode" }, "number=?", new String[] { number }, null, null, null); boolean result = fal; if (cursor.moveToFirst()) { result = true; } cursor.clo(); db.clo(); return result; } /** * 查找號(hào)碼攔截模式 * @param number * @return */ public int findMode(String number) { SQLiteDataba db = mHelper.getWritableDataba(); Cursor cursor = db.query("blacknumber", new String[] { "mode" }, "number=?", new String[] { number }, null, null, null); int mode = -1; if (cursor.moveToFirst()) { mode = cursor.getInt(0); } cursor.clo(); db.clo(); return mode; } /** * 查找黑名單列表 * @return */ public ArrayList<BlackNumberInfo> findAll() { SQLiteDataba db = mHelper.getWritableDataba(); Cursor cursor = db .query("blacknumber", new String[] { "number", "mode" }, null, null, null, null, null); ArrayList<BlackNumberInfo> list = new ArrayList<BlackNumberDao.BlackNumberInfo>(); while (cursor.moveToNext()) { String number = cursor.getString(0); int mode = cursor.getInt(1); BlackNumberInfo info = new BlackNumberInfo(); info.number = number; info.mode = mode; list.add(info); } cursor.clo(); db.clo(); return list; } /** * 黑名單對(duì)象 * @author Kevin * */ public class BlackNumberInfo { public String number; public int mode; @Override public String toString() { return "BlackNumberInfo [number=" + number + ", mode=" + mode + "]"; } }}增刪改查單元測(cè)試

            public class TestBlackNumberDao extends AndroidTestCa { /** * 測(cè)試數(shù)據(jù)創(chuàng)建 */ public void testCreateDb() { BlackNumberOpenHelper helper = new BlackNumberOpenHelper(getContext()); helper.getWritableDataba(); } /** * 測(cè)試增加黑名單 */ public void testAdd() { //添加100個(gè)號(hào)碼,攔截模式隨機(jī) Random random = new Random(); for (int i = 0; i < 100; i++) { int mode = random.nextInt(3) + 1; if (i < 10) { BlackNumberDao.getInstance(getContext()).add("1381234560" + i, mode); } el { BlackNumberDao.getInstance(getContext()).add("138123456" + i, mode); } } } /** * 測(cè)試刪除黑名單 */ public void testDelete() { BlackNumberDao.getInstance(getContext()).delete("13812345601"); } /** * 測(cè)試更新黑名單 */ public void testUpdate() { BlackNumberDao.getInstance(getContext()).update("13812345600", 2); } /** * 測(cè)試查找黑名單 */ public void testFind() { boolean find = BlackNumberDao.getInstance(getContext()).find( "13812345600"); asrtEquals(true, find); } /** * 測(cè)試查找黑名單攔截模式 */ public void testFindMode() { int mode = BlackNumberDao.getInstance(getContext()).findMode( "13812345600"); System.out.println("攔截模式:" + mode); }}使用命令行查看數(shù)據(jù)庫(kù)文件

            1. 運(yùn)行adb shell進(jìn)入linux環(huán)境2. 切換至data/data/包名/databas3. 運(yùn)行sqlite3 *.db,進(jìn)入數(shù)據(jù)庫(kù)4. 編寫sql語(yǔ)句,進(jìn)行相關(guān)操作.記得加分號(hào)(;)結(jié)束5. .quit退出sqlite,切換到adb shell介紹convertView的重用機(jī)制和ViewHolder的使用方法

            //使用static修飾內(nèi)部類,系統(tǒng)只加載一份字節(jié)碼文件,節(jié)省內(nèi)存static class ViewHolder { public TextView tvNumber; public TextView tvMode;}使用convertView和ViewHolder進(jìn)行優(yōu)化之后,重新使用traceview計(jì)算getView的執(zhí)行時(shí)間,進(jìn)行對(duì)比最終優(yōu)化結(jié)果

            @Overridepublic View getView(int position, View convertView, ViewGroup parent) { View view = null; ViewHolder holder = null; if (convertView == null) { view = View.inflate(BlackNumberActivity.this, R.layout.list_black_number_item, null); System.out.println("listview創(chuàng)建"); // viewHolder類似一個(gè)容器,可以保存findViewById獲得的view對(duì)象 holder = new ViewHolder(); holder.tvNumber = (TextView) view.findViewById(R.id.tv_number); holder.tvMode = (TextView) view.findViewById(R.id.tv_mode); // 將viewHolder設(shè)置給view對(duì)象,保存起來(lái) view.tTag(holder); } el { view = convertView; holder = (ViewHolder) view.getTag();// 從view對(duì)象中得到之前設(shè)置好的viewHolder System.out.println("listview重用了"); } BlackNumberInfo info = mBlackNumberList.get(position); holder.tvNumber.tText(info.number); switch (info.mode) { ca 1: holder.tvMode.tText("攔截電話"); break; ca 2: holder.tvMode.tText("攔截短信"); break; ca 3: holder.tvMode.tText("攔截電話+短信"); break; } return view;}static class ViewHolder { public TextView tvNumber; public TextView tvMode;}啟動(dòng)子線程在數(shù)據(jù)庫(kù)讀取數(shù)據(jù)

            當(dāng)數(shù)據(jù)量比較大時(shí),讀取數(shù)據(jù)比較耗時(shí),為了避免ANR,最好將該邏輯放在子線程中進(jìn)行, 為了模擬數(shù)據(jù)量大時(shí)訪問(wèn)比較慢的情況,可以讓線程休眠1-2秒后再加載數(shù)據(jù)

            加載中的進(jìn)度條展示數(shù)據(jù)分批加載

            分批加載優(yōu)勢(shì):避免一次性加載過(guò)多內(nèi)容, 節(jié)省時(shí)間和流量sql語(yǔ)句: lect * from blacknumber limit 20 offt 0, 表示起始位置是0,加載條數(shù)為20, 等同于limit 0,20/** * 分頁(yè)查找黑名單列表 * * @return */public ArrayList<BlackNumberInfo> findPart(int startIndex) { SQLiteDataba db = mHelper.getWritableDataba(); Cursor cursor = db.rawQuery( "lect number,mode from blacknumber order by _id desc limit 20 offt ?", new String[] { String.valueOf(startIndex) }); ArrayList<BlackNumberInfo> list = new ArrayList<BlackNumberDao.BlackNumberInfo>(); while (cursor.moveToNext()) { String number = cursor.getString(0); int mode = cursor.getInt(1); BlackNumberInfo info = new BlackNumberInfo(); info.number = number; info.mode = mode; list.add(info); } cursor.clo(); db.clo(); return list;}/** * 獲取黑名單數(shù)量 * * @return */public int getTotalCount() { SQLiteDataba db = mHelper.getWritableDataba(); Cursor cursor = db.rawQuery("lect count(*) from blacknumber", null); int count = 0; if (cursor.moveToNext()) { count = cursor.getInt(0); } cursor.clo(); db.clo(); return count;}--------------------------------------//監(jiān)聽listview的滑動(dòng)事件lvList.tOnScrollListener(new OnScrollListener() {// 滑動(dòng)狀態(tài)發(fā)生變化// 1.靜止->滾動(dòng) 2.滾動(dòng)->靜止 3.慣性滑動(dòng)@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == SCROLL_STATE_IDLE) { //獲取當(dāng)前l(fā)istview顯示的最后一個(gè)item的位置 int lastVisiblePosition = lvList.getLastVisiblePosition(); //判斷是否應(yīng)該加載下一頁(yè) if (lastVisiblePosition >= mBlackNumberList.size() - 1 && !isLoading) { int totalCount = BlackNumberDao.getInstance( BlackNumberActivity.this).getTotalCount(); //判斷是否已經(jīng)到達(dá)最后一頁(yè) if (mStartIndex >= totalCount) { Toast.makeText(BlackNumberActivity.this, "沒(méi)有更多數(shù)據(jù)了", Toast.LENGTH_SHORT).show(); return; } Toast.makeText(BlackNumberActivity.this, "加載更多數(shù)據(jù)...", Toast.LENGTH_SHORT).show(); System.out.println("加載更多數(shù)據(jù)..."); initData(); } }}-----------------------------------//加載數(shù)據(jù)private void initData() { pbLoading.tVisibility(View.VISIBLE);//顯示進(jìn)度條 isLoading = true; new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // 第一頁(yè)數(shù)據(jù) if (mBlackNumberList == null) { mBlackNumberList = BlackNumberDao.getInstance( BlackNumberActivity.this).findPart(mStartIndex); } el { mBlackNumberList.addAll(BlackNumberDao.getInstance( BlackNumberActivity.this).findPart(mStartIndex)); } mHandler.ndEmptyMessage(0); } }.start();}-----------------------------------private int mStartIndex;//下一頁(yè)的起始位置private boolean isLoading;// 表示是否正在加載private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { pbLoading.tVisibility(View.GONE);//隱藏進(jìn)度條 // 第一頁(yè)數(shù)據(jù) if (mAdapter == null) { mAdapter = new BlackNumberAdapter(); lvList.tAdapter(mAdapter); } el { mAdapter.notifyDataSetChanged();//刷新adapter } mStartIndex = mBlackNumberList.size(); isLoading = fal; };};添加黑名單

            /** * 添加黑名單 * * @param view */public void addBlackNumber(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(this); View view = View.inflate(this, R.layout.dialog_add_black_number, null); final AlertDialog dialog = builder.create(); dialog.tView(view, 0, 0, 0, 0); final EditText etBlackNumber = (EditText) view .findViewById(R.id.et_black_number); final RadioGroup rgMode = (RadioGroup) view.findViewById(R.id.rg_mode); Button btnOK = (Button) view.findViewById(R.id.btn_ok); Button btnCancel = (Button) view.findViewById(R.id.btn_cancel); btnOK.tOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String number = etBlackNumber.getText().toString().trim(); if (!TextUtils.isEmpty(number)) { int checkedRadioButtonId = rgMode.getCheckedRadioButtonId(); int mode = 1; // 根據(jù)當(dāng)前選中的RadioButtonId來(lái)判斷是哪種攔截模式 switch (checkedRadioButtonId) { ca R.id.rb_call: mode = 1; break; ca R.id.rb_sms: mode = 2; break; ca R.id.rb_all: mode = 3; break; default: break; } // 保存數(shù)據(jù)庫(kù) BlackNumberDao.getInstance(getApplicationContext()).add( number, mode); // 向列表第一個(gè)位置增加黑名單對(duì)象,并刷新listview //注意: 分頁(yè)查詢時(shí)需要逆序排列,保證后添加的最新數(shù)據(jù)展示在最前面 BlackNumberInfo info = new BlackNumberInfo(); info.number = number; info.mode = mode; mBlackNumberList.add(0, info); mAdapter.notifyDataSetChanged(); dialog.dismiss(); } el { Toast.makeText(getApplicationContext(), "輸入內(nèi)容不能為空!", Toast.LENGTH_SHORT).show(); } } }); btnCancel.tOnClickListener(new OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); dialog.show();}刪除黑名單

            holder.ivDelete.tOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //從數(shù)據(jù)庫(kù)中刪除 BlackNumberDao.getInstance(getApplicationContext()).delete( info.number); //從內(nèi)存列表中刪除并刷新listview mBlackNumberList.remove(info); mAdapter.notifyDataSetChanged(); }});創(chuàng)建黑名單攔截服務(wù)攔截短信邏輯實(shí)現(xiàn)

            邏輯類似手機(jī)防盜頁(yè)面攔截特殊短信指令的代碼, 只不過(guò)該廣播是動(dòng)態(tài)注冊(cè),不是靜態(tài)注冊(cè). 動(dòng)態(tài)注冊(cè)的好處是可以隨服務(wù)的開啟或關(guān)閉來(lái)決定是否監(jiān)聽廣播,而且在同等優(yōu)先級(jí)的前提下,動(dòng)態(tài)注冊(cè)的廣播比靜態(tài)注冊(cè)的更先接收到廣播(可以通過(guò)打印日志進(jìn)行驗(yàn)證)

            設(shè)置頁(yè)面增加黑名單攔截開關(guān)

            通過(guò)此開關(guān)來(lái)開啟和關(guān)閉服務(wù), 邏輯類似來(lái)電歸屬地顯示的開關(guān)

            來(lái)電攔截

            1. 掛斷電話的API早期版本endCall()是可以使用的,現(xiàn)在不可以用了;但本身掛斷電話這個(gè)功能是存在的

            2. 很多服務(wù)都是獲取遠(yuǎn)程服務(wù)的代理對(duì)象IBinder,再調(diào)用里面的方法的.例如:

            IBinder b = ServiceManager.getService(ALARM_SERVICE);

            IAlarmManager rvice = IAlarmManager.Stub.asInterface(b);

            return new AlarmManager(rvice);

            3. 于是我們跟蹤TelephoneyManager,查看它的對(duì)象到底是如何創(chuàng)建的.我們跟蹤到了這樣一個(gè)方法:

            private ITelephony getITelephony() {

            return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));

            }

            該方法返回一個(gè)ITelephony對(duì)象, 查看ITelephony對(duì)象的方法,發(fā)現(xiàn)有endCall方法

            4. 于是我們將獲取ITelephony的代碼拷貝到自己的項(xiàng)目中,發(fā)現(xiàn)無(wú)法導(dǎo)包,因?yàn)楦居袥](méi)有ServiceManager這個(gè)類,但我們知道它肯定存在,因?yàn)門elephonyManager就引用了該類,只不過(guò)android系統(tǒng)隱藏了這個(gè)類,

            5. 為了調(diào)用隱藏類的方法,我們想到了反射

            通過(guò)反射獲取endCall方法

            /** * 掛斷電話 * 注意加權(quán)限: <us-permission * android:name="android.permission.CALL_PHONE"/> */public void endCall() { try { // 獲取ServiceManager Class clazz = BlackNumberService.class.getClassLoader().loadClass( "android.os.ServiceManager"); Method method = clazz.getDeclaredMethod("getService", String.class);// 獲取方法getService IBinder binder = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE);// 方法時(shí)靜態(tài)的,不需要傳遞對(duì)象進(jìn)去 ITelephony telephony = ITelephony.Stub.asInterface(binder);// 獲取ITelephony對(duì)象,前提是要先配置好aidl文件 telephony.endCall();//掛斷電話 } catch (Exception e) { e.printStackTrace(); }}注意加權(quán)限: <us-permission android:name="android.permission.CALL_PHONE"/>

            本文發(fā)布于:2023-02-28 19:58:00,感謝您對(duì)本站的認(rèn)可!

            本文鏈接:http://www.newhan.cn/zhishi/a/167764652272924.html

            版權(quán)聲明:本站內(nèi)容均來(lái)自互聯(lián)網(wǎng),僅供演示用,請(qǐng)勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。

            本文word下載地址:radiogroup(radiogroup什么意思).doc

            本文 PDF 下載地址:radiogroup(radiogroup什么意思).pdf

            標(biāo)簽:什么意思   radiogroup
            相關(guān)文章
            留言與評(píng)論(共有 0 條評(píng)論)
               
            驗(yàn)證碼:
            Copyright ?2019-2022 Comsenz Inc.Powered by ? 實(shí)用文體寫作網(wǎng)旗下知識(shí)大全大全欄目是一個(gè)全百科類寶庫(kù)! 優(yōu)秀范文|法律文書|專利查詢|
            主站蜘蛛池模板: 亚洲精品自拍在线视频| 免费无码又爽又刺激高潮的app| 国产精品视频中文字幕| 久久av色欲av久久蜜桃网| 亚洲香蕉伊综合在人在线| 亚洲国产精品久久久天堂麻豆宅男 | 蜜桃视频在线免费观看一区二区| 国产精品中文第一字幕| 久久国产V一级毛多内射| 成人午夜无人区一区二区| 亚洲免费人成网站在线观看| 日本第一区二区三区视频| 久久亚洲2019中文字幕| 午夜性做爰电影| 国产精品一码在线播放| 国产无套乱子伦精彩是白视频| 国产午夜精品福利在线观看| 黄页网址大全免费观看| 视频一区视频二区视频三| 欧美区一区二区三区| 亚洲精品国产av天美传媒| 亚洲 制服 丝袜 无码| 成人无码无遮挡很H在线播放| 国产成人av电影在线观看第一页| 久久九九有精品国产23百花影院| 精品激情视频一区二区三区| 精品无码国产一区二区三区AV| 精品无码一区在线观看| 少女韩国在线观看完整版免费| 国产一码二码三码区别| 亚洲男人AV天堂午夜在| 国产suv精品一区二区四| 狠狠色噜噜狠狠狠狠777米奇| 94人妻少妇偷人精品| 九九热在线观看精品视频| 亚洲另类国产欧美一区二区| 久久亚洲国产精品五月天| 国产超碰无码最新上传| 国产果冻豆传媒麻婆精东| 国产成人精品午夜二三区| 韩国三级+mp4|