手机卫士-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();

            }
        }
    }
}

技术分享

技术分享

技术分享

资料下载


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。