Android实现SQLite数据库联系人列表

Android实现SQLite数据库联系人列表

开发工具:Andorid Studio 1.3
运行环境:Android 4.4 KitKat

工程内容

实现一个通讯录查看程序:

  1. 要求使用SQLite数据库保存通讯录,使得每次运行程序均能显示当前联系人的列表
  2. 主界面包含一个添加联系人按钮和一个联系人列表,每一项显示联系人学号,姓名,手机号码。
  3. 点击添加联系人按钮能添加新的联系人。
  4. 在次界面输入联系人信息之后点击确定按钮后会返回主界面。(前提输入正确)
  5. 长按某个联系人,弹出对话框,询问是否删除该联系人。
  6. 单击某个联系人,弹出修改联想人的界面。

代码实现

为联系人添加一个类Contact,封装学号姓名手机号码三个字段,并重构三个构造函数,给每个字段设置公有的get、set函数,这是类最标准的做法。

public class Contact {
    private String no;
    private String name;
    private String phoneNumber;

    public Contact() {}
    public Contact(String _name, String _phoneNumber) {
        this.name = _name;
        this.phoneNumber = _phoneNumber;
    }
    public Contact(String _no, String _name, String _phoneNumber) {
        this.no = _no;
        this.name = _name;
        this.phoneNumber = _phoneNumber;
    }

    public String getNo() { return no; }
    public void setNo(String _no) { this.no = _no; }
    public String getName() { return name; }
    public void setName(String _name) { this.name = _name; }
    public String getPhoneNumber() { return phoneNumber; }
    public void setPhoneNumber(String _phoneNumber) { this.phoneNumber = _phoneNumber; }

}

为接下来要用到的数据库方法新建一个类MyDatabaseHelper继承自SQLiteOpenHelper,设置好数据库名称和表格名称以及比较重要的版本号,封装好以便后面使用。

public class MyDatabaseHelper extends SQLiteOpenHelper {
    private static final String DB_NAME = "Contacts.db";
    private static final String TABLE_NAME = "Contacts";
    private static final int DB_VERSION = 1;

    public MyDatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }
}

一开始是创建数据库,这里使用自增的id字段为关键字,其余学号姓名手机为基本字段,创建
一个表格存储,当这个MyDatabaseHelper被实例化的时候即创建表格,因此在onCreate()中做

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_TABLE = "create table " + TABLE_NAME
            + " (_id integer primary key autoincrement, "
            + "_no text not null, "
            + "_name text not null, "
            + "_pnumber text);";
    db.execSQL(CREATE_TABLE);
}

为了能创建实例需要重载onUpgrade()函数,这里简单地重载,但是调用会出事,整张表格内容会丢失,但在这次程序里面不会被调用,先暂且写着

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    String DROP_TABLE = "DROP TABLE IF EXITS " + TABLE_NAME;
    db.execSQL(DROP_TABLE);
    onCreate(db);
}

在数据库中插入一个联系人,传入一个联系人对象即可,插入一个数据库项

public long insert(Contact entity) {
    SQLiteDatabase db = getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("_no", entity.getNo());
    values.put("_name", entity.getName());
    values.put("_pnumber", entity.getPhoneNumber());
    long id = db.insert(TABLE_NAME, null, values);
    db.close();
    return id;
}

在数据库中更新联系人,根据传入的联系人学号查找数据库,将新的数据覆盖原来数据库中的数据即可更新

public int update(Contact entity) {
    SQLiteDatabase db = getWritableDatabase();
    String whereClause = "_no = ?";
    String[] whereArgs = { entity.getNo() };

    ContentValues values = new ContentValues();
    values.put("_no", entity.getNo());
    values.put("_name", entity.getName());
    values.put("_pnumber", entity.getPhoneNumber());

    int rows = db.update(TABLE_NAME, values, whereClause, whereArgs);
    db.close();
    return rows;
}

在数据库中删除联系人,根据传入的联系人的学号查找数据库,找到后删除即可

public int delete(Contact entity) {
    SQLiteDatabase db = getWritableDatabase();
    String whereClause = "_no = ?";
    String[] whereArgs = { entity.getNo() };

    int rows = db.delete(TABLE_NAME, whereClause, whereArgs);
    db.close();
    return rows;
}

在数据库中查询数据库表头,使用query方法参数全部为空即可匹配数据库表的第一项,返回内容是指向第一项的指针类,可以向后遍历表格中的项

public Cursor query() {
    SQLiteDatabase db = getReadableDatabase();
    return db.query(TABLE_NAME, null, null, null, null, null, null);
}

为ListView建立一个MySimpleAdapter类继承自SimpleAdapter,可以方便地绑定到ListView中

public class MySimpleAdapter extends SimpleAdapter {
    private ArrayList<Map<String, String>> mData;

    public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data,
                           int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
        this.mData = (ArrayList<Map<String, String>>)data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int mPosition = position;
        return super.getView(position, convertView, parent);
    }
}

准备工作已经做好了,剩下的就是程序的逻辑编写。
进入主界面需要更新ListView的内容,使用刚才写好的query方法访问数据库中全部的内容,加入到一个List中,并通过该List和之前写好的ListView Item Layout创建一个MySimpleAdapter绑定到ListView中,完成更新。由于这步工作在后续的添加联系人、修改联系人和删除联系人中都使用到,因此封装成一个函数以便调用。

private void setData(List<Map<String, String>> mDataList) {
    Map<String, String> mData;
    Cursor c = myDatabaseHelper.query();
    while (c.moveToNext()) {
        mData = new HashMap<String, String>();
        mData.put("no", c.getString(c.getColumnIndex("_no")));
        mData.put("name", c.getString(c.getColumnIndex("_name")));
        mData.put("pnumber", c.getString(c.getColumnIndex("_pnumber")));
        mDataList.add(mData);
    }
}

private void updateListView() {
    dataList.clear();
    setData(dataList);
    MySimpleAdapter mySimpleAdapter = new MySimpleAdapter(this, dataList, R.layout.contact_item,
            new String[] { "no", "name", "pnumber" },
            new int[] { R.id.contact_no, R.id.contact_name, R.id.contact_phonenumber });
    ListView lv = (ListView)this.findViewById(R.id.lv_contact);
    lv.setAdapter(mySimpleAdapter);
}

当用户点击添加按钮的时候,跳转到次界面,并传递消息给次界面是通过Add按钮跳转到这里来的,使用startActivityForResult方法,并设定Add按钮的requestCode为1

Button btnAdd = (Button)this.findViewById(R.id.btn_add);
btnAdd.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(MainActivity.this, DetailActivity.class);
        Bundle bundle = new Bundle();
        bundle.putBoolean("AddorNot", true);
        intent.putExtras(bundle);
        int requestCode = 1;
        startActivityForResult(intent, requestCode);
    }
});

次界面中根据主界面传递进来的消息,更新界面,显示是否是添加联系人或者修改联系人,如果是添加联系人,界面全部字段为空,如果是修改联系人,填入原本的联系人信息到界面字段中

Bundle bundle = getIntent().getExtras();
final boolean addOrNot = bundle.getBoolean("AddorNot");
if (addOrNot) {
    tvTitle.setText(getResources().getString(R.string.titleAdd));
    edtNo.setText("");
    edtName.setText("");
    edtPNumber.setText("");
} else {
    tvTitle.setText(getResources().getString(R.string.titleModify));
    edtNo.setText(bundle.getString("oldNo"));
    edtName.setText(bundle.getString("oldName"));
    edtPNumber.setText(bundle.getString("oldPNumber"));
}

当用户在次界面点击按钮的时候,用正则表达式判断输入是否符合学号和手机号码的规则,以及姓名不能为空,然后根据是添加联系人或者修改联系人设定返回信息,并传递联系人消息回主界面

Button btnConfirm = (Button)this.findViewById(R.id.btn_confirm);
btnConfirm.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String newNo = edtNo.getText().toString();
        String newName = edtName.getText().toString();
        String newPNumber = edtPNumber.getText().toString();

        if (!newNo.matches("^[1-9]\\d{7}$")
                || !newPNumber.matches("^[1-9]\\d{10}$")
                || newName.isEmpty()) {
            Toast.makeText(getApplicationContext(), getResources().getString(R.string.msgWarning),
                    Toast.LENGTH_SHORT).show();
            return;
        }

        Intent intent = new Intent();
        intent.putExtra("_newNo", newNo);
        intent.putExtra("_newName", newName);
        intent.putExtra("_newPNumber", newPNumber);
        int resultCode = 0;
        if (addOrNot)   resultCode = 1;
        else            resultCode = 2;

        DetailActivity.this.setResult(resultCode, intent);
        DetailActivity.this.finish();
    }
});

主界面需要重载onActivityResult方法捕获从次界面传递回来的消息,判断是否为更新联系人或者添加联系人,然后均需要更新整个界面

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("Hint", "requestCode = " + requestCode);
    Log.d("Hint", "resultCode = " + resultCode);
    if (resultCode == 0)
        return;
    String newNo = data.getStringExtra("_newNo");
    String newName = data.getStringExtra("_newName");
    String newPNumber = data.getStringExtra("_newPNumber");
    switch (requestCode) {
        case 1:
            myDatabaseHelper.insert(new Contact(newNo, newName, newPNumber));
            break;
        case 2:
            myDatabaseHelper.update(new Contact(newNo, newName, newPNumber));
            break;
        default:
            break;
    }
    updateListView();
}

点击联系人进入修改联系人界面(次界面),传递消息告诉次界面为修改联系人,设置相应的requestCode为2

ListView lv = (ListView)this.findViewById(R.id.lv_contact);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        ListView listView = (ListView) parent;
        HashMap<String, String> map = (HashMap<String, String>)listView.getItemAtPosition(position);

        Intent intent = new Intent(MainActivity.this, DetailActivity.class);
        Bundle bundle = new Bundle();
        bundle.putBoolean("AddorNot", false);
        bundle.putString("oldNo", map.get("no"));
        bundle.putString("oldName", map.get("name"));
        bundle.putString("oldPNumber", map.get("pnumber"));
        intent.putExtras(bundle);
        int requestCode = 2;
        startActivityForResult(intent, requestCode);
    }
});

当长按联系人的时候,弹出弹窗询问是否需要删除联系,如果用户选择是删除联系人,则使用数据库的delete方法,并更新界面

lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        ListView listView = (ListView) parent;
        final HashMap<String, String> map = (HashMap<String, String>)listView.getItemAtPosition(position);
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setMessage("确认删除吗?");
        builder.setTitle("提示");
        builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                try {
                    myDatabaseHelper.delete(new Contact(map.get("no"), map.get("name"), map.get("pnumber")));
                    updateListView();
                } catch (Exception e) {
                    Log.d("Hint", "Remove failed!");
                }
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                // nothing to do
            }
        });
        builder.show();
        return true;
    }
});

基本逻辑完成,但是程序有bug,在下面会说到

效果图

初始化界面->点击添加->填入错误信息点击确定->填入正确信息

cant showcant showcant showcant show

正确信息确定后主界面增加->点击张三进入修改->修改为正确内容->确定确定后更新

cant showcant showcant showcant show

长按李四提示是否删除->点击确认删除后更新界面

cant showcant show

一些总结

当用户在次界面点击返回按钮的时候,因为主界面会捕获消息并进行相应的处理,但是返回键是没有消息返回的,因此需要重载返回按钮,否则整个程序会崩溃。通过设置resultCode为0,以区分是用返回键返回的

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK) {
        int resultCode = 0;
        DetailActivity.this.setResult(resultCode);
        DetailActivity.this.finish();
    }
    return true;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("Hint", "requestCode = " + requestCode);
    Log.d("Hint", "resultCode = " + resultCode);
    if (resultCode == 0)
        return;
}

工程下载

传送门:下载

转载于:https://www.cnblogs.com/wsine/p/5177542.html

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android开发实验---通讯录 实验报告 通讯录 姓名: 学号: 课程名称: 移动应用开发 所在学院: 信息科学与工程学院 专业班级: 计算机 任课教师: Android开发实验---通讯录全文共25页,当前为第1页。 Android开发实验---通讯录全文共25页,当前为第1页。 实验项目名称 通讯录 实验目的与要求: 目的:练习掌握 Android 软件开发基本编程技术、Android 系统 SQLite 数据库的使用、通话、短信的使用等,设计制作一 Android 通讯录软件。 要求: (1)每位同学独立设计软件功能、完成软件的开发与测试。 (2)软件完成后由任课教师检查、提问软件功能、软件的设计和开发的代码。(3)每位同学独立完成实验报告(包括学号、姓名,实验目的、实验内容、软件功能、设计思想、实验总结等),并将实验报告和开发软件的工程文件压缩包提交任课教师。 实验设备及软件: 一台电脑,Androidstudio2.3.3软件 实验方法(原理、流程图) 实现的通讯录功能和界面可在实验开发中由每位同学自己设计,但必须使用 SQLite 数据库保存通讯录信息。 以下功能和软件界面供参考:仿照一般手机通讯录的使用界面和功能,主要功能可包括: (1)可以添加、删减联系人 (2)联系人的信息包括:姓名、手机号码、工作单位、群组、电子邮件、手机铃声 (3)选择联系人后,可以快速进行操作,如:拨打电话发送短信、查看详细、移出群组、移动分组、删除联系人等。查看详细时显示手机号码、群组、和设定的手机铃声以及同该联系人的通话记录。 (4)在联系人界面,可以查看各群组。点击群组,跳出对应联系人。 (5)有拨号键盘,点击数字将号码显示出来,并可以对手机号码进行删减 (6)可以发送信息,显示信息记录 (7)发送信息时,可以快速选择现有联系人。 实验过程、步骤及内容 通讯录界面要求布局合理简约,颜色舒,控制按钮简单明了,让用户一眼就能看出各个按钮的作用及操方法。能实要求的功能,但又不重复。要考到不同手机屏幕大小可能不一样,应尽兼容大多数手机屏幕尺寸,使之显示无障碍。 实现思路与简单设计 1. 关于通讯录获取联系人信息以及联系人信息的存储结构的分析。 2. 解决添加联系人的表中添加数据以及读取已保存的数据 3. 实现通讯录的基本功能的具体实现。 4. 对通讯录界面的具体设计,给人一种方便的操作通道。 5. 灵活应用各种系统库函数实现完整的通讯录。 Android开发实验---通讯录全文共25页,当前为第2页。开发流程图: Android开发实验---通讯录全文共25页,当前为第2页。 主要功能分析: 增加、删除、编联系人 点击通信录界面中的增加按钮,入增加联系人面。输入联系人的基本信息,并可根据用户需求增加个性化信息如头像、姓名、手机号码、办室电话、家庭电话、职务职称、单位名称、地址、邮政编码、Email、其他联系方式、备注这些信息,击确认返回主界面。点击通信录中一个已存在的联系人,进入联系人编辑界面,可修改系人的资料或进行删除联系人操作,完成后退回到主界面。对列表联系人的标记,点mnu键弹出功能界面上的删除按键也可进行删除。还可以在菜单上选择删除全部联系人清空通讯录。在删除联系人的过程中,系统将提示用户是否继续操作,若放弃操作,则系人信息将继续保存。 2、查找联系人 用户点击menu键打开底部菜单框,底部菜单框为查询系人提供入口,进入通讯录的缺省页面为联系人列表,在列表中看到所有联系人的姓名、电话息排列,用户点击查找按键输入联系人基本信息,,通讯录显所有符合查询条件的联系人列表,用户选择一个联系人进入联系人基本信息页面进行其他操作;查询完成,用户按返回键返回主界面。 3、通功能 用户在通录选择联系人进入联系详细信息界面,这时点击menu键打开通信功能框,选择打电话、发信息的功能进行操作。 4、菜单能 通过对menu按的点击,显示底部菜框,包含有增加查找、除、菜单、返回功能,菜单按键则包含显示所有、删除所有等实用功能。 增加联系人: 这个功能由ContactAdder类完成,具体实现不是比较麻烦,保存动作由ContentResolver类解决,但实现方式有所不同,可分为一次性批量增加与挨个增加。 由于界面设置繁琐,代码页过多,所以挑出其中的一部分进行说明 首先是DB数据库建库过程: Android开发实验---通讯录全文共25页,当前为第3页。package com.xample.hivian.my_contact_manager.models.db; import android.content.ContentValues; import android.database.Cursor; import android.database.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值