自制的通讯录APP(SQLite的应用)

来源:互联网 发布:明底线知敬畏演讲稿 编辑:程序博客网 时间:2024/06/11 18:41

转载请附上本文链接并标明作者。
这几天做了一个通讯录APP,主要难点是自己在SQlite建表而不是读取手机联系人的信息以及对SearchView的应用,另外还添加了生日提醒功能,由于时间关系并没有太多注释,可读性一般,也相对粗糙。建议在了解SQliteOpenHelper,Cursor,SimpleCursorAdapter,ListView和adapter等知识之后阅读,会容易理解。适合练手,有什么问题请留言指正,欢迎大牛指点。

(SDK:4.3,开发工具:AS1.5)

1.建立一个ContactDBhelper继承自SQliteOpenHelper类

public class ContactDBHelper extends SQLiteOpenHelper {    private static final String DB_NAME = "CONTACT_DB";    private static final String TBL_NAME = "CONTACT_TBL";    //"_id"很重要,最好加上.name存放姓名,number存放电话,千万别和我一样存int型!还有month和day分别对应月和日,用data型,这里用int型是巨大失误导致后面判断日期是十分麻烦.    private static final String CREAT_TBL ="create table CONTACT_TBL(_id INTEGER PRIMARY KEY AUTOINCREMENT,name string(20),number int,month int,day int)";    private static SQLiteDatabase db;    public static final int VERSION = 1;    public ContactDBHelper(Context context) {        super(context,DB_NAME, null,VERSION);    }    public void onCreate(SQLiteDatabase db){        this.db = db;        db.execSQL(CREAT_TBL);    }    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){    }    public void close(){        if(db != null){            db.close();        }    }}

2.点击添加进入addActivity来添加用户,主要用到了ContentValues.put方法。

public class addActivity extends ActionBarActivity {    private EditText iname;    private EditText inumber;    private EditText imonth;    private EditText iday;    private Button ensure,cancel;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.add);        iname = (EditText)findViewById(R.id.input_name);        inumber = (EditText)findViewById(R.id.input_number);        imonth = (EditText)findViewById(R.id.input_month);        iday = (EditText)findViewById(R.id.input_day);        ensure =(Button)findViewById(R.id.action_ensure);        cancel = (Button)findViewById(R.id.action_cancel);        ensure.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                ContactDBHelper contactDBHelper = new ContactDBHelper(getBaseContext());                SQLiteDatabase db = contactDBHelper.getWritableDatabase();                ContentValues cv = new ContentValues();                cv.put("name", iname.getText().toString());                cv.put("number", Integer.parseInt(inumber.getText().toString()));                cv.put("month", Integer.parseInt(imonth.getText().toString()));                cv.put("day", Integer.parseInt(iday.getText().toString()));                db.insert("CONTACT_TBL",null,cv);                addActivity.this.finish();            }        });        cancel.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                addActivity.this.finish();            }        });    }}

3.点击ListView上的用户名跳转到ModifyActivity,详情页的概念。点击修改可以修改联系人信息,并单击完成保存,原理是用update更新表。

public class ModifyActivity extends ActionBarActivity {    private EditText rname;    private EditText rnumber;    private EditText rmonth;    private EditText rday;    private Button change,stop;    private ImageButton phone,msg;    private int position;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_modify);        rname = (EditText)findViewById(R.id.read_name);        rnumber = (EditText)findViewById(R.id.read_number);        rmonth = (EditText)findViewById(R.id.read_month);        rday = (EditText)findViewById(R.id.read_day);        change =(Button)findViewById(R.id.action_change);        stop = (Button)findViewById(R.id.action_stop);        phone = (ImageButton)findViewById(R.id.phone);        msg = (ImageButton)findViewById(R.id.msg);        Bundle bundle = this.getIntent().getExtras();        position = bundle.getInt("position");        ContactDBHelper contactDBHelper = new ContactDBHelper(getBaseContext());        SQLiteDatabase dbr = contactDBHelper.getReadableDatabase();        Cursor cursor= dbr.query("CONTACT_TBL", null, null, null, null, null, null);        cursor.moveToPosition(position);        rname.setText(cursor.getString(cursor.getColumnIndex("name")));        rnumber.setText(cursor.getString(cursor.getColumnIndex("number")));        rmonth.setText(cursor.getString(cursor.getColumnIndex("month")));        rday.setText(cursor.getString(cursor.getColumnIndex("day")));        rname.setEnabled(false);        rnumber.setEnabled(false);        rmonth.setEnabled(false);        rday.setEnabled(false);        change.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                ContactDBHelper contactDBHelper = new ContactDBHelper(getBaseContext());                SQLiteDatabase db = contactDBHelper.getWritableDatabase();                Cursor cursor = db.query("CONTACT_TBL", null, null, null, null, null, null);                cursor.moveToPosition(position);                int itemID = cursor.getInt(cursor.getColumnIndex("_id"));                String[] which = new String[]{itemID + ""};                ContentValues cv = new ContentValues();                cv.put("name", rname.getText().toString());                cv.put("number", Integer.parseInt(rnumber.getText().toString()));                cv.put("month", Integer.parseInt(rmonth.getText().toString()));                cv.put("day", Integer.parseInt(rday.getText().toString()));                db.update("CONTACT_TBL", cv, "_id=?", which);                ModifyActivity.this.finish();            }        });        stop.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                ModifyActivity.this.finish();            }        });        phone.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + rnumber.getText()));                ModifyActivity.this.startActivity(intent);            }        });        msg.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Uri sms = Uri.parse("smsto:"+rnumber.getText());                Intent intent = new Intent(Intent.ACTION_SENDTO, sms);                ModifyActivity.this.startActivity(intent);            }        });    }    public boolean onOptionsItemSelected(MenuItem item) {        int id = item.getItemId();        switch (id) {            case R.id.action_modify:                rname.setEnabled(true);                rnumber.setEnabled(true);                rmonth.setEnabled(true);                rday.setEnabled(true);        }        return super.onOptionsItemSelected(item);    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_modify, menu);        return true;    }}

4.自定义Myadapter用于SearchView。

public class Myadapter extends BaseAdapter implements Filterable {    private Context context;    private List<String> data , copyData ;    public Myadapter(Context context, List<String> data) {        super();        this.context = context;        this.data = data;        copyData = data ;    }    @Override    public int getCount() {        return data.size() ;    }    @Override    public Object getItem(int position) {        return data.get(position) ;    }    @Override    public long getItemId(int position) {        return position ;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        View view ;        if(null == convertView) {            view = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, null) ;        }        else {            view = convertView ;        }        TextView tv = (TextView) view.findViewById(android.R.id.text1) ;        tv.setText(data.get(position)) ;        return view ;    }    private Filter myFilter ;    @Override    public Filter getFilter() {        if(null == myFilter) {            myFilter = new MyFilter() ;        }        return myFilter ;    }    class MyFilter extends Filter{        // 定义过滤规则        protected FilterResults performFiltering(CharSequence constraint) {            List<String> filterData = new ArrayList<String>() ;            if(constraint != null && constraint.toString().trim().length() > 0) {                String key = constraint.toString().trim().toLowerCase() ;                for (String item : copyData) {                    if(item.toLowerCase().indexOf(key) != -1) {                        filterData.add(item) ;                    }                }            }            else {  //如果搜索框为空,就恢复原始数据                filterData = copyData ;            }            FilterResults results = new FilterResults() ;            results.values = filterData ;            results.count = filterData.size() ;            return results ;        }        @Override        protected void publishResults(CharSequence constraint,                                      FilterResults results) {            data = (List<String>) results.values ;            if(results.count > 0) {                notifyDataSetChanged() ;            }            else {                notifyDataSetInvalidated() ;            }        }    } ;}

5.实现搜索框的方法是:点击EditText跳转到SearchActivity,利用SearchActivity里的SearchView来实现。此时就需要实例化前面自定义的Myadapter类。

public class SearchActivity extends ActionBarActivity {    private static final String TBL_NAME = "CONTACT_TBL";    private static ContactDBHelper contactDBHelper;    private static SQLiteDatabase dbRead;    private static SQLiteDatabase dbWrite;    private static Cursor cursor;    private static ContentValues cv;    public SearchView searchView;    public ListView listView2;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_search);        searchView = (SearchView)findViewById(R.id.search_view);        listView2 = (ListView)findViewById(R.id.listview2);        listView2.setTextFilterEnabled(true) ;        contactDBHelper = new ContactDBHelper(this);        dbWrite = contactDBHelper.getWritableDatabase();        dbRead = contactDBHelper.getReadableDatabase();        cursor = dbRead.query(TBL_NAME, null, null, null, null, null, null);        //遍历表得到data,用于实例化Myadapter        List<String> data = new ArrayList<String>();        if(cursor!=null&&cursor.moveToFirst()){            do{                data.add(cursor.getString(cursor.getColumnIndex("name")));            }while(cursor.moveToNext());        };        Myadapter myadapter = new Myadapter(SearchActivity.this,data);        listView2.setAdapter(myadapter);        searchView.setIconifiedByDefault(false);        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {            public boolean onQueryTextSubmit(String s) {                return true;            }            @Override            public boolean onQueryTextChange(String s) {                if (s != null && s.length() > 0) {                    listView2.setFilterText(s);                } else {                    listView2.clearTextFilter();                }                return true;            }        });        //设置listview点击事件        listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {                cursor.moveToPosition(position);                Intent intent = new Intent(SearchActivity.this, ModifyActivity.class);                Bundle bundle = new Bundle();                bundle.putInt("position", position);                intent.putExtras(bundle);                startActivity(intent);            }        });        //设置listview长按事件        listView2.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {            @Override            public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int position, long l) {                new AlertDialog.Builder(SearchActivity.this)                        .setTitle("是否删除该联系人?")                        .setNegativeButton("取消", null)                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialogInterface, int i) {                                cursor.moveToPosition(position);                                int itemID = cursor.getInt(cursor.getColumnIndex("_id"));                                String[] which = new String[]{itemID + ""};                                dbWrite.delete(TBL_NAME, "_id=?", which);                                refreshListView();                            }                        }).show();                return true;            }        });    }    public void refreshListView(){        cursor = dbRead.query(TBL_NAME, null, null, null, null, null, null);        List<String> data = new ArrayList<String>();        if(cursor!=null&&cursor.moveToFirst()){            do{                data.add(cursor.getString(cursor.getColumnIndex("name")));            }while(cursor.moveToNext());        };        Myadapter myadapter = new Myadapter(SearchActivity.this,data);        listView2.setAdapter(myadapter);    }    @Override    protected void onResume(){        super.onResume();        refreshListView();    }}

6.最后是主活动。长按LiteView上的Item先弹出是否删除的对话框,选择是删除。删除主要靠delete()方法。

public class MainActivity extends ActionBarActivity {    public static final String TBL_NAME = "CONTACT_TBL";    public static ContactDBHelper contactDBHelper;    public static SQLiteDatabase dbRead;    public static SQLiteDatabase dbWrite;    public static Cursor cursor;    public static ContentValues cv;    public ListView listView;    public EditText editText;    public SimpleCursorAdapter listAdapter;    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        listView = (ListView) findViewById(R.id.listview);        editText = (EditText)findViewById(R.id.edittext);        editText.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent intent = new Intent(MainActivity.this,SearchActivity.class);                startActivity(intent);            }        });        contactDBHelper = new ContactDBHelper(this);        dbWrite = contactDBHelper.getWritableDatabase();//        cv = new ContentValues();////        cv.put("name", "jonsnow");//        cv.put("number", 9257);//        cv.put("month", 3);//        cv.put("day",10);//        dbWrite.insert(TBL_NAME, null, cv);//////        cv.put("name", "james");//        cv.put("number", 3154);//        cv.put("month", 6);//        cv.put("day",12);//        dbWrite.insert(TBL_NAME, null, cv);//////        cv.put("name", "curry");//        cv.put("number", 8080);//        cv.put("month", 4);//        cv.put("day",25);//        dbWrite.insert(TBL_NAME, null, cv);        //dbWrite.delete(TBL_NAME,null,null);        dbRead = contactDBHelper.getReadableDatabase();        cursor = dbRead.query(TBL_NAME, null, null, null, null, null, null);        String[] from = new String[]{"name"};        int[] to = new int[]{R.id.name};        //SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags).        //五个参数的实例化SimpleCursorAdapter方法已经被废弃,然而笔者将第六个参数flag设为0,却始终无法编译成功,查了很多资料仍无法解决错误,无奈之下只好使用老方法。有知道为何的朋友若能告知,感激不尽。        listAdapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, from, to);        listView.setAdapter(listAdapter);        listView.setTextFilterEnabled(true);        //设置listview点击事件        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {                Cursor c = listAdapter.getCursor();                c.moveToPosition(position);                Intent intent = new Intent(MainActivity.this, ModifyActivity.class);                Bundle bundle = new Bundle();                bundle.putInt("position", position);                intent.putExtras(bundle);                startActivity(intent);            }        });        //设置listview长按事件        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {            @Override            public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int position, long l) {                new AlertDialog.Builder(MainActivity.this)                        .setTitle("是否删除该联系人?")                        .setNegativeButton("取消", null)                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialogInterface, int i) {                                ;                                Cursor c = listAdapter.getCursor();                                c.moveToPosition(position);                                int itemID = c.getInt(c.getColumnIndex("_id"));                                String[] which = new String[]{itemID + ""};                                dbWrite.delete(TBL_NAME, "_id=?", which);                                refreshListView();                            }                        }).show();                return true;            }        });        BirthRemind();    }    public boolean onOptionsItemSelected(MenuItem item) {        int id = item.getItemId();        switch (id) {            case R.id.action_add:                Intent intent = new Intent(MainActivity.this,addActivity.class);                startActivity(intent);//                break;//            case R.id.action_about://                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);//                builder.setTitle("关于我们")//                        .setMessage("团队:Espirit\n"+"Blog:http://blog.csdn.net/qq_28625603")//                        .show();        }        return super.onOptionsItemSelected(item);    }        @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    public void refreshListView(){        cursor = dbRead.query(TBL_NAME, null, null, null, null, null, null);        listAdapter.changeCursor(cursor);    }    @Override    protected void onResume(){        super.onResume();        refreshListView();    }    //生日提醒功能    protected void BirthRemind(){        //获取当前时间        Calendar c = Calendar.getInstance();        int  month =c.get(Calendar.MONTH)+1;        int  day =c.get(Calendar.DAY_OF_MONTH);        Cursor cursor = dbWrite.query(TBL_NAME, new String[]{"month", "day"}, null, null, null, null, null);        //这里就是强烈建议大家用data型存储日期的原因。我利用四个List才确定了日期。如果处理大一点的数据,不敢想象。当初建表的时候没考虑周全,果然还是naive。        //主要逻辑就是先把所有人的生日月份拿出来和当前月比较,把相同的月份的索引拿出来放入新的list里。由于月和日是一起录入到两个list里的,所以索引是能对上号的。然后根据索引读取存放所有人的day里的数据,放在心的list里,最后如果list里有符合当前日的元素,就利用通知栏通知。        //因为建表的问题和时间关系,并没有读取姓名并且显示到通知栏上,实现起来相信也不难。这里点击通知栏也只有回到主页面而不是详情页。        List<Integer> listmonth = new ArrayList<Integer>();        List<Integer> listday = new ArrayList<Integer>();        while(cursor.moveToNext()){            listmonth.add(Integer.parseInt(cursor.getString(cursor.getColumnIndex("month"))));            listday.add( Integer.parseInt(cursor.getString(cursor.getColumnIndex("day"))));        }        int lm = listmonth.size();        List<Integer> matchm = new ArrayList<>();        for(int i = 0;i<lm;i++)        {            if(listmonth.get(i)==month){                matchm.add(i);                continue;            }        }        int mm = matchm.size();        List<Integer> matchd = new ArrayList<>();        for(int i=0; i<mm;i++){            matchd.add(listday.get(matchm.get(i)));        }        if(matchd.contains(day)){            //通知栏通知            NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);            int icon = android.R.drawable.stat_notify_chat;            long when = System.currentTimeMillis() + 2000;            Notification n = new Notification(icon, "您有一个联系人今天生日", when);            n.defaults = Notification.DEFAULT_SOUND;            n.flags |= Notification.FLAG_AUTO_CANCEL;            Intent openintent = new Intent(this,MainActivity.class);            PendingIntent pi = PendingIntent.getActivity(this, 0, openintent, PendingIntent.FLAG_CANCEL_CURRENT);            n.setLatestEventInfo(this, "生日提醒", "XXX今天生日,快去给TA送上祝福吧", pi);            nm.notify(0, n);        }    }}

layout文件就不放了。
效果如下:

主页面,点击添加跳转至添加联系人页面。点击用户名跳转至联系人详情页,长按用户名呼出删除提示。


主页面


添加联系人页面。

添加联系人


删除提示框,点击确认即可删除用户。

删除提示


在详情页点击修改可修改,单击电话或者短信图标分别对应通话或短信功能。

详情页


点击搜索框跳转到搜索页面。搜索页面也可以进入详情页和进行删除联系人操作。

这里写图片描述

0 0
原创粉丝点击