手机安全卫士第六天

今天,我使用Android Studio开发环境继续手机卫士的开发。

首先,我们将eclipse中的工作区间及其其中的项目导入到Android Studio工作区间中。在Android Studio中New Project表示新建工作区间,New Module表示新建Android工程,

Reopen Project表示切换工作区间。

将eclipse中的工作区间导入Android Studio中:

File-->close project--->切换到Welcome to Android Sutdio页面--->Import project(Eclipse  ADT,Gradle,etc.)--->选择要导入的Android工程:

手机安全卫士第六天_第1张图片

点击ok


点击下一步next


这时候会报错,说导入的项目的sdk为19,在当前工作区间中没有找到。

解决方法:切换到Project选项上,打开app中的build.gradle,修改为:

手机安全卫士第六天_第2张图片

因为当前AndroidStudio中的SDK为:

手机安全卫士第六天_第3张图片

修改完成后,点击右上角try again,同步到项目中去。

有可能还会报这种错误,解决方法已经注明好了:

手机安全卫士第六天_第4张图片

Android Studio常用的快捷键总结:

格式化代码:Ctrl + Alt + L

删除行:Ctrl + Y

方法参数提示:Ctrl + P

将局部变量改为类的成员变量:Ctrl + Alt + F

得到一些Intention Action,可以生产构造器、Getter、Setter、将 == 改为equals()等:Alt + Insert(联想笔记本中Insert键,是组合键Fn+PgDn Insert)

清除无效包引用:Ctrl + Alt + O

上下移动代码:Alt + Shift + Up/Down



通讯卫士:

list_view.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</ListView>
activity_callsafe.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">
    <TextView
        style="@style/TitleStyle"
        android:text="黑名单管理"/>
    <include layout="@layout/list_view"
        android:id="@+id/lv_list"/>
</LinearLayout>
使用Android Studio的好处就是能使布局“所写所见”,这只是其中一个好处:
手机安全卫士第六天_第5张图片

分析该功能:黑名单管理,需要将黑名单里的电话号码持久化,如果放到内存中的吧,可能退出当前应用后就没有了。所以最好的方式我们在这里创建一个数据库,将所有的数据持久化到数据库中。
BlackNumberDao.java
package com.xbmu.mobilesafe.db.dao;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.xbmu.mobilesafe.bean.BlackNumberInfo;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/2/1 0001.
 */
public class BlackNumberDao {
    private BlackNumberOpenHelper helper;

    /**
     * 在构造方法中创建了BlackNumberOpenHelper对象
     * @param context
     */
    public BlackNumberDao(Context context) {
        helper = new BlackNumberOpenHelper(context);
    }

    /**
     * 向黑名单中添加数据
     *
     * @param number 黑名单电话号码
     * @param mode   拦截模式
     * @return 添加成功,返回true 否则返回false
     */
    public boolean add(String number, String mode) {
        SQLiteDatabase db = helper.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("number", number);
        contentValues.put("mode", mode);
        long rowId = db.insert("blacknumber", null, contentValues);
        if (rowId == -1) {
            return false;
        } else {
            return true;
        }

    }

    /**
     * 移除该电话号码
     *
     * @param number
     * @return
     */
    public boolean delete(String number) {
        SQLiteDatabase db = helper.getWritableDatabase();
        int rowNumber = db.delete("blacknumber", "number=?", new String[]{number});
        if (rowNumber == 0) {
            return false;
        } else {
            return true;
        }

    }

    /**
     * 根据电话号码更改拦截模式
     *
     * @param number
     * @return
     */
    public boolean changeModeByNumber(String number) {
        SQLiteDatabase db = helper.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        int rowNumber = db.update("blacknumber", contentValues, "number=?", new String[]{number});
        if (rowNumber == 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 通过电话号码进行查找
     *
     * @param number
     * @return
     */
    public String findByNumber(String number) {
        String mode = "";
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.query("blacknumber", 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("blacknumber", new String[]{"number", "mode"}, null, null, null, null, null);
        List<BlackNumberInfo> blackNumberInfoList = new ArrayList<BlackNumberInfo>();
        while (cursor.moveToNext()){
            String number = cursor.getString(0);
            String mode = cursor.getString(1);
            BlackNumberInfo blackNumberInfo = new BlackNumberInfo(number,mode);
            blackNumberInfoList.add(blackNumberInfo);
        }
        cursor.close();
        db.close();
        return blackNumberInfoList;
    }
}
BlackNumberOpenHelper.java
package com.xbmu.mobilesafe.db.dao;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Created by Administrator on 2016/2/1 0001.
 */
public class BlackNumberOpenHelper extends SQLiteOpenHelper {
    public BlackNumberOpenHelper(Context mContext){
        super(mContext,"safe.db",null,1);
    }

    /***
     * blacknumber 表名
     * _id 主键自动增长
     * number电话号码
     * mode 拦截模式:电话拦截 短信拦截
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table blacknumber(_id integer primary key autoincrement,number varchar(20),mode varchar(20))");
    }

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

    }
}
BlackNumberInfo.java
package com.xbmu.mobilesafe.bean;

/**
 * Created by Administrator on 2016/2/1 0001.
 */
public class BlackNumberInfo {
    /**
     * 黑名单电话号码
     */
    private String number;
    /**
     * 黑名单拦截模式:
     * 1 全部拦截 电话拦截 + 短信拦截
     * 2 电话拦截
     * 3 短信拦截
     */
    private String mode;

    public BlackNumberInfo() {
    }

    public BlackNumberInfo(String number,String mode) {
        this.number = number;
        this.mode = mode;
    }

    @Override
    public String toString() {
        return "BlackNumberInfo{" +
                "mode='" + mode + '\'' +
                ", number='" + number + '\'' +
                '}';
    }

    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;
    }
}
TestBlackNumberDao.java
package androidTest.java.com.xbmu.mobilesafe;

import android.content.Context;
import android.test.AndroidTestCase;

import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;
import java.util.Random;

/**
 * Created by Administrator on 2016/2/1 0001.
 */
public class TestBlackNumberDao extends AndroidTestCase {
    private Context mContext;
    @Override
    protected void setUp() throws Exception {
        mContext = getContext();
        super.setUp();
    }
    public void testAdd(){
        BlackNumberDao blackNumberDao = new BlackNumberDao(mContext);
        Random random = new Random();
        for (int i = 0;i < 200; i ++){
            Long number = 10086L+i;
            blackNumberDao.add(number+"",String.valueOf(random.nextInt(3)+1));
        }
    }
    public void testDelete(){
        BlackNumberDao blackNumberDao = new BlackNumberDao(mContext);
        boolean delete = blackNumberDao.delete("10086");
        assertEquals(true,delete);
    }
    public void testFind(){
        BlackNumberDao blackNumberDao = new BlackNumberDao(mContext);
        String find = blackNumberDao.findByNumber("10087");
        System.out.print(find);
    }
    public void testFindAll(){
        BlackNumberDao blackNumberDao = new BlackNumberDao(mContext);
       List<BlackNumberInfo> blackNumberInfos =  blackNumberDao.findAll();
        for(BlackNumberInfo blackNumber : blackNumberInfos){
            System.out.println(blackNumber.getNumber()+","+blackNumber.getMode());
        }
    }
}

黑名单管理界面的设计及其ListView的优化:

item_call_safe.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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="130000000"
        android:id="@+id/tv_black_number"
        android:textSize="20sp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"/>
    <TextView
        android:id="@id/tv_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="短信拦截"
        android:layout_below="@id/tv_black_number"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="5dp"/>
    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentRight="true"
        android:background="@drawable/ic_delete_btn"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        />
</RelativeLayout>
res/values/ids.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item type="id" name="tv_mode"/>
</resources>
也要知道这种创建组件id的方式。
CallSafeActivity.java
package com.xbmu.mobilesafe;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;

/**
 * 通讯卫士
 */
public class CallSafeActivity extends Activity {

    private ListView lv_list;
    private List<BlackNumberInfo> blackNumberInfoList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_safe);
        initUI();
        initData();
    }
    /**初始化数据*/
    private void initData() {
        BlackNumberDao dao = new BlackNumberDao(this);
        blackNumberInfoList = dao.findAll();
        CallSafeAdapter adapter = new CallSafeAdapter();
        lv_list.setAdapter(adapter);
    }
    private class CallSafeAdapter extends BaseAdapter{


        @Override
        public int getCount() {
            return blackNumberInfoList.size();
        }

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

        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if(convertView == null){
                viewHolder = new ViewHolder();
                convertView = View.inflate(CallSafeActivity.this,R.layout.item_call_safe,null);
                viewHolder.tv_black_number = (TextView) convertView.findViewById(R.id.tv_black_number);
                viewHolder.tv_mode = (TextView) convertView.findViewById(R.id.tv_mode);
                convertView.setTag(viewHolder);
            }
            viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.tv_black_number.setText(blackNumberInfoList.get(position).getNumber());
            String mode = blackNumberInfoList.get(position).getMode();
            if("1".equals(mode)){
                viewHolder.tv_mode.setText("电话+短信拦截");
            }else if("2".equals(mode)){
                viewHolder.tv_mode.setText("电话拦截");
            }else{
                viewHolder.tv_mode.setText("短信拦截");
            }

            return convertView;
        }
    }
    static class ViewHolder{
        TextView tv_black_number;
        TextView tv_mode;


    }
    /**初始化UI界面*/
    private void initUI() {
        lv_list = (ListView) findViewById(R.id.lv_list);
    }

}

抽取MyCallSafeAdapter.java

package com.xbmu.mobilesafe.adapter;

import android.content.Context;
import android.widget.BaseAdapter;

import java.util.List;

/**
 * Created by Administrator on 2016/2/2 0002.
 */
public abstract class MyCallSafeAdapter<T> extends BaseAdapter {
    public List<T> mDatas;
    public Context mContext;

    public MyCallSafeAdapter(Context mContext, List<T> mDatas) {
        this.mContext = mContext;
        this.mDatas = mDatas;
    }

    @Override
    public int getCount() {
        return mDatas.size();
    }

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

    @Override
    public long getItemId(int position) {
        return position;
    }
}
CallSafeActivity.java
package com.xbmu.mobilesafe;

import android.content.Context;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.xbmu.mobilesafe.adapter.MyCallSafeAdapter;
import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;

/**
 * 通讯卫士
 */
public class CallSafeActivity extends Activity {

    private ListView lv_list;
    private List<BlackNumberInfo> blackNumberInfoList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_safe);
        initUI();
        initData();
    }
    /**初始化数据*/
    private void initData() {
        BlackNumberDao dao = new BlackNumberDao(this);
        blackNumberInfoList = dao.findAll();
        CallSafeAdapter adapter = new CallSafeAdapter(this,blackNumberInfoList);
        lv_list.setAdapter(adapter);
    }
    private class CallSafeAdapter extends MyCallSafeAdapter{
        public CallSafeAdapter(Context mContext, List mDatas) {
            super(mContext, mDatas);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if(convertView == null){
                viewHolder = new ViewHolder();
                convertView = View.inflate(CallSafeActivity.this,R.layout.item_call_safe,null);
                viewHolder.tv_black_number = (TextView) convertView.findViewById(R.id.tv_black_number);
                viewHolder.tv_mode = (TextView) convertView.findViewById(R.id.tv_mode);
                convertView.setTag(viewHolder);
            }
            viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.tv_black_number.setText(blackNumberInfoList.get(position).getNumber());
            String mode = blackNumberInfoList.get(position).getMode();
            if("1".equals(mode)){
                viewHolder.tv_mode.setText("电话+短信拦截");
            }else if("2".equals(mode)){
                viewHolder.tv_mode.setText("电话拦截");
            }else{
                viewHolder.tv_mode.setText("短信拦截");
            }

            return convertView;
        }
    }
    static class ViewHolder{
        TextView tv_black_number;
        TextView tv_mode;


    }
    /**初始化UI界面*/
    private void initUI() {
        lv_list = (ListView) findViewById(R.id.lv_list);
    }

}

优化加载的数据:

CallSafeActivity.java
package com.xbmu.mobilesafe;

import android.content.Context;
import android.os.Bundle;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.xbmu.mobilesafe.adapter.MyCallSafeAdapter;
import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;

/**
 * 通讯卫士
 */
public class CallSafeActivity extends Activity {

    private ListView lv_list;
    private List<BlackNumberInfo> blackNumberInfoList;
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            CallSafeAdapter adapter = new CallSafeAdapter(CallSafeActivity.this,blackNumberInfoList);
            lv_list.setAdapter(adapter);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_safe);
        initUI();
        initData();
    }
    /**初始化数据*/
    private void initData() {
        /**
         * 数据优化:如果加载的数据只有三四百条数据的话,放在主线程中加载也是可以的,对性能的影响很少。
         * 但是如果成千条,成亿条数据要加载的话,一般情况下放在子线程中加载,对应用的性能会有很大的提高。
         */
        new Thread(){
            @Override
            public void run() {
                super.run();
                BlackNumberDao dao = new BlackNumberDao(CallSafeActivity.this);
                blackNumberInfoList = dao.findAll();
                //使用Handler对象发送消息
                mHandler.sendEmptyMessage(0);
            }
        }.start();
    }
    //...

}

让数据延迟显示,完成加载页面的显示

activity_call_safe.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.xbmu.mobilesafe.CallSafeActivity"
    >
    <TextView
        style="@style/TitleStyle"
        android:text="黑名单管理"/>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:id="@+id/ll_pb"
            android:orientation="vertical"
            android:visibility="invisible">
            <ProgressBar

                android:id="@+id/pb_black_number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            <TextView
                android:textSize="18sp"
                android:textColor="#000"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="玩命加载中..."/>
        </LinearLayout>

        <include
            android:id="@+id/lv_list"
            layout="@layout/list_view" />
    </FrameLayout>
</LinearLayout>
BlackNumberDao.java
/**
     * 查找所有
     *
     * @return
     */
    public List<BlackNumberInfo> findAll() {
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.query("blacknumber", new String[]{"number", "mode"}, null, null, null, null, null);
        List<BlackNumberInfo> blackNumberInfoList = new ArrayList<BlackNumberInfo>();
        while (cursor.moveToNext()){
            String number = cursor.getString(0);
            String mode = cursor.getString(1);
            BlackNumberInfo blackNumberInfo = new BlackNumberInfo(number,mode);
            blackNumberInfoList.add(blackNumberInfo);
        }
        cursor.close();
        db.close();
        //睡眠3秒钟
        SystemClock.sleep(3000);
        return blackNumberInfoList;
    }
CalSafeActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.xbmu.mobilesafe.adapter.MyCallSafeAdapter;
import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;

/**
 * 通讯卫士
 */
public class CallSafeActivity extends Activity {

    private ListView lv_list;
    private List<BlackNumberInfo> blackNumberInfoList;
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ll_pb.setVisibility(View.INVISIBLE);
            CallSafeAdapter adapter = new CallSafeAdapter(CallSafeActivity.this,blackNumberInfoList);
            lv_list.setAdapter(adapter);
        }
    };
    private LinearLayout ll_pb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_safe);
        initUI();
        initData();
    }
    /**初始化数据*/
    private void initData() {

        /**
         * 数据优化:如果加载的数据只有三四百条数据的话,放在主线程中加载也是可以的,对性能的影响很少。
         * 但是如果成千条,成亿条数据要加载的话,一般情况下放在子线程中加载,对应用的性能会有很大的提高。
         */
        new Thread(){
            @Override
            public void run() {
                super.run();
                BlackNumberDao dao = new BlackNumberDao(CallSafeActivity.this);
                blackNumberInfoList = dao.findAll();
                //使用Handler对象发送消息
                mHandler.sendEmptyMessage(0);
            }
        }.start();
    }
    private class CallSafeAdapter extends MyCallSafeAdapter{
        public CallSafeAdapter(Context mContext, List mDatas) {
            super(mContext, mDatas);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if(convertView == null){
                viewHolder = new ViewHolder();
                convertView = View.inflate(CallSafeActivity.this,R.layout.item_call_safe,null);
                viewHolder.tv_black_number = (TextView) convertView.findViewById(R.id.tv_black_number);
                viewHolder.tv_mode = (TextView) convertView.findViewById(R.id.tv_mode);
                convertView.setTag(viewHolder);
            }
            viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.tv_black_number.setText(blackNumberInfoList.get(position).getNumber());
            String mode = blackNumberInfoList.get(position).getMode();
            if("1".equals(mode)){
                viewHolder.tv_mode.setText("电话+短信拦截");
            }else if("2".equals(mode)){
                viewHolder.tv_mode.setText("电话拦截");
            }else{
                viewHolder.tv_mode.setText("短信拦截");
            }

            return convertView;
        }
    }
    static class ViewHolder{
        TextView tv_black_number;
        TextView tv_mode;


    }
    /**初始化UI界面*/
    private void initUI() {
        ll_pb = (LinearLayout) findViewById(R.id.ll_pb);
        //显示加载的圈圈
        ll_pb.setVisibility(View.VISIBLE);
        lv_list = (ListView) findViewById(R.id.lv_list);
    }

}
运行效果:
手机安全卫士第六天_第6张图片

分页加载数据&删除单条数据:

BlackNumberDao.java
 /**
     * 分页加载数据
     *
     * @param pageNumber 当前是那一页
     * @param pageSize   每一页有多少条数据
     * @return 返回每页加载的数据集合
     * <p/>
     * limit:表示限制,当前有多少条数据
     * offset:表示跳过,从第几条开始
     */
    public List<BlackNumberInfo> findPage(int pageNumber, int pageSize) {
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select number,mode from blacknumber limit ? offset ?",
                new String[]{String.valueOf(pageSize), String.valueOf(pageNumber * pageSize)});
        List<BlackNumberInfo> blackNumberInfoList = new ArrayList<BlackNumberInfo>();
        while (cursor.moveToNext()) {
            String number = cursor.getString(0);
            String mode = cursor.getString(1);
            BlackNumberInfo blackNumberInfo = new BlackNumberInfo(number, mode);
            blackNumberInfoList.add(blackNumberInfo);
        }
        cursor.close();
        db.close();
        return blackNumberInfoList;
    }

    /**
     * 获取总的记录数
     *
     * @return
     */
    public int totalRecords() {
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select count(*) from blacknumber", null);
        cursor.moveToNext();
        int total = cursor.getInt(0);
        cursor.close();
        db.close();
        return total;
    }
activity_call_safe.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.xbmu.mobilesafe.CallSafeActivity"

    >
    <TextView
        style="@style/TitleStyle"
        android:text="黑名单管理"/>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:id="@+id/ll_pb"
            android:orientation="vertical"
            android:visibility="invisible">
            <ProgressBar

                android:id="@+id/pb_black_number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            <TextView
                android:textSize="18sp"
                android:textColor="#000"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="玩命加载中..."/>
        </LinearLayout>

        <include
            android:id="@+id/lv_list"
            layout="@layout/list_view" />
    </FrameLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="prePage"
            android:text="上一页"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="nextPage"
            android:text="下一页"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="jump"
            android:text="跳转"/>
        <EditText
            android:id="@+id/et_page_number"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"/>
        <TextView
            android:id="@+id/tv_page_number"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="0/10"
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="#000"/>
    </LinearLayout>
</LinearLayout>
效果图:
手机安全卫士第六天_第7张图片
CallSafeActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.Context;
import android.media.Image;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telecom.Call;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.xbmu.mobilesafe.adapter.MyCallSafeAdapter;
import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;

/**
 * 通讯卫士
 */
public class CallSafeActivity extends Activity {

    private ListView lv_list;
    private List<BlackNumberInfo> blackNumberInfoList;
    private CallSafeAdapter adapter;

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ll_pb.setVisibility(View.INVISIBLE);
            adapter = new CallSafeAdapter(CallSafeActivity.this,blackNumberInfoList);
            lv_list.setAdapter(adapter);
            tv_page_number.setText(mCurrentPageNumber + "/" + totalPage);
        }
    };
    private LinearLayout ll_pb;
    private BlackNumberDao dao;
    /**
     * 当前页吗
     */
    private int mCurrentPageNumber = 0;
    /**
     * 每页显示20条数据
     */
    private int pageSize = 20;
    private TextView tv_page_number;
    /**
     * 总页数
     */
    private int totalPage;
    private EditText et_page_number;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_safe);
        initUI();
        initData();
    }
    /**初始化数据*/
    private void initData() {

        /**
         * 数据优化:如果加载的数据只有三四百条数据的话,放在主线程中加载也是可以的,对性能的影响很少。
         * 但是如果成千条,成亿条数据要加载的话,一般情况下放在子线程中加载,对应用的性能会有很大的提高。
         */
        new Thread(){

            @Override
            public void run() {
                super.run();
                dao = new BlackNumberDao(CallSafeActivity.this);
                //总页数 = 总记录数/ 每页显示的数据
                totalPage = dao.totalRecords() / pageSize;
                blackNumberInfoList = dao.findPage(mCurrentPageNumber,pageSize);

                //使用Handler对象发送消息
                mHandler.sendEmptyMessage(0);
            }
        }.start();
    }
    private class CallSafeAdapter extends MyCallSafeAdapter{
        public CallSafeAdapter(Context mContext, List mDatas) {
            super(mContext, mDatas);
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if(convertView == null){
                viewHolder = new ViewHolder();
                convertView = View.inflate(CallSafeActivity.this,R.layout.item_call_safe,null);
                viewHolder.tv_black_number = (TextView) convertView.findViewById(R.id.tv_black_number);
                viewHolder.tv_mode = (TextView) convertView.findViewById(R.id.tv_mode);
                viewHolder.iv_delete = (ImageView) convertView.findViewById(R.id.iv_delete);
                convertView.setTag(viewHolder);
            }
            viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.tv_black_number.setText(blackNumberInfoList.get(position).getNumber());
            String mode = blackNumberInfoList.get(position).getMode();
            if("1".equals(mode)){
                viewHolder.tv_mode.setText("电话+短信拦截");
            }else if("2".equals(mode)){
                viewHolder.tv_mode.setText("电话拦截");
            }else{
                viewHolder.tv_mode.setText("短信拦截");
            }
            viewHolder.iv_delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String number = blackNumberInfoList.get(position).getNumber();
                    boolean delete = dao.delete(number);
                    if (delete) {
                        Toast.makeText(CallSafeActivity.this,"删除成功!",Toast.LENGTH_SHORT).show();
                        blackNumberInfoList.remove(position);
                        //刷新界面
                        adapter.notifyDataSetChanged();
                    } else {
                        Toast.makeText(CallSafeActivity.this,"删除失败!",Toast.LENGTH_SHORT).show();
                    }
                }
            });
            return convertView;
        }
    }
    static class ViewHolder{
        TextView tv_black_number;
        TextView tv_mode;
        ImageView iv_delete;


    }
    /**初始化UI界面*/
    private void initUI() {
        ll_pb = (LinearLayout) findViewById(R.id.ll_pb);
        //显示加载的圈圈
        ll_pb.setVisibility(View.VISIBLE);
        lv_list = (ListView) findViewById(R.id.lv_list);
        tv_page_number = (TextView) findViewById(R.id.tv_page_number);
        et_page_number = (EditText) findViewById(R.id.et_page_number);
    }

    /**
     * 上一页
     * @param view
     */
    public void prePage(View view){
        //当前页小于等于0
        if(mCurrentPageNumber <= 0){
            Toast.makeText(this,"当前页已经是首页了!",Toast.LENGTH_SHORT).show();
            return;
        }
        mCurrentPageNumber--;
        initData();

    }

    /**
     * 下一页
     * @param view
     */
    public void nextPage(View view){
        //当前页大于总页数
        if(mCurrentPageNumber > (totalPage-1)){
            Toast.makeText(this,"当前页已经是尾页了!",Toast.LENGTH_SHORT).show();
            return;
        }
        mCurrentPageNumber++;
        initData();
    }

    /**
     * 跳转
     * @param view
     */
    public void jump(View view){
        String pageStr = et_page_number.getText().toString().trim();
        if(TextUtils.isEmpty(pageStr)){
            Toast.makeText(this,"请输入页码!",Toast.LENGTH_SHORT).show();
        }else{
            if(Integer.valueOf(pageStr) < 0 && Integer.valueOf(pageStr) > (totalPage -1)){
                Toast.makeText(this,"请输入正确的页码!",Toast.LENGTH_SHORT).show();
            }
        }
        mCurrentPageNumber = Integer.valueOf(pageStr);
        initData();
    }
}
运行效果图:

分批加载数据:

分批处理的好处:不用等待太久,节约流量,慢慢引导用户看感兴趣的内容。
BlackNumberDao.java
 /**
     * 分批加载数据
     * @param startIndex 开始的位置
     * @param maxCount 每页展示的最大条目数
     * @return
     *
     * limit:表示限制,当前有多少条数据
     * offset:表示跳过,从第几条开始
     */
    public List<BlackNumberInfo> findBatch(int startIndex,int maxCount){
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select number,mode from blacknumber limit ? offset ?",
                new String[]{String.valueOf(maxCount), String.valueOf(startIndex)});
        List<BlackNumberInfo> blackNumberInfoList = new ArrayList<BlackNumberInfo>();
        while (cursor.moveToNext()) {
            String number = cursor.getString(0);
            String mode = cursor.getString(1);
            BlackNumberInfo blackNumberInfo = new BlackNumberInfo(number, mode);
            blackNumberInfoList.add(blackNumberInfo);
        }
        cursor.close();
        db.close();
        return blackNumberInfoList;
    }
CallSafeActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.Context;
import android.media.Image;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telecom.Call;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.xbmu.mobilesafe.adapter.MyCallSafeAdapter;
import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;

/**
 * 通讯卫士
 */
public class CallSafeActivity extends Activity {

    private ListView lv_list;
    private List<BlackNumberInfo> blackNumberInfoList;
    private CallSafeAdapter adapter;

    private Handler mHandler = new Handler() {


        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ll_pb.setVisibility(View.INVISIBLE);
            if (adapter == null) {
                adapter = new CallSafeAdapter(CallSafeActivity.this, blackNumberInfoList);
                lv_list.setAdapter(adapter);

            } else {
                adapter.notifyDataSetChanged();
            }
        }
    };
    private LinearLayout ll_pb;
    private BlackNumberDao dao;
    /**
     * 当前页吗
     */
    private int startIndex = 0;
    /**
     * 每页显示20条数据
     */
    private int maxCount = 20;
   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_safe);
        initUI();
        initData();
    }

    /**
     * 初始化数据
     */
    private void initData() {

        dao = new BlackNumberDao(CallSafeActivity.this);
        totalRecords = dao.totalRecords();//一共有多少条数据
        /**
         * 数据优化:如果加载的数据只有三四百条数据的话,放在主线程中加载也是可以的,对性能的影响很少。
         * 但是如果成千条,成亿条数据要加载的话,一般情况下放在子线程中加载,对应用的性能会有很大的提高。
         */
        new Thread() {

            @Override
            public void run() {
                super.run();

                //分批加载数据
                if (blackNumberInfoList == null) {
                    blackNumberInfoList = dao.findBatch(startIndex, maxCount);
                } else {
                    //把后面的数据加载blackNumberInfoList集合中,防止前面分批加载的黑名单被覆盖
                    blackNumberInfoList.addAll(dao.findBatch(startIndex, maxCount));
                }
                mHandler.sendEmptyMessage(0);
            }
        }.start();
    }

    private class CallSafeAdapter extends MyCallSafeAdapter {
        public CallSafeAdapter(Context mContext, List mDatas) {
            super(mContext, mDatas);
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = View.inflate(CallSafeActivity.this, R.layout.item_call_safe, null);
                viewHolder.tv_black_number = (TextView) convertView.findViewById(R.id.tv_black_number);
                viewHolder.tv_mode = (TextView) convertView.findViewById(R.id.tv_mode);
                viewHolder.iv_delete = (ImageView) convertView.findViewById(R.id.iv_delete);
                convertView.setTag(viewHolder);
            }
            viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.tv_black_number.setText(blackNumberInfoList.get(position).getNumber());
            String mode = blackNumberInfoList.get(position).getMode();
            if ("1".equals(mode)) {
                viewHolder.tv_mode.setText("电话+短信拦截");
            } else if ("2".equals(mode)) {
                viewHolder.tv_mode.setText("电话拦截");
            } else {
                viewHolder.tv_mode.setText("短信拦截");
            }
            viewHolder.iv_delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String number = blackNumberInfoList.get(position).getNumber();
                    boolean delete = dao.delete(number);
                    if (delete) {
                        Toast.makeText(CallSafeActivity.this, "删除成功!", Toast.LENGTH_SHORT).show();
                        blackNumberInfoList.remove(position);
                        //刷新界面
                        adapter.notifyDataSetChanged();
                    } else {
                        Toast.makeText(CallSafeActivity.this, "删除失败!", Toast.LENGTH_SHORT).show();
                    }
                }
            });
            return convertView;
        }
    }

    static class ViewHolder {
        TextView tv_black_number;
        TextView tv_mode;
        ImageView iv_delete;


    }

    /**
     * 初始化UI界面
     */
    private void initUI() {
        ll_pb = (LinearLayout) findViewById(R.id.ll_pb);
        //显示加载的圈圈
        ll_pb.setVisibility(View.VISIBLE);
        lv_list = (ListView) findViewById(R.id.lv_list);
        //设置ListView滚动监听
        lv_list.setOnScrollListener(new AbsListView.OnScrollListener() {
            //状态改变的时候回调该方法

            /**
             * @param view
             * @param scrollState 表示滚动的状态
             *
             *                  AbsListView.OnScrollListener.SCROLL_STATE_IDLE: 当屏幕停止滚动时(闲置状态)
             *                  AbsListView.OnScrollListener.SCROLL_STATE_FLING:由于用户的操作,屏幕产生惯性滑动时
             *                  AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:当屏幕滚动且用户使用的触碰或手指还在屏幕上时
             *
             */
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                System.out.println("onScrollStateChanged");
                switch (scrollState) {
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        //获取到最后一条显示的数据的位置

                        //值为19,最后一条数据的位置。随着后续的加载39,59....

                        int lastVisiblePosition = lv_list.getLastVisiblePosition();

                        int total = blackNumberInfoList.size();//20,总得数据

                        System.out.println("lastVisiblePosition=" + lastVisiblePosition);

                        if(lastVisiblePosition == (total - 1) ){
                            // 最后一条数据了,该去加载了。
                            Toast.makeText(getApplicationContext(),
                                    "加载。", Toast.LENGTH_SHORT).show();
                            ll_pb.setVisibility(View.VISIBLE);//显示加载
                            startIndex += maxCount;
                            initData();
                        }
                        break;
                }
            }

            //listView滚动时候调用的方法
            //时时调用,当我们的手触摸屏幕的时候调用
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

            }
        });
    }

}
运行效果:

防止重复加载 & 加载到最后一条,提醒用户:

CallSafeActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.Context;
import android.media.Image;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telecom.Call;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.xbmu.mobilesafe.adapter.MyCallSafeAdapter;
import com.xbmu.mobilesafe.bean.BlackNumberInfo;
import com.xbmu.mobilesafe.db.dao.BlackNumberDao;

import java.util.List;

/**
 * 通讯卫士
 */
public class CallSafeActivity extends Activity {

    private ListView lv_list;
    private List<BlackNumberInfo> blackNumberInfoList;
    private CallSafeAdapter adapter;
    private boolean isLoading = false;
    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ll_pb.setVisibility(View.INVISIBLE);
            if (adapter == null) {
                adapter = new CallSafeAdapter(CallSafeActivity.this, blackNumberInfoList);
                lv_list.setAdapter(adapter);

            } else {
                adapter.notifyDataSetChanged();
            }
            isLoading = false;
        }
    };
    private LinearLayout ll_pb;
    private BlackNumberDao dao;
    /**
     * 当前页吗
     */
    private int startIndex = 0;
    /**
     * 每页显示20条数据
     */
    private int maxCount = 20;
    /**
     * 总记录数
     */
    private int totalRecords;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call_safe);
        initUI();
        initData();
    }

    /**
     * 初始化数据
     */
    private void initData() {

        dao = new BlackNumberDao(CallSafeActivity.this);
        totalRecords = dao.totalRecords();
        /**
         * 数据优化:如果加载的数据只有三四百条数据的话,放在主线程中加载也是可以的,对性能的影响很少。
         * 但是如果成千条,成亿条数据要加载的话,一般情况下放在子线程中加载,对应用的性能会有很大的提高。
         */
        new Thread() {

            @Override
            public void run() {
                super.run();

                //分批加载数据
                if (blackNumberInfoList == null) {
                    blackNumberInfoList = dao.findBatch(startIndex, maxCount);
                } else {
                    //把后面的数据加载blackNumberInfoList集合中,防止前面分批加载的黑名单被覆盖
                    blackNumberInfoList.addAll(dao.findBatch(startIndex, maxCount));
                }
                mHandler.sendEmptyMessage(0);
            }
        }.start();
    }

    private class CallSafeAdapter extends MyCallSafeAdapter {
        public CallSafeAdapter(Context mContext, List mDatas) {
            super(mContext, mDatas);
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = View.inflate(CallSafeActivity.this, R.layout.item_call_safe, null);
                viewHolder.tv_black_number = (TextView) convertView.findViewById(R.id.tv_black_number);
                viewHolder.tv_mode = (TextView) convertView.findViewById(R.id.tv_mode);
                viewHolder.iv_delete = (ImageView) convertView.findViewById(R.id.iv_delete);
                convertView.setTag(viewHolder);
            }
            viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.tv_black_number.setText(blackNumberInfoList.get(position).getNumber());
            String mode = blackNumberInfoList.get(position).getMode();
            if ("1".equals(mode)) {
                viewHolder.tv_mode.setText("电话+短信拦截");
            } else if ("2".equals(mode)) {
                viewHolder.tv_mode.setText("电话拦截");
            } else {
                viewHolder.tv_mode.setText("短信拦截");
            }
            viewHolder.iv_delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String number = blackNumberInfoList.get(position).getNumber();
                    boolean delete = dao.delete(number);
                    if (delete) {
                        Toast.makeText(CallSafeActivity.this, "删除成功!", Toast.LENGTH_SHORT).show();
                        blackNumberInfoList.remove(position);
                        //刷新界面
                        adapter.notifyDataSetChanged();
                    } else {
                        Toast.makeText(CallSafeActivity.this, "删除失败!", Toast.LENGTH_SHORT).show();
                    }
                }
            });
            return convertView;
        }
    }

    static class ViewHolder {
        TextView tv_black_number;
        TextView tv_mode;
        ImageView iv_delete;


    }

    /**
     * 初始化UI界面
     */
    private void initUI() {
        ll_pb = (LinearLayout) findViewById(R.id.ll_pb);
        //显示加载的圈圈
        ll_pb.setVisibility(View.VISIBLE);
        lv_list = (ListView) findViewById(R.id.lv_list);
        //设置ListView滚动监听
        lv_list.setOnScrollListener(new AbsListView.OnScrollListener() {
            //状态改变的时候回调该方法

            /**
             * @param view
             * @param scrollState 表示滚动的状态
             *
             *                  AbsListView.OnScrollListener.SCROLL_STATE_IDLE: 当屏幕停止滚动时(闲置状态)
             *                  AbsListView.OnScrollListener.SCROLL_STATE_FLING:由于用户的操作,屏幕产生惯性滑动时
             *                  AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:当屏幕滚动且用户使用的触碰或手指还在屏幕上时
             *
             */
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                System.out.println("onScrollStateChanged");
                switch (scrollState) {
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        //获取到最后一条显示的数据的位置

                        //值为19,最后一条数据的位置。随着后续的加载39,59...
                        int lastVisiblePosition = lv_list.getLastVisiblePosition();

                        int total = blackNumberInfoList.size();//20,总得数据

                        System.out.println("lastVisiblePosition=" + lastVisiblePosition);

                        if(lastVisiblePosition == (total - 1) ){
                            if (isLoading){
                                return;
                            }
                            // 最后一条数据了,该去加载了。
                            Toast.makeText(getApplicationContext(),
                                    "加载。", Toast.LENGTH_SHORT).show();
                            ll_pb.setVisibility(View.VISIBLE);//显示加载
                            startIndex += maxCount;
                            if(startIndex >= totalRecords){
                                // 最后一条数据了,该去加载了。
                                Toast.makeText(getApplicationContext(),
                                        "已经是最后一条数据了,没有更多数据了。", Toast.LENGTH_SHORT).show();
                            }
                            initData();

                            isLoading = true;
                        }
                        break;
                }
            }

            //listView滚动时候调用的方法
            //时时调用,当我们的手触摸屏幕的时候调用
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

            }
        });
    }

}
运行效果:






你可能感兴趣的:(手机安全卫士)