手機衛士-04

手機衛士-04

課1

實現第二個功能,通訊衛士 該功能做黑名單的攔截(短信或電話或短信和電話) 在主頁面mainActivity裏的switch/case加上該功能相應方法

case 1:
    Intent intent = new Intent(MainActivity.this,CallSafeActivity.class);
    startActivity(intent);
    break;
}

清單文件加上activity節點:CallSafeActivity.class

創建CallSafeActivity.class/CallSafeActivity.class的xml:activitycallsafe.xml activitycallsafe.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" 
    android:background="@drawable/startpage">

    <TextView 
        style="@style/textview_title_style"
        android:text="通訊衛士"
        android:gravity="center"
        android:textColor="#E2DED8"
        />
    <FrameLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="10"
        >
        <LinearLayout 
            android:id="@+id/ll_loading"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="visible"
            android:orientation="vertical"
            android:gravity="center">
            <ProgressBar 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            <TextView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#E2DED8"
                android:textSize="15sp"
                android:text="玩命加載中..."
                />

        </LinearLayout>
        <!-- android:fastScrollEnabled="true" 設置快速滑動 -->
        <ListView 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/blacklist"
            android:divider="@drawable/list_devider"
            android:fastScrollEnabled="true"
            ></ListView>
    </FrameLayout>
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_weight="1"
        >
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="上一頁"
            android:onClick="pre"
            android:layout_marginRight="10sp"
            android:background="@drawable/btn_selector"
            />
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="下一頁"
             android:layout_marginRight="10sp"
            android:onClick="next"
            android:background="@drawable/btn_selector"
            />
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="跳轉"
            android:onClick="jump"
             android:layout_marginRight="10sp"
            android:background="@drawable/btn_selector"
            />
        <EditText 
            android:id="@+id/et_page"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/faith_yee_textview_style"
            android:layout_marginRight="10sp"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv_page"
            style="@style/faith_yee_textview_style"
            android:text="xxx"
             />
    </LinearLayout>

</LinearLayout>


activitycallsafe.xml嵌套ListView:itemcallsafe.xml ListView:itemcallsafe.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=""wrap_content""
    >
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/faith_yee_textview_style"
        android:text="xxx"
        android:id="@+id/tv_name"
        />
        <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/faith_yee_textview_style"
        android:text="xxx"
        android:textSize="18sp"
        android:id="@+id/tv_phone"
        android:layout_below="@id/tv_name"
        />
    <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"
        />

</RelativeLayout>

由於黑名單裏的數據需要持久化,所以要存入到數據庫中 新建數據庫:BlackNumberDB.class

BlackNumberDBHelper.java

public class BlackNumberDBHelper extends SQLiteOpenHelper {

    public BlackNumberDBHelper(Context context, String name,
            CursorFactory factory, int version) {
        super(context, "callsafe.db", null, 1);
    }


    /**
     * 創建blackinfo這個表
     * number 黑名單電話號碼
     * mode    黑名單攔截的模式
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table blackinfo (_id integer primary key autoincrement,number varchar(20),mode varchar(2))");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}

初始化數據庫、表 新建bean:BlackNumber(電話號碼)

BlackNumberInfo.java

package com.itheima.phonesafeguard.bean;

public class BlackNumberInfo {

    private String number;

    private String mode;

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getMode() {
        return mode;
    }

    public void setMode(String mode) {
        this.mode = mode;
    }

}

新建數據庫的dao對象:BlackNumberDao.class

BlackNumberDao.java

public class BlackNumberDao {

    private BlackNumberDBHelper helper;

    public BlackNumberDao(Context context) {
        super();
        helper = new BlackNumberDBHelper(context);
    }

    /**
     * 添加到黑名單數據庫的方法
     * 
     * @return
     */
    public boolean add(String number, String mode) {

        SQLiteDatabase db = helper.getWritableDatabase();

        ContentValues values = new ContentValues();

        values.put("number", number);

        values.put("mode", mode);

        long rowid = db.insert("blackinfo", null, values);

        if (rowid == -1) {
            return false;
        } else {
            return true;
        }

    }

    /**
     * 根據電話號碼刪除黑名單的數據
     * 
     * @param number
     *            電話號碼
     * @return
     */
    public boolean delete(String number) {

        SQLiteDatabase db = helper.getWritableDatabase();

        int rowid = db.delete("blackinfo", "number = ?",
                new String[] { number });

        if (rowid == 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 根據電話號碼修改攔截的模式
     * 
     * @return
     */
    public boolean changeNumberMode(String number, String newmode) {

        SQLiteDatabase db = helper.getWritableDatabase();

        ContentValues values = new ContentValues();

        values.put("mode", newmode);

        int rowid = db.update("blackinfo", values, "number = ?",
                new String[] { number });

        if (rowid == 0) {
            return false;
        } else {
            return true;
        }

    }

    /**
     * 根據電話號碼查詢攔截的模式
     * 
     * @param number
     * @return
     */
    public String findNumberMode(String number) {
        String mode = "0";
        SQLiteDatabase db = helper.getReadableDatabase();
        // 返回一個遊標
        Cursor cursor = db.query("blackinfo", new String[] { "mode" },
                "number = ?", new String[] { number }, null, null, null);
        // 判斷當前的遊標能否向後面移動
        if (cursor.moveToNext()) {
            mode = cursor.getString(0);
        }
        cursor.close();
        db.close();
        return mode;
    }

    /**
     * 返回所有的黑名單
     * 
     * @return
     */

    public List<BlackNumberInfo> findAll() {

        SQLiteDatabase db = helper.getReadableDatabase();

        Cursor cursor = db
                .query("blackinfo", new String[] { "number", "mode" }, null,
                        null, null, null, null);
        // 創建一個集合用來存放黑名單
        List<BlackNumberInfo> lists = new ArrayList<BlackNumberInfo>();
        while (cursor.moveToNext()) {
            // 初始化黑名單的對象
            BlackNumberInfo info = new BlackNumberInfo();
            info.setNumber(cursor.getString(0));
            info.setMode(cursor.getString(1));
            lists.add(info);
        }
        SystemClock.sleep(2000);
        cursor.close();
        db.close();
        return lists;
    }

    /**
     * 分頁加載數據
     * 
     * @param pageSize
     *            每一頁展示的數據條目
     * @param pageNumber
     *            從哪一條數據開始
     * @return 返回一個黑名單的集合數據
     */
    public List<BlackNumberInfo> findPage(int pageSize, int pageNumber) {

        SQLiteDatabase db = helper.getReadableDatabase();

        Cursor cursor = db.rawQuery(
                "select number,mode from blackinfo limit ? offset ?",
                new String[] { String.valueOf(pageSize),
                        String.valueOf(pageSize * pageNumber) });
        // 初始化黑名單的集合
        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;
    }

    /**
     * 返回所有數據的總數
     * 
     * @return
     */
    public int getCountTotal() {
        String count = "";
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select count(*) from blackinfo", null);
        if (cursor.moveToNext()) {
            count = cursor.getString(0);
        }

        cursor.close();
        return Integer.parseInt(count);
    }

}

在裏面寫增刪查改的方法(添加黑名單方法、根據電話號碼刪除黑名單的數據、根據電話號碼修改攔截的模式、根據電話號碼查詢攔截的模式、查詢所有的方法(返回List)) 新建測試類TestBlackNumerDao.class測試一下dao對象

AndroidManifest.xml

<!-- 配置測試 -->
<instrumentation
    android:name="android.test.InstrumentationTestRunner"
    android:targetPackage="com.itheima.mobile47" />
<application
    android:allowBackup="true"
    android:icon="@drawable/main_icon"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <uses-library android:name="android.test.runner" />

TestBlackNumberDao.java

public class TestBlackNumberDao extends AndroidTestCase {

    private Context context;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        context = getContext(); 
    }

    public void testAdd(){
        BlackNumberDao dao = new BlackNumberDao(context);
        for (int i = 10; i < 99; i++) {
            String number = "138299610" + i +"";
            dao.add(number, new Random().nextInt(3)+1+"");
        }
    }

    public void testDelete(){
        BlackNumberDao dao = new BlackNumberDao(context);

        boolean result = dao.delete("13829961049");

        assertEquals(true, result);
    }

    public void testfind(){
        BlackNumberDao dao = new BlackNumberDao(context);

        String mode = dao.findNumberMode("13829961066");

        System.out.println(mode);
    }

    public void testfindall(){
        BlackNumberDao dao = new BlackNumberDao(context);

        List<BlackNumberInfo> lists = dao.findAll();

        for (int i = 0; i < lists.size(); i++) {
            System.out.println(lists.get(i).getMode()+"--------" + lists.get(i).getNumber());
        }
    }
}

新建一個工程,獲取清單文件中需要的信息,複製到源工程下

課2

把數據都添加到listView裏面:CallSafeActivity.class itemcallsafe.xml佈局的實現(填充ListView的資源文件) 在itemcallsafe.xml的ImageView添加上選擇器:delet_select.xml 在CallSafeActivity.class的getView中注入itemcallsafe.xml

考慮到黑名單裏的仇人過多,查詢量太大,所以可以把CallSafeActivity.class中的查詢代碼放在子線程中處理,並加上handler來處理

但是這樣處理還是不夠優化,我們還可以在getView裏的convertView進行復用。這樣查詢出來的數據交給getView處理效率高多了

如果想在這裏效率達到最高,可以加上private ViewHolder(){} 把在listView裏要顯示的小條目都放在ViewHolder裏,然後修改getView裏的代碼:課下可以瞭解一下 當我們拖動listView是速度很慢,我們可以設置listView裏的屬性:fastScrollEnabled="true" 我們爲打開功能時添加一個獲取數據的時間響應動畫“玩命加載中...” 給它線程睡一會,繼續設計activitycallsafe.xml 加上,把其放在listView中,都用FrameLayout包住

但是考慮到我們如果通過查詢數據是一次太多,不可能等一次過查完所有數據再顯示到listView裏,所以我們需要解決! 我們需要加載分頁數據!

在activitycallsafe.xml裏繼續定義一個linearLayout(包裹上一頁、下一頁、跳轉),我們需要渲染這個linearLayout,讓其上面的佈局不至於擠掉它,所以設置Weight 在CallSafeActivity.class裏實現分頁技術(實現上一頁、下一頁的功能)

課3

如果要使用分頁技術,就不能使用之前dao提供的api(findAll)了 繼續在dao裏添加分頁查詢的api(findPage) 導出db文件,觀察其兩百條黑名單信息

sql:select number,mode form balckInfo limit 20 (從0開始到20)
sql:select number,mode form balckInfo limit 20 offset 20 (從20開始到40)

分頁規律:20是pagesize:每一頁展示的數據條目,40是pageNumber:從哪一條數據開始 findPage(String pageSize,String pageNumber)

代碼如何實現:

繼續在dao裏提供一個api獲取總的分頁條目數(?/? 頁碼) getCountTotal 在CallSafeActivity.class實現業務邏輯:分頁實現 取消線程裏的findall方法,換成dao.findPage方法(測試一下) 然後繼續實現上一頁,下一頁,跳轉的按鈕功能 下一頁功能:public void next(View view),上一頁功能 測試發現刷新界面那段代碼有問題 實現跳轉功能

CallSafeActivity.java

public class CallSafeActivity extends Activity {

    private BlackNumberDao dao;
    @ViewInject(R.id.ll_loading)
    private LinearLayout ll_loading;
    @ViewInject(R.id.tv_page)
    private TextView tv_page;

    @ViewInject(R.id.tv_mode)
    private TextView tv_mode;
    @ViewInject(R.id.tv_phone)
    private TextView tv_phone;
    @ViewInject(R.id.iv_delete)
    private ImageView iv_delete;
    @ViewInject(R.id.et_page)
    private EditText et_page;

    private ListView list_view;

    private String number = "";

    //自定義每頁需要展示多少條數據
    private int pageSize = 20;
    private int totalpage;
    private int mCurrentNumber = 0;
    List<BlackNumberInfo> lists = new ArrayList<BlackNumberInfo>();
    private CallSafeAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_call_safe);
        list_view = (ListView) findViewById(R.id.blacklist);
        ViewUtils.inject(this);
        initData();
    }

    private void initData() {
        //初始化dao對象

        dao = new BlackNumberDao(this);
        //設置當前的加載圖片可見
        ll_loading.setVisibility(View.VISIBLE);

        totalpage = dao.getCountTotal()/ pageSize;
        if(totalpage == 0){
            totalpage = 1;
        }

        tv_page.setText(mCurrentNumber+1+"/"+totalpage+"頁碼");

        //由於考慮到從數據庫獲得所有名單的操作太龐大,在加載頁面的時候很耗時,所以使用子線程
        new Thread(){
            public void run(){
                synchronized (CallSafeActivity.class) {
//              lists = dao.findAll();
                    lists = dao.findPage(pageSize, mCurrentNumber);
                    System.out.println(lists);
                    try {
                        sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    handler.sendEmptyMessage(0);

                }
            };
        }.start();
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(android.os.Message msg) {
            super.handleMessage(msg);

            ll_loading.setVisibility(View.INVISIBLE);
            if(lists!=null && lists.size()> 0 ){
                adapter = new CallSafeAdapter();

                list_view.setAdapter(adapter);

            }
        };

    };

    private class ViewHolder {
        public TextView tv_phone;
        public TextView tv_mode;
        public ImageView iv_delete;
    }

    public class CallSafeAdapter extends BaseAdapter {
        private ViewHolder holder;
        @Override
        public int getCount() {
            return lists.size();
        }

        @Override
        public Object getItem(int position) {
            return lists.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view;
            if(convertView == null){
                view = View.inflate(CallSafeActivity.this, R.layout.item_call_safe, null);

                holder = new ViewHolder();

                holder.tv_phone = (TextView) view.findViewById(R.id.tv_phone);

                holder.tv_mode = (TextView) view.findViewById(R.id.tv_mode);

                holder.iv_delete = (ImageView) view.findViewById(R.id.iv_delete);

                // 添加一個標記
                view.setTag(holder);
            }else{
                view = convertView;
                holder = (ViewHolder) view.getTag();
            }

            holder.tv_phone.setText(lists.get(position).getNumber());

            holder.iv_delete.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    Toast.makeText(CallSafeActivity.this, "需要刪除名單嗎?", 0).show();
                }
            });

            String mode = lists.get(position).getMode();
            if(mode.equals("1")){
                holder.tv_mode.setText("全部攔截");
            }
            if(mode.equals("2")){
                holder.tv_mode.setText("短信攔截");
            }
            if(mode.equals("3")){
                holder.tv_mode.setText("電話攔截");
            }
            return view;
        }

    }




    /**
     * 跳轉到上一頁
     * 
     * @param view
     */
    public void pre(View view){
        if(mCurrentNumber <=  0 ){
            Toast.makeText(CallSafeActivity.this, "已經是第一頁了", 0).show();
            return ;
        }
        mCurrentNumber--;
        initData();
    }


    /**
     * 跳轉到下一頁
     * 
     * @param view
     */
    public void next(View view){
        System.out.println("xxxxxxxxxxxxxx-------------"+totalpage);
        //totalpage=10
        mCurrentNumber++;
        if(mCurrentNumber >=  totalpage ){
            //重置會最後一頁,以免點擊上一頁時再次搜索搜索一次最後一頁的內容
            mCurrentNumber=totalpage-1;
            Toast.makeText(CallSafeActivity.this, "已經是最後一頁了", 0).show();
            return ;
        }
        System.out.println("------------------------>"+mCurrentNumber);
        initData();
    }


    /**
     * 跳轉到哪一頁
     * 
     * @param view
     */
    public void jump(View view) {
        number = et_page.getText().toString().trim();

        if(TextUtils.isEmpty(number)){
            Toast.makeText(CallSafeActivity.this, "請輸入頁碼", 0).show();
        }else{
            int number = Integer.parseInt(et_page.getText().toString().trim());
            if(number <=  0 || number >  totalpage){
                return;
            }else{
                number--;
                mCurrentNumber =number;
                initData();

            }
        }
    }
}




資料下載


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章