Android实验之实现一个生日备忘簿

本文详述了一个Android实验,通过SQLite数据库和ContentProvider实现生日备忘簿应用。实验要求包括创建数据库存储生日信息,使用ContentProvider获取联系人电话,以及实现界面交互如增加、查看、修改和删除生日条目。实验涵盖了Android界面编程、数据库操作及内容提供者的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.实验内容

实现一个生日备忘簿

二.实验目的

1. 学习 SQLite 数据库的使用;

2. 学习ContentProvider的使用;

3. 复习Android界面编程。
     

三.实验要求

1、 使用 SQLite 数据库保存生日的相关信息,使得每次运行程序都可以显示出已经存储在数据库里的内容;

2、 使用 ContentProvider 来获取对应寿星的电话号码;

3、功能简介

1) 主界面包含增加生日条目按钮和生日信息列表

2) 点击<增加条目>按钮跳转到次界面;

3) 次界面输入生日相关信息后点击<增加>按钮会返回主界面(同时更新主界面的生日 信息列表),且姓名字段不能为空,姓名字段不能重复

4) 主界面中的列表点击事项处理:
  a) 单击(查看并可修改该生日条目):
     i. 弹出对话框,显示该条目的相关信息,并提供修改。
     ii. 同时,显示该生日条目寿星的电话号码;
    iii. 点击<保存修改>按钮,更新主界面的生日信息列表 b) 长按(可删除该生日条目)
  b) 长按
     i. 弹出对话框,显示是否删除;
    ii. 点击<是>按钮,删除该生日条目,并更新主界面的生日信息列表

四.实验步骤

  1. 实现主页面和次页面。主页面的布局为一个RelativeLayout, 布局下为一个按钮,三个文本,以及一个LIstview。次页面的布局为一个TableLayout和一个按钮。

  2. 在实现主页面和次页面之后,在MainActivity.java里面实现点击增加条目按钮,页面跳转。

    // "增加条目"按钮的点击函数
    Button btn_add = (Button)findViewById(R.id.btn_add);
    btn_add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, new_Infor.class);
            startActivity(intent);
        }
    });
  3. 在实验次页面的逻辑功能之前,先创建一个SQLiteOpenHelper的子类和数据库。

    public class myDB extends SQLiteOpenHelper {
        private static final String DB_NAME = "MyDatabase";
        private static final String TABLE_NAME = "MyTable";
        private static final int DB_VERSION = 1;
    
        // 调用父类构造函数
        public myDB(Context context) {     
            super(context, DB_NAME, null, DB_VERSION);
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            String CREATE_TABLE = "CREATE TABLE if not exists "
                    + TABLE_NAME
                    + " (_id INTEGER PRIMARY KEY, name TEXT, birthday TEXT, gift TEXT)";
            sqLiteDatabase.execSQL(CREATE_TABLE); // 直接执行创建数据库的语句
        }
    
        @Override
        public  void  onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        }
    }
    
  4. 实现次页面的逻辑功能。点击增加按钮,检测名字是否为空、重复,并将数据插入到数据库中。重写OnCreate代码如下:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new__infor);
        //  创建一个myDB类的实例
        final myDB dataHelper = new myDB(new_Infor.this);
        // 获取布局控件
        final EditText edit_name = (EditText) findViewById(R.id.name_input);
        final EditText edit_birthday = (EditText) findViewById(R.id.birthday_input);
        final EditText edit_gift = (EditText) findViewById(R.id.gift_input);
        // 增加按钮的监听函数
        Button btn_add = (Button) findViewById(R.id.btn_new_add);
        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取输入文本
                String name = edit_name.getText().toString();
                String birth = edit_birthday.getText().toString();
                String gift = edit_gift.getText().toString();
                if (name.equals("")) { // 名字不能为空
                    Toast.makeText(getApplicationContext(), R.string.emptyName,Toast.LENGTH_LONG).show();
                } else {
                    // 在执行查找操作之前,先getReadableDatabase获取一个数据库实例
                    SQLiteDatabase dbRead = dataHelper.getReadableDatabase();
                    Cursor cursor = dbRead.rawQuery("select * from MyTable", null);
                    while (cursor.moveToNext()) { // 遍历全表
                        // 获取表中每一行name列的文本内容
                        String db_name = cursor.getString(cursor.getColumnIndex("name"));
                        if (name.equals(db_name)) {  // 如果输入名字已在数据库中
                            Toast.makeText(getApplicationContext(), R.string.duplicateName,
                                Toast.LENGTH_LONG).show();
                            return;
                        }
                    }
                    cursor.close();  // 关闭游标, 释放资源
                    // 在执行插入操作之前,先getWritableDatabase获取一个数据库实例
                    SQLiteDatabase db = dataHelper.getWritableDatabase();
                    ContentValues cv = new ContentValues();
                    cv.put("name", name);
                    cv.put("birthday", birth);
                    cv.put("gift", gift);
                    db.insert("MyTable", null, cv);
                    db.close();
                    // 页面跳转到主页面
                    Intent intent = new Intent(new_Infor.this, MainActivity.class);
                    startActivity(intent);
                }
            }
        });
    }
    
  5. 实现listview里面item的布局之后,在MainActivity.java里面获取数据库中的数据,并利用SimpleAdapter把数据显示到Listview中。

    final myDB dataHelper = new myDB(getApplicationContext());
    // 查询数据库中的所有数据
    SQLiteDatabase db = dataHelper.getReadableDatabase();
    final Cursor cursor = db.rawQuery("select * from MyTable", null);
    final List<Map<String, Object>> data = new ArrayList<>();
    while (cursor.moveToNext()) {
        String name = cursor.getString(cursor.getColumnIndex("name"));
        String birth = cursor.getString(cursor.getColumnIndex("birthday"));
        String gift = cursor.getString(cursor.getColumnIndex("gift"));
        Map<String, Object> temp = new LinkedHashMap<>();
        temp.put("name", name);
        temp.put("birthday", birth);
        temp.put("gift", gift);
        data.add(temp);
    }
    cursor.close();
    
    // 将数据显示到listView中
    final ListView listView = (ListView)findViewById(R.id.listView);
    final SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.item,
            new String[] {"name", "birthday", "gift"},
            new int[] {R.id.name, R.id.birthday, R.id.gift});
    listView.setAdapter(simpleAdapter);   
  6. 实现长按列表项弹出对话框,询问是否删除,并实现对应的逻辑功能。

    // 列表项的长按
    listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setMessage(R.string.confirmDelete)
                .setTitle(R.string.hint)
                .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 获取对应的姓名
                        String nameToDelete = data.get(position).get("name").toString();
                        // 更新listView的显示
                        data.remove(position);
                        simpleAdapter.notifyDataSetChanged();
                        // 删除数据库中对应的列表项
                        SQLiteDatabase db = dataHelper.getWritableDatabase();
                        db.delete("MyTable", "name=?", new String[] {nameToDelete});
                        db.close();
                    }
                })
                .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .create().show();
        return true;
    }
    });
    
  7. 长按列表项,弹出自定义对话框,显示对应姓名的基本信息,并获取通讯录中的联系电话。

    // 列表项的单击
    listView .setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
            try {
                // 自定义对话框
                LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
                final View newView = inflater.inflate(R.layout.dialoglayout, null);
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setView(newView);
    
                // 填充文本内容,这里一定要注意用newView这个layout来findViewById
                final TextView textName = (TextView) newView.findViewById(R.id.personName);
                final EditText editBirthday = (EditText) newView.findViewById(R.id.editBirthday);
                final EditText editGift = (EditText) newView.findViewById(R.id.editGift);
                TextView telephone = (TextView) newView.findViewById(R.id.telephone);
    
                final String personName = data.get(position).get("name").toString();
                textName.setText(personName);
                editBirthday.setText(data.get(position).get("birthday").toString());
                editGift.setText(data.get(position).get("gift").toString());
    
                builder.setPositiveButton(R.string.saveChanged, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 保存修改,更新数据库
                        SQLiteDatabase db = dataHelper.getWritableDatabase();
                        ContentValues cv = new ContentValues();
                        cv.put("birthday", editBirthday.getText().toString());
                        cv.put("gift", editGift.getText().toString());
                       db.update("MyTable", cv, "name=?", new String[]{personName});
                        // 更新listView显示
                        data.get(position).put("birthday", editBirthday.getText().toString());
                        data.get(position).put("gift", editGift.getText().toString());
                        simpleAdapter.notifyDataSetChanged();
                    }
                }).setNegativeButton(R.string.discardChanged, null).create().show();
    
    
                // 使用getContentResolver方法读取联系人列表
                Cursor cursor1 = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
                        null, null, null, null);
                boolean find = false;  // 判断是否找到联系人的电话
                // 遍历查询结果
                while (cursor1.moveToNext()) {
                    // 获取联系人ID
                    String contactId = cursor1.getString(cursor1.getColumnIndex(
                                        ContactsContract.Contacts._ID));
                    // 获取联系人名字
                    String Name = cursor1.getString(cursor1.getColumnIndex(
                                        ContactsContract.Contacts.DISPLAY_NAME));
                    // 判断某条联系人的信息中,是否有电话号码
                   if (Name.equals(personName)) {
                        find = true;
                        Cursor phone = getContentResolver().query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null,
                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId,
                                null, null);
                        if (phone.moveToNext()) {
                            // 获取联系电话
                            String phoneNumber = phone.getString(phone.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.NUMBER));
                            // 显示电话
                            String newText = telephone.getText().toString() + phoneNumber;
                            telephone.setText(newText);
                        }
                        phone.close();
                    }
                }
                cursor1.close();
                if (!find) {
                    String newText = telephone.getText().toString() + "无";
                    telephone.setText(newText);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    
  8. 设置次页面的no-history属性为true,使得创建一个新的条目后,点击返回键不会回到刚才的编辑页面。同时在MainActivity.java里面重写OnKeyDown函数,使得点击返回键直接返回桌面,而不会在修改联系人信息之后,点击返回键页面显示修改前的信息。

    <activity android:name=".new_Infor" android:noHistory="true"></activity>
    // 重写onKeyDown,点击返回键按钮直接返回桌面
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            Intent home = new Intent(Intent.ACTION_MAIN);
            home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            home.addCategory(Intent.CATEGORY_HOME);
            startActivity(home);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

五.实验截图

  1. 主页面

    这里写图片描述

  2. 点击增加按钮,跳转到新页面,输入信息。

    这里写图片描述

  3. 点击增加按钮,页面跳回主页面。可见正常显示。

    这里写图片描述

  4. 单击新增加的列表项,弹出自定义对话框。显示对应姓名的具体信息。

    这里写图片描述

  5. 修改礼物信息,点击保存按钮。

    这里写图片描述

    可见页面显示修改后的内容。

    这里写图片描述

  6. 长按列表项,弹出对话框,提示是否删除。

    这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值