日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手机卫士-05

發(fā)布時間:2024/1/1 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手机卫士-05 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

手機(jī)衛(wèi)士-05

課1

模仿網(wǎng)易新聞下拉加載分頁數(shù)據(jù)listView

在activtiycallsafe.xml里重新修改(去掉原來的button)

activtiycallsafe.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content" ><TextViewstyle="@style/textview_title_style"android:layout_height="60dp"android:gravity="center"android:text="通訊衛(wèi)士" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:onClick="addBlackNumber"android:text="添加" /></RelativeLayout><!-- android:fastScrollEnabled="true" 設(shè)置快速滑動 --><FrameLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="10" ><LinearLayoutandroid:id="@+id/ll_loading"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"android:visibility="invisible" ><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/list_view"android:layout_width="match_parent"android:layout_height="match_parent"android:divider="@drawable/list_devider"android:fastScrollEnabled="true" /></FrameLayout></LinearLayout>

在CallSafeActivity.class里重新修改

list_view.setOnScrollListener//初始化listview的滾動監(jiān)聽 在方法里有分別識別(慣性滑動、當(dāng)滾動然后停下來閑置的時候、在觸摸屏幕的時候調(diào)用方法)的操作 現(xiàn)在目的是下拉滑動的數(shù)據(jù)到20條截止就再請求數(shù)據(jù)庫獲取數(shù)據(jù) 在case OnScrollListener.SCROLLSTATEIDLE里進(jìn)行操作

CallSafeActivity.class

list_view.setOnScrollListener(new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {switch (scrollState) {// 慣性滑動case OnScrollListener.SCROLL_STATE_FLING:break;// 當(dāng)滾動然后停下來閑置的時候case OnScrollListener.SCROLL_STATE_IDLE:// 最后一個顯示可見的位置int lastVisiblePosition = list_view.getLastVisiblePosition();System.out.println("lastVisiblePosition----->"+ lastVisiblePosition);if (lastVisiblePosition == lists.size() - 1) {startIndex += pageCount;if (startIndex > countTotal) {Toast.makeText(CallSafeActivity.this,"沒有更多的數(shù)據(jù)進(jìn)行加載了", 0).show();return;}}initData();break;// 在觸摸屏幕的時候調(diào)用的方法case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:break;}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// TODO Auto-generated method stub}});

在BlackNumberDao里繼續(xù)加功能(分批加載數(shù)據(jù))

CallSafeActivity.class里使用分批加載數(shù)據(jù)的方法(首先定義好startIndex、pageCount初始化了)

CallSafeActivity.class

/*** 從第0條數(shù)據(jù)進(jìn)行加載*/ private int startIndex = 0; /*** 每頁最多的加載數(shù)據(jù)*/ private int pageCount = 20; 調(diào)用lists = dao.findPage2() BlackNumberDao.java/*** 分批加載數(shù)據(jù)* * @param startIndex* 開始數(shù)據(jù)的條目* @param pageCount* 每頁最多加載多少條數(shù)據(jù)* @return 返回一個黑名單的集合數(shù)據(jù)*/ public List<BlackNumberInfo> findPage2(int startIndex, int pageCount) {SQLiteDatabase db = helper.getReadableDatabase();Cursor cursor = db.rawQuery("select number,mode from blackinfo order by _id desc limit ? offset ?",new String[] { String.valueOf(pageCount),String.valueOf(startIndex) });// 初始化黑名單的集合ArrayList<BlackNumberInfo> lists = new ArrayList<BlackNumberInfo>();while (cursor.moveToNext()) {BlackNumberInfo info = new BlackNumberInfo();info.setMode(cursor.getString(1));info.setNumber(cursor.getString(0));lists.add(info);}cursor.close();db.close();return lists; }

但是這樣做加載后就把之前的給覆蓋了 解決小bug,在使用lists = dao.findPage2()的時候加個判斷,如果lists!=null,就再lists里追加加載后的數(shù)據(jù)。

CallSafeActivity.class

// 當(dāng)滾動然后停下來閑置的時候 case OnScrollListener.SCROLL_STATE_IDLE:// 最后一個顯示可見的位置int lastVisiblePosition = list_view.getLastVisiblePosition();System.out.println("lastVisiblePosition----->"+ lastVisiblePosition);if (lastVisiblePosition == lists.size() - 1) {startIndex += pageCount;if (startIndex > countTotal) {Toast.makeText(CallSafeActivity.this,"沒有更多的數(shù)據(jù)進(jìn)行加載了", 0).show();return;}}initData();break;

繼續(xù)解決小bug,由于每次都追加后都new一個新的adapter,所以在new一個適配器時需要進(jìn)行判斷,如果已經(jīng)有適配器時,就使用刷新界面的適配器方法notifyDataSetChanged

CallSafeActivity.class

//判斷當(dāng)前的結(jié)果值是否添加成功 boolean result = dao.add(phone, mode);if(result){if(adapter == null){CallSafeAdapter adapter = new CallSafeAdapter(CallSafeActivity.this, lists);list_view.setAdapter(adapter);}else{adapter.notifyDataSetChanged();}}

繼續(xù)實(shí)現(xiàn)黑名單里的刪除圖片的刪除功能 在getView里添加圖片控件,并讓holder去管理

itemcallsafe.xml

<ImageView android:id="@+id/iv_delete"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/delet_selector"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:layout_marginRight="10dp"/>

ViewHolder的詳解(減低ListView里工作)

holder用來管理ListView里的GetView所綁定的xml文件里的控件 簡單來說就是通過在下面 private class ViewHolder { TextView tvnumber; TextView tvmode; ImageView iv_delete; } ViewHolder里管理的控件變量,當(dāng)在獲取getView要綁定的xml資源到View view時,通過在綁定后把holder里管理的變量通過該view去findViewById獲取對象并添加一個標(biāo)記view.setTag(holder);,那么每次getView時就可以實(shí)現(xiàn)不用重復(fù)再重復(fù)的去findViewById獲取對象,這就可以節(jié)省手機(jī)的cpu處理資源,大大減低ListView的效率

在設(shè)置的點(diǎn)擊事件里進(jìn)行操作集合移除的操作

但是如果不使用adapter的刷新方法,那么也看不出馬上被刪除的效果,解決這個小bug

CallSafeActivity.class

private class ViewHolder {TextView tv_number;TextView tv_mode;ImageView iv_delete; }private class CallSafeAdapter extendsMyBaseAdapter<BlackNumberInfo, ListView> {private View view;private ViewHolder holder;//private BlackNumberInfo info;public CallSafeAdapter(CallSafeActivity callSafeActivity,List<BlackNumberInfo> lists) {super(lists, callSafeActivity);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {view = View.inflate(context, R.layout.item_call_safe, null);holder = new ViewHolder();holder.tv_number = (TextView) view.findViewById(R.id.tv_number);holder.tv_mode = (TextView) view.findViewById(R.id.tv_mode);holder.iv_delete = (ImageView) view.findViewById(R.id.iv_delete);// 添加一個標(biāo)記view.setTag(holder);} else {view = convertView;holder = (ViewHolder) view.getTag();}final BlackNumberInfo info = lists.get(position);System.out.println("---------------------"+info.getNumber());//給imageview設(shè)置刪除點(diǎn)擊事件holder.iv_delete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubString blackNumber = info.getNumber();//刪除黑名單電話號碼boolean result = dao.delete(blackNumber);//從集合里面移除黑名單電話號碼lists.remove(info);if(result){adapter.notifyDataSetChanged();}}});


課2

繼續(xù)在黑名單里加上添加黑名單按鈕的功能 在activitycallsafe.xml增加按鈕控件

activitycallsafe.xml

<Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:onClick="addBlackNumber"android:text="添加" />

在CallSafeActivity.java里為按鈕方法添加一個對話框

CallSafeActivity.java

/*** 添加黑名單電話號碼* @param view*/ public void addBlackNumber(View view){AlertDialog.Builder builder = new Builder(this);View dialogview = View.inflate(CallSafeActivity.this, R.layout.dialog_add_black_number, null);final EditText et_phone = (EditText) dialogview.findViewById(R.id.et_phone);final CheckBox cb_phone = (CheckBox) dialogview.findViewById(R.id.cb_phone);final CheckBox cb_sms = (CheckBox) dialogview.findViewById(R.id.cb_sms);//取消dialogview.findViewById(R.id.bt_cancel).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubdialog.dismiss();}});//確定dialogview.findViewById(R.id.bt_ok).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String mode = "0";String phone = et_phone.getText().toString().trim();//判斷當(dāng)前的電話號碼是否有值if(TextUtils.isEmpty(phone)){Toast.makeText(CallSafeActivity.this, "請輸入電話號碼", 0).show();return ;}/*** 攔截模式 1 全部攔截 2 短信攔截 3 電話攔截*/if(cb_phone.isChecked() && cb_sms.isChecked()){mode = "1";}else if(cb_phone.isChecked()){mode = "3";}else if(cb_sms.isChecked()){mode = "2";}else{Toast.makeText(CallSafeActivity.this, "請勾選攔截模式", 0).show();return;}BlackNumberInfo info = new BlackNumberInfo();info.setMode(mode);info.setNumber(phone);lists.add(0,info);//判斷當(dāng)前的結(jié)果值是否添加成功boolean result = dao.add(phone, mode);if(result){if(adapter == null){CallSafeAdapter adapter = new CallSafeAdapter(CallSafeActivity.this, lists);list_view.setAdapter(adapter);}else{adapter.notifyDataSetChanged();}}dialog.dismiss();}});builder.setView(dialogview);dialog = builder.show(); }

實(shí)現(xiàn)對話框的布局dialogaddblack_number.xml

dialogaddblack_number.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:layout_width="match_parent"android:layout_height="40dp"android:background="#5500ff00"android:gravity="center"android:text="黑名單電話號碼添加"android:textSize="24sp" /><EditTextandroid:id="@+id/et_phone"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="請輸入電話號碼"android:inputType="phone" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><CheckBoxandroid:id="@+id/cb_phone"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="電話攔截" /><CheckBoxandroid:id="@+id/cb_sms"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="短信攔截" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Buttonandroid:id="@+id/bt_ok"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@drawable/btn_selector"android:text="確定" /><Buttonandroid:id="@+id/bt_cancel"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:background="@drawable/btn_selector"android:text="取消" /></LinearLayout></LinearLayout>


設(shè)計完畢后就繼續(xù)注入dialogView去使用。

CallSafeActivity.java

AlertDialog.Builder builder = new Builder(this);View dialogview = View.inflate(CallSafeActivity.this, R.layout.dialog_add_black_number, null);final EditText et_phone = (EditText) dialogview.findViewById(R.id.et_phone);final CheckBox cb_phone = (CheckBox) dialogview.findViewById(R.id.cb_phone);final CheckBox cb_sms = (CheckBox) dialogview.findViewById(R.id.cb_sms);

(技巧)我們可以設(shè)置dialog里面的一個方法setCanceledOnTouchOutside(true);的一個方法去鎖定提示框

AlertDialog dialog = builder.show(); dialog.setCanceledOnTouchOutside(true);

主要邏輯是對話框里的確定按鈕響應(yīng)事件

1、拿到EditText里的內(nèi)容 2、判斷checkBox是否有勾上 3、操作賦值 4、更新適配器

CallSafeActivity.java

//確定 dialogview.findViewById(R.id.bt_ok).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String mode = "0";String phone = et_phone.getText().toString().trim();//判斷當(dāng)前的電話號碼是否有值if(TextUtils.isEmpty(phone)){Toast.makeText(CallSafeActivity.this, "請輸入電話號碼", 0).show();return ;}/*** 攔截模式 1 全部攔截 2 短信攔截 3 電話攔截*/if(cb_phone.isChecked() && cb_sms.isChecked()){mode = "1";}else if(cb_phone.isChecked()){mode = "3";}else if(cb_sms.isChecked()){mode = "2";}else{Toast.makeText(CallSafeActivity.this, "請勾選攔截模式", 0).show();return;}BlackNumberInfo info = new BlackNumberInfo();info.setMode(mode);info.setNumber(phone);lists.add(0,info);//判斷當(dāng)前的結(jié)果值是否添加成功boolean result = dao.add(phone, mode);if(result){if(adapter == null){CallSafeAdapter adapter = new CallSafeAdapter(CallSafeActivity.this, lists);list_view.setAdapter(adapter);}else{adapter.notifyDataSetChanged();}}dialog.dismiss();} });

bug,如果添加的話,它會加載到lists的最后,解決lists.add(position,xxx); 解決了上一個bug之后,發(fā)現(xiàn)關(guān)掉該頁面后再打開,lists還是按順序展示,所以我們需要修改dao層里的數(shù)據(jù)庫的sql

BlackNumberDao.java

public List<BlackNumberInfo> findPage2(int startIndex, int pageCount) {SQLiteDatabase db = helper.getReadableDatabase();Cursor cursor = db.rawQuery("select number,mode from blackinfo order by _id desc limit ? offset ?",new String[] { String.valueOf(pageCount),String.valueOf(startIndex) });


真正實(shí)現(xiàn)電話和信息攔截的功能 首先實(shí)現(xiàn)電話攔截 短信攔截:在清單文件里已經(jīng)實(shí)現(xiàn)過了(靜態(tài)注冊過了) 今天實(shí)現(xiàn)短信攔截的動態(tài)注冊

在之前學(xué)過activitysettingcenter.xml里添加二維碼的布局

activitysettingcenter.xml

<TextViewandroid:layout_width="match_parent"android:layout_height="40dp"android:background="@drawable/list_selector"android:clickable="true"android:enabled="true"android:focusable="true"android:onClick="about"android:text="關(guān)于我們"android:textSize="24sp" /><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@drawable/list_devider" /><TextViewandroid:layout_width="match_parent"android:layout_height="40dp"android:background="@drawable/list_selector"android:clickable="true"android:enabled="true"android:focusable="true"android:text="掃一掃"android:textSize="24sp" /><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@drawable/list_devider" />


二維碼實(shí)現(xiàn) 顏色選擇器添加:在value里新建color.xml--->然后在新建的listselector.xml來調(diào)用,然后再在關(guān)于的TextView里調(diào)用 activityabount.xml--->ImageView 里加上一個網(wǎng)上下載的二維碼圖片在abountActivity.class注入,然后通過SettingCenterActivity.java里的關(guān)于(點(diǎn)擊時加上選擇器)跳到abountActivity.class里 并在SettingCenterActivity.java里實(shí)現(xiàn)二維碼功能--->調(diào)到處理二維碼的類:abountActivity.class

AboutActivity.java

public class AboutActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_about);} }

清單文件加上activity節(jié)點(diǎn)

<!-- 關(guān)于 --> <activityandroid:name="com.itheima.mobile47.AboutActivity"android:screenOrientation="portrait" > </activity>

布置布局文件activity_abount.xml--->ImageView

activity_about.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:textSize="24sp"android:background="#ff0000"android:text="關(guān)于" /><ImageViewandroid:layout_width="200dp"android:layout_height="200dp"android:layout_centerInParent="true"android:background="@drawable/qrcode" /></RelativeLayout>


課3

繼續(xù)在xx實(shí)現(xiàn)掃一掃的功能 zxing的githut里下載二維碼的開源代碼 移植到項目中 然后通過順藤摸瓜去找到項目如何把鏈接顯示在照片上,然后找到首頁面,首頁面所支持的TextView,然后在TextView要setText時找到大致的地方去截取要set的地址值,然后進(jìn)行處理

繼續(xù)在activitysettingcenter.xml設(shè)置中心布局里實(shí)現(xiàn)黑名單攔截功能打開


在SettingCenterActivity.java里加上響應(yīng)事件里增加功能 使用服務(wù)實(shí)現(xiàn)功能 新建黑名單攔截服務(wù):CallSafeService.java

四大組件配置清單文件(服務(wù))

true:開啟服務(wù)、false:關(guān)閉服務(wù),在手機(jī)本地的應(yīng)用服務(wù)里查看沒加功能的服務(wù)開啟沒

SettingCenterActivity.java

@Override protected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_setting_center);intent = new Intent(this,CallSafeService.class);//黑名單設(shè)置setting_view_black.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(setting_view_black.isChecked()){setting_view_black.setChecked(false);stopService(intent);}else{setting_view_black.setChecked(true);startService(intent);}}});

繼續(xù)實(shí)現(xiàn)服務(wù)功能CallSafeService.java 過濾器是廣播的一種實(shí)現(xiàn)receiver節(jié)點(diǎn)里的action節(jié)點(diǎn) 在CallSafeService.java動態(tài)注冊短信的廣播,然后在filter里設(shè)置setPriority,在然后就registerReceiver

CallSafeService.java

public class CallSafeService extends Service {private BlackNumberDao dao; private TelephonyManager tm;@Override public IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null; }@Override public void onCreate() {// TODO Auto-generated method stubsuper.onCreate();// 獲取到黑名單的數(shù)據(jù)dao = new BlackNumberDao(this);// 獲取到電話相關(guān)的服務(wù)tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);// 初始化電話狀態(tài)的監(jiān)聽MyPhoneStateListener listener = new MyPhoneStateListener();tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);// 初始化內(nèi)部攔截短信的廣播InnerSmsReceiver receiver = new InnerSmsReceiver();// 初始化一個短信攔截的actionIntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");filter.setPriority(Integer.MAX_VALUE);// 注冊短信的廣播registerReceiver(receiver, filter); }

在內(nèi)部類InnerSmsReceiver實(shí)現(xiàn)短信攔截的功能

CallSafeService.java

private class InnerSmsReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 獲取到短信Object[] objs = (Object[]) intent.getExtras().get("pdus");for (Object obj : objs) {SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);// 獲取到短信的電話號碼String number = smsMessage.getOriginatingAddress();// 獲取到短信的內(nèi)容String body = smsMessage.getMessageBody();// 獲取到攔截模式String mode = dao.findNumberMode(number);// 如果是全部攔截或者是短信攔截。那么就全部攔截下來if (mode.equals("1") || mode.equals("2")) {System.out.println("攔截下來了");abortBroadcast();}// 智能攔截if (body.contains("fapiao")) {System.out.println("垃圾短信攔截下來了");abortBroadcast();}}}}

在onCreate里操作dao通過電話號碼獲取攔截模式,然后給內(nèi)部類

String mode = dao.findNumberMode(number); // 如果是全部攔截或者是短信攔截。那么就全部攔截下來 if (mode.equals("1") || mode.equals("2")) {System.out.println("攔截下來了");abortBroadcast(); }

InnerSmsReceiver實(shí)現(xiàn)短信攔截的功能abortBroadcast(),我們可以把短信服務(wù)理解為一個有序廣播,然后我們通過條件定位到手機(jī)號,當(dāng)服務(wù)一促發(fā)就查詢dao,當(dāng)對比有該號碼就攔截abortBroadcast()。 該服務(wù)打開時繼續(xù)設(shè)置一個方法攔截一些垃圾短信,只要短信body包含了一些我們自己我想見到信息內(nèi)容,就abortBroadcast(),上下文的方法

繼續(xù)在CallSafeService實(shí)現(xiàn)電話號碼攔截

使用getSystemService(TelephonyManager)獲得電話服務(wù),然后繼續(xù)實(shí)現(xiàn),這是之前學(xué)習(xí)服務(wù)時候?qū)W習(xí)過的電話竊聽的一個例子 在電話不同的狀態(tài)下進(jìn)行攔截操作。(在手機(jī)鈴響時就使用dao查詢攔截的模式,從而進(jìn)行分類攔截)

課4

繼續(xù)實(shí)現(xiàn)攔截短信中結(jié)束電話的方法(在TelephonyManager查看源碼):CallSafeService.class TelephonyManager里的getService是關(guān)于服務(wù)的知識,回憶起老師當(dāng)時的調(diào)用遠(yuǎn)程服務(wù)的例子 掛掉電話的方法(觀察源碼后想到的方法) endcall()://使用反射的方法獲得類 然后再獲取方法,然后獲取到ibunder遠(yuǎn)程服務(wù)(getService) 把遠(yuǎn)程服務(wù)的aidl拿過來 放在和該aidl一樣的包名里(打開aidl里查看包名) 最后調(diào)用遠(yuǎn)程服務(wù),把ibunder傳進(jìn)去,最后調(diào)用endcall()系統(tǒng)遠(yuǎn)程服務(wù)來掛斷電話 課下回憶老師教我們遠(yuǎn)程服務(wù)的實(shí)例對比今天的課的內(nèi)容 解決小bug,在設(shè)置中心關(guān)閉服務(wù),但是后臺服務(wù)卻沒有關(guān),如何控制呢?把開關(guān)標(biāo)記存在sp不合適,因?yàn)樵趹?yīng)用設(shè)置處清除數(shù)據(jù)后sp沒了,但是服務(wù)卻依然在跑。 新建類ServiceIsRunning.java,該util類用來判斷服務(wù)是否開啟、 使用ActivityManager來判斷正在運(yùn)行的一些服務(wù)am.getRunningServices(50) 把傳進(jìn)來的服務(wù)名字和系統(tǒng)獲得的服務(wù)名字做對比,如果名字相同,就進(jìn)行關(guān)閉操作,然后設(shè)置中心SettingCenterActivity.class就使用該工具類來進(jìn)行開關(guān)服務(wù)操作onstart();

CallSafeService.java

@Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); // 獲取到黑名單的數(shù)據(jù) dao = new BlackNumberDao(this);// 獲取到電話相關(guān)的服務(wù)tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);// 初始化電話狀態(tài)的監(jiān)聽MyPhoneStateListener listener = new MyPhoneStateListener();tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);// 初始化內(nèi)部攔截短信的廣播InnerSmsReceiver receiver = new InnerSmsReceiver();// 初始化一個短信攔截的actionIntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");filter.setPriority(Integer.MAX_VALUE);// 注冊短信的廣播registerReceiver(receiver, filter); }private class MyPhoneStateListener extends PhoneStateListener {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {// 閑置狀態(tài)case TelephonyManager.CALL_STATE_IDLE:break;// 響鈴狀態(tài)case TelephonyManager.CALL_STATE_RINGING:String mode = dao.findNumberMode(incomingNumber);if(mode.equals("1")||mode.equals("3")){System.out.println("電話攔截");//掛斷電話endcall();}break;// 通話狀態(tài)case TelephonyManager.CALL_STATE_OFFHOOK:break;}super.onCallStateChanged(state, incomingNumber);}} /** * 掛掉電話 */ public void endcall() {try {//使用類加載器去加載一個類Class<?> clazz = getClassLoader().loadClass("android.os.ServiceManager");//獲取到方法/*** 第一個參數(shù)是名字* 第二個參數(shù)是類型*/Method method = clazz.getDeclaredMethod("getService", String.class);//實(shí)現(xiàn)調(diào)用這個方法//第一個參數(shù):如果是靜態(tài)的那么就是設(shè)置為nullIBinder iBinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE);//通過IBinder對象獲取到ITelephonyITelephony iTelephony = ITelephony.Stub.asInterface(iBinder);//掛斷電話iTelephony.endCall();} catch (Exception e) {e.printStackTrace();}}

課5

實(shí)現(xiàn)號碼歸屬地查詢 在高級工具里設(shè)計case 7 新建ToolsActivity.java 布局activity_tools.xml

activity_tools.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewstyle="@style/textview_title_style"android:gravity="center"android:text="高級工具" /><TextViewandroid:onClick="queryLocation"android:layout_width="match_parent"android:layout_height="wrap_content"android:drawableLeft="@android:drawable/star_big_off"android:textSize="24sp"android:clickable="true"android:focusable="true"android:enabled="true"android:background="@drawable/list_selector"android:text="歸屬地查詢" /></LinearLayout>

ToolsActivity.java

public class ToolsActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_tools);}/*** 歸屬地查詢* @param view*/public void queryLocation(View view){Intent intent = new Intent(this,QueryLocationActivity.class);startActivity(intent);} }


回到ToolsActivity.java實(shí)現(xiàn)號碼歸屬地查詢:queryLocation--->方法跳到下一個號碼歸屬地查詢的Activity:新建QueryLocationActivity+布局文件activityquerylocation.xml

activityquerylocation.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/main_title_bg"android:gravity="center"android:text="號碼歸屬地查詢"android:textColor="#fff"android:textSize="24sp" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="輸入你要查詢的電話號碼"android:textSize="20sp" /><EditTextandroid:id="@+id/et_number"android:layout_width="match_parent"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/tv_address"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="20sp"android:text="歸屬地信息" /><Button android:onClick="btQuery"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="點(diǎn)擊查詢"/></LinearLayout>

QueryLocationActivity.java

public class QueryLocationActivity extends Activity {@ViewInject(R.id.et_number)private EditText et_number;@ViewInject(R.id.tv_address)private TextView tv_address;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_query_location);ViewUtils.inject(this);}/*** 點(diǎn)擊查詢歸屬地* * @param view*/public void btQuery(View view) {String number = et_number.getText().toString().trim();if(TextUtils.isEmpty(number)){Toast.makeText(QueryLocationActivity.this, "請輸入查詢號碼", 0).show();}else{LocationDao dao = new LocationDao();String address = dao.getLocation(number);tv_address.setText("地理位置號碼歸屬地 : " +address);}} }


實(shí)現(xiàn)點(diǎn)擊查詢歸屬地的功能btQuery(查詢數(shù)據(jù)庫) 觀察金山手機(jī)衛(wèi)士發(fā)現(xiàn),清空該app的數(shù)據(jù)后,重新打開時會自動導(dǎo)入之前的數(shù)據(jù)庫 因此我們也模擬該app的導(dǎo)入數(shù)據(jù)庫模式導(dǎo)入,即在打開首頁時就導(dǎo)入進(jìn)來 先把數(shù)據(jù)庫放入到assets目錄下 在SplashActivity里加上拷貝數(shù)據(jù)庫方法copyDB,用來初始化數(shù)據(jù)庫 把a(bǔ)sset里的文件流拷貝到data/data下 考慮到如果拷貝的數(shù)據(jù)比較大,所以使用子線程來作拷貝操作 這里使用線程池來執(zhí)行線程操作

SplashActivity.java

@Override protected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);// 設(shè)置沒有標(biāo)題 必須寫到setcontview前面requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_splash);ViewUtils.inject(this);// ImageView image_view = (ImageView) findViewById(R.id.image_view);// image_view.setBackgroundResource(R.drawable.ic_launcher);// 獲取到包的管理者。PackageManager pm = getPackageManager();try {// 拷貝數(shù)據(jù)庫到data/data目錄下面copyDB("address.db");

SplashActivity.java

/*** 拷貝數(shù)據(jù)庫* * @param dbName* 數(shù)據(jù)庫的名字*/ private void copyDB(String dbName) {ExecutorService executorService = Executors.newFixedThreadPool(1);TaskRunnable taskRunnable = new TaskRunnable(dbName);executorService.execute(taskRunnable);}private class TaskRunnable implements Runnable {private String dbName = null;public TaskRunnable(String dbName) {this.dbName = dbName;}@Overridepublic void run() {try {InputStream is = getAssets().open(dbName);// 獲取到一個輸出流.// 第一個參數(shù)是數(shù)據(jù)庫的名字。第二個參數(shù)是模式。設(shè)置是私有的FileOutputStream fos = openFileOutput(dbName, 0);byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1) {fos.write(buffer, 0, len);}is.close();fos.close();} catch (Exception e) {e.printStackTrace();}} }

繼續(xù)實(shí)現(xiàn)號碼歸屬地查詢,QueryLocationActivity中的btQuery 在edittext里進(jìn)行輸入號碼,然后進(jìn)行與數(shù)據(jù)庫查詢比較 新建一個為號碼歸屬地查詢的dao--->getLocation(返回地理位置)

LocationDao.java

public class LocationDao {/*** 返回地理位置* * @param number* 查詢的電話號碼* @return*/public String getLocation(String number) {String location = "";// 獲取到Database// 第一個參數(shù)是數(shù)據(jù)庫的路徑,第二個參數(shù)是工廠默認(rèn)不要。第三個參數(shù)是標(biāo)記。設(shè)置只讀SQLiteDatabase db = SQLiteDatabase.openDatabase("/data/data/com.itheima.mobile47/files/address.db", null,SQLiteDatabase.OPEN_READONLY);Cursor cursor = db.rawQuery("select location from data2 where id =( select outkey from data1 where id = ?) ",new String[] { number.substring(0, 7) });if(cursor.moveToNext()){location = cursor.getString(0);}return location;} }

(新技巧)在getLocation里獲取數(shù)據(jù)庫的代碼是SQLiteDatabase db = SQLiteDatabase.openDatabase("/data/data/com.itheima.mobile47/files/address.db",null,SQLiteDatabase.READONLY); 拿到了db后,繼續(xù)實(shí)現(xiàn)查詢方法。需要做聯(lián)表查詢 1、select outkey from data1 where id = 1300020 得到id = 3 2、select location from data2 where id = 3 得到結(jié)果

課下對比一下以前使用數(shù)據(jù)庫的方式和這節(jié)課的方式的方式的不同:

那是因?yàn)橐郧拔覀兡菢幼鍪菫榱讼葎?chuàng)建一個數(shù)據(jù)庫,而現(xiàn)在的是數(shù)據(jù)庫已經(jīng)存在,所以直接拿到數(shù)據(jù)庫的對象

返回location 回到QueryLocationActivity.class,在btQuery里把location設(shè)置到控件TextView里

QueryLocationActivity.java

/*** 點(diǎn)擊查詢歸屬地* * @param view*/ public void btQuery(View view) {String number = et_number.getText().toString().trim();if(TextUtils.isEmpty(number)){Toast.makeText(QueryLocationActivity.this, "請輸入查詢號碼", 0).show();}else{LocationDao dao = new LocationDao();String address = dao.getLocation(number);tv_address.setText("地理位置號碼歸屬地 : " +address);}}

技巧小結(jié)

如何讓TextView實(shí)現(xiàn)可點(diǎn)擊化:在該控件里加上focusable\clickable\enabled來實(shí)現(xiàn)

  • ViewHolder的詳解(減低ListView里工作)

holder用來管理ListView里的GetView所綁定的xml文件里的控件 簡單來說就是通過在下面 private class ViewHolder { TextView tvnumber; TextView tvmode; ImageView iv_delete; } ViewHolder里管理的控件變量,當(dāng)在獲取getView要綁定的xml資源到View view時,通過在綁定后把holder里管理的變量通過該view去findViewById獲取對象并添加一個標(biāo)記view.setTag(holder);,那么每次getView時就可以實(shí)現(xiàn)不用重復(fù)再重復(fù)的去findViewById獲取對象,這就可以節(jié)省手機(jī)的cpu處理資源,大大減低ListView的效率

在設(shè)置的點(diǎn)擊事件里進(jìn)行操作集合移除的操作

但是如果不使用adapter的刷新方法,那么也看不出馬上被刪除的效果,解決這個小bug

CallSafeActivity.class

private class ViewHolder {TextView tv_number;TextView tv_mode;ImageView iv_delete; } private class CallSafeAdapter extends MyBaseAdapter<BlackNumberInfo, ListView> {private View view;private ViewHolder holder; // private BlackNumberInfo info;public CallSafeAdapter(CallSafeActivity callSafeActivity,List<BlackNumberInfo> lists) {super(lists, callSafeActivity);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {view = View.inflate(context, R.layout.item_call_safe, null);holder = new ViewHolder();holder.tv_number = (TextView) view.findViewById(R.id.tv_number);holder.tv_mode = (TextView) view.findViewById(R.id.tv_mode);holder.iv_delete = (ImageView) view.findViewById(R.id.iv_delete);// 添加一個標(biāo)記view.setTag(holder);} else {view = convertView;holder = (ViewHolder) view.getTag();}final BlackNumberInfo info = lists.get(position);System.out.println("---------------------"+info.getNumber());//給imageview設(shè)置刪除點(diǎn)擊事件holder.iv_delete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubString blackNumber = info.getNumber();//刪除黑名單電話號碼boolean result = dao.delete(blackNumber);//從集合里面移除黑名單電話號碼lists.remove(info);if(result){adapter.notifyDataSetChanged();}}});

listView里的適配器中數(shù)據(jù)刷新的技巧,為了節(jié)省cpu資源,不用每次顯示listView時都要new出一個新的適配器

private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {// 設(shè)置loading的圖片不可以見ll_loading.setVisibility(View.INVISIBLE);if (lists != null && lists.size() > 0) {//判斷適配器里面是否有數(shù)據(jù)。第一次為null那么就需要創(chuàng)建一個適配器。//為了防止每一次就重新新建適配器。那么就只需要刷新界面if (adapter == null) {adapter = new CallSafeAdapter(CallSafeActivity.this, lists);list_view.setAdapter(adapter);} else {// 刷新界面adapter.notifyDataSetChanged();}}}; }; 資料下載

總結(jié)

以上是生活随笔為你收集整理的手机卫士-05的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。