精华内容
下载资源
问答
  • 2021-01-10 12:50:02

    功能描述:

    该通讯录app实现了注册、登录、添加联系人、修改、删除联系人等功能,适合新手学习。

    开发语言:

    java

    技术框架:

    mvc

    开发工具:

    AndroidStudio2.2,新手最好使用此版本搭建,不同版本修改配置比较繁琐

    数据库

    sqlite

    程序截图

    代码在公众号:师哥帮忙 中自行下载。

    更多相关内容
  • 摘要:Java源码,Android源码,通讯录 Android contact通讯录实例,比较不错的例子,来自书中的完整实例,Android手机读取联系人信息、显示、保存、编辑联系人,多卡同时读取联系人等,涉及要点:删除指定数据列、URI...
  • 基于Android通讯录课程设计报告.pdf
  • 毕业设计 题 目 基于Android 通讯录管理系统设计与实现 本人严重声明 1持以求实创新的科学精神从事研究工作 2本文是我个人在导师指导下进行的研究工作和取得的研究 成果 3本文除引文外所有实验数据和有关材料均是...
  • 程序是使用 Android studio 开发的简单通讯录 适合刚入门的Android程序员,有对通讯录的增删改查功能,有登录界面 和验证密码功能 有数据库的简单练习
  • 安卓实训设计报告 安卓通讯录 设计题目 安卓通讯录 班 级 姓 名 学 号 指导老师 日 期 2012年6月7日 内容要求 题目分析功能要求 实验目的 熟悉 Android 软件开发的基本架构 利用Eclipse和ADT插件设计通讯录 功能 本...
  • 安卓通讯录

    2017-03-06 21:52:36
    可实现手机通讯录的复制功能。
  • 使用python+pyqt5开发将excel文件里的手机号码批量生成安卓vcf通讯录文件,可批量导入手机通讯录进行保存。
  • android通讯录

    2018-12-05 03:56:30
    Android通讯录小软件(可以导入手机上的联系人、发短信、打电话、增加、修改联系人等
  • 使用adt-bundle-windows编写的android通讯录系统,实现增删改查功能。
  • 对于大多数人来说,随身带个小本子来记录一些即将要处理的事情是很有必要的,从而出现了备忘录。有了随身备忘录,就可以将自己的生活与工作的事情安排的井井有条 当今,智能手机已经走进千家万户,人们对于智能手机...
  • 精致的安卓通讯录

    2021-05-15 06:46:13
    精致的安卓通讯录源码是一套用户体验做的很赞的安卓通讯录和短信项目源码,尤其是号码的拨打界面项目先是根据联系人的名字翻译出对应的汉语拼音名,在输入数字的时候根据数字和字母的两种方式进行联系人匹配。
  • Android 通讯录展示

    2021-05-27 03:17:20
    获取系统通讯录,自定义通讯录展示:基于RecyclerView实现列表展示。image技术:RecyclerView、首字母排序(汉字转拼音)、侧边栏View实现、PopupWindow(气泡)。1、创建通讯录实体类:public class Contact implements...

    获取系统通讯录,自定义通讯录展示:基于RecyclerView实现列表展示。

    ca0e4523332a

    image

    技术:

    RecyclerView、首字母排序(汉字转拼音)、侧边栏View实现、PopupWindow(气泡)。

    1、创建通讯录实体类:

    public class Contact implements Serializable {

    private String letter; // 首字母

    private String name; // 姓名

    private String number; // 号码

    ...

    }

    这里继承了Serializable接口,方便Activity之间传递对象数据。

    2、获取通讯录:

    2.1:申请权限:

    private void initData() {

    if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)

    != PackageManager.PERMISSION_GRANTED){

    String[] list = { Manifest.permission.READ_CONTACTS };

    ActivityCompat.requestPermissions(this, list, 1);

    }else {

    readContacts();

    }

    }

    @Override

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == 1){

    if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){

    readContacts();

    }

    }

    }

    2.2 获取通讯录信息:

    并将通讯录数据简单处理存入ArrayList中

    2.2.1

    获取通讯录数据

    ContentResolver contentResolver = this.getContentResolver();

    Cursor cursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,

    null, null, null, null);

    cursor.getCount();

    ArrayList data = new ArrayList<>();

    while(cursor.moveToNext()) {

    String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));

    String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

    Contact contact = new Contact();

    contact.setName(name);

    contact.setNumber(number);

    data.add(contact);

    }

    cursor.close();

    mContact = filledData(data);

    Collections.sort(mContact, mComparator);

    Collections.sort(mContact, mComparator);是用于对数据进行排序的。

    mComparator是自定义的一个工具类。

    2.2.2

    对通讯录数据进行排序处理:

    // 为list填充数据

    private ArrayList filledData(ArrayList data){

    ArrayList list = new ArrayList<>();

    for (int i = data.size() - 1; i >= 0; i--) {

    Contact sm = new Contact();

    sm.setName(data.get(i).getName());

    sm.setNumber(data.get(i).getNumber());

    String pinyin = mParser.getSelling(data.get(i).getName());

    String sortString = pinyin.substring(0, 1).toUpperCase();

    if (sortString.matches("[A-Z]")) {

    sm.setLetter(sortString);

    } else {

    sm.setLetter("#");

    }

    list.add(sm);

    }

    return list;

    }

    这里mParser用到了一个工具类:

    private CharacterParser mParser = CharacterParser.getInstance();

    用于将汉字转为拼音。

    2.2.3 定义布局文件:

    main_activity.xml,

    view_contact.xml,

    布局可根据自身需求定义。

    2.2.4 实现Adapter:

    常规RecycleView的Adapter定义,这里还添加了一个点击监听和长按监听。以及对通讯录数据进行了简单处理:同一人含有多个号码时;进行合并:

    public class ContactAdapter extends RecyclerView.Adapter {

    private ArrayList mContact;

    public MyItemOnClickListener mListener;

    public MyItemOnLongClickListener mLongListener;

    public static class MyViewHolder extends RecyclerView.ViewHolder {

    private TextView nameView;

    private TextView numberView;

    private TextView letterView;

    private TextView tv_item_tag;

    private RelativeLayout userView;

    public MyViewHolder(View view) {

    super(view);

    nameView = (TextView) view.findViewById(R.id.name);

    numberView = (TextView) view.findViewById(R.id.number);

    letterView = (TextView) view.findViewById(R.id.letter);

    tv_item_tag = (TextView) view.findViewById(R.id.tv_item_tag);

    userView = (RelativeLayout) view.findViewById(R.id.user);

    }

    }

    // 通讯录数据处理

    public ContactAdapter(ArrayList mContact) {

    for (int i = 0; i < mContact.size(); i++) {

    for (int j = i + 1; j < mContact.size(); j++) {

    if (mContact.get(i).getName().equals(mContact.get(j).getName())) {

    String number = mContact.get(i).getNumber() + "\n" + mContact.get(j).getNumber();

    mContact.get(i).setNumber(number);

    mContact.remove(j);

    }

    }

    }

    this.mContact = mContact;

    }

    @NonNull

    @Override

    public ContactAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View v = LayoutInflater.from(parent.getContext())

    .inflate(R.layout.view_contact, parent, false);

    return new MyViewHolder(v);

    }

    @Override

    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {

    String name = String.valueOf(mContact.get(position).getName());

    String number = String.valueOf(mContact.get(position).getNumber());

    String letter = String.valueOf(mContact.get(position).getLetter());

    if (!letterCompareSection(position)) {

    holder.tv_item_tag.setText(letter);

    holder.tv_item_tag.setVisibility(View.VISIBLE);

    } else {

    holder.tv_item_tag.setVisibility(View.GONE);

    }

    holder.nameView.setText(name);

    holder.numberView.setText(number);

    holder.letterView.setText(letter);

    if(mListener != null){

    holder.userView.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

    try {

    mListener.onItemOnClick(v, mContact.get(position));

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    });

    }

    if(mLongListener != null){

    holder.userView.setOnLongClickListener(new View.OnLongClickListener() {

    @Override

    public boolean onLongClick(View v) {

    try {

    mLongListener.onItemLongClick(v, mContact.get(position));

    } catch (IOException e) {

    e.printStackTrace();

    }

    return true;

    }

    });

    }

    }

    @Override

    public int getItemCount() {

    return mContact.size();

    }

    private Boolean letterCompareSection(int position) {

    if (position == 0) {

    return false;

    }

    String letter1 = mContact.get(position).getLetter();

    String letter2 = mContact.get(position - 1 ).getLetter();

    Boolean result = letter1.equals(letter2);

    return result;

    }

    public void setOnItemClickListener(MyItemOnClickListener listener){

    this.mListener = listener;

    }

    public void setOnItemLongClickListener(MyItemOnLongClickListener listener) {

    this.mLongListener = listener;

    }

    public interface MyItemOnClickListener {

    void onItemOnClick(View view, Contact contact) throws IOException;

    }

    public interface MyItemOnLongClickListener {

    void onItemLongClick(View view, Contact contact) throws IOException;

    }

    }

    注意:

    if (!letterCompareSection(position)) {

    holder.tv_item_tag.setText(letter);

    holder.tv_item_tag.setVisibility(View.VISIBLE);

    } else {

    holder.tv_item_tag.setVisibility(View.GONE);

    }

    这里是为了添加一个判断,合并首字母相同的项,将这些项只显示为一类

    ca0e4523332a

    image.png

    Android 中 RecyclerView加载过程中,不是一次吧所有的View全部加载出来的,而是只加载界面能展示的项加上预加载的项,所有有未加载的项加载时,他会从内存中寻找是否有已加载的view,来实现服用,减少资源占用。所以要添加:

    holder.tv_item_tag.setVisibility(View.VISIBLE);

    让其保证该展示的都展示,不然会存在不展示的现象。详情可了解RecyclerView加载机制。

    2.2.6

    MainActivity.java 初始化RecycleView布局:

    binding.recyclerview.setHasFixedSize(true);

    layoutManager = new LinearLayoutManager(this);

    binding.recyclerview.setLayoutManager(layoutManager);

    viewAdapter = new ContactAdapter(mContact);

    viewAdapter.setOnItemClickListener(new ContactAdapter.MyItemOnClickListener() {

    @Override

    public void onItemOnClick(View view, Contact contact) throws IOException {

    Intent intent = new Intent(MainActivity.this, UserActivity.class);

    intent.putExtra("contact", contact);

    startActivity(intent);

    }

    });

    viewAdapter.setOnItemLongClickListener(new ContactAdapter.MyItemOnLongClickListener() {

    @Override

    public void onItemLongClick(View view, final Contact contact) throws IOException {

    initPopWindow(view, contact);

    }

    });

    binding.recyclerview.setAdapter(viewAdapter);

    2.3 添加长按气泡

    ca0e4523332a

    image.png

    使用PopupWindow控件

    这里可以根据菜鸟教程上的介绍学习使用

    我这里进行了简单修改,添加了在上部展示.

    MainActivity.java:

    viewAdapter.setOnItemLongClickListener(new ContactAdapter.MyItemOnLongClickListener() {

    @Override

    public void onItemLongClick(View view, final Contact contact) throws IOException {

    initPopWindow(view, contact);

    }

    });

    private void initPopWindow(View v, final Contact contact) {

    View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.bubble_dialog, null, false);

    Button btn_xixi = (Button) view.findViewById(R.id.buttonDelete);

    //1.构造一个PopupWindow,参数依次是加载的View,宽高

    final PopWindowView popWindow = new PopWindowView(MainActivity.this, view);

    // ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);

    popWindow.setAnimationStyle(R.anim.anim_pop); //设置加载动画

    //这些为了点击非PopupWindow区域,PopupWindow会消失的,如果没有下面的

    //代码的话,你会发现,当你把PopupWindow显示出来了,无论你按多少次后退键

    //PopupWindow并不会关闭,而且退不出程序,加上下述代码可以解决这个问题

    popWindow.setTouchable(true);

    popWindow.setTouchInterceptor(new View.OnTouchListener() {

    // @Override

    // public boolean onTouch(View v, MotionEvent event) {

    // return false;

    // }

    @Override

    public boolean onTouch(View v, MotionEvent event) {

    return false;

    // 这里如果返回true的话,touch事件将被拦截

    // 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss

    }

    });

    popWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));

    popWindow.getBackground().setAlpha(0); //要为popWindow设置一个背景才有效

    //设置popupWindow显示的位置,参数依次是参照View,x轴的偏移量,y轴的偏移量

    popWindow.showUp2(v, 300, 50);

    //设置popupWindow里的按钮的事件

    btn_xixi.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

    mContact.remove(contact);

    viewAdapter.notifyDataSetChanged();

    popWindow.dismiss();

    }

    });

    }

    重写类:PopWindowView,添加在上部显示气泡,

    如果没有这个需求可以不用写此项.直接使用PopupWindow.

    public class PopWindowView extends PopupWindow {

    private int popupWidth;

    private int popupHeight;

    public PopWindowView(Context context, View view) {

    super(context);

    setPopConfig(view);

    }

    /**

    *

    * 配置弹出框属性

    * @version 1.0

    *

    * @createTime 2015/12/1,12:45

    * @updateTime 2015/12/1,12:45

    * @createAuthor

    * @updateAuthor

    * @updateInfo (此处输入修改内容,若无修改可不写.)

    *

    */

    private void setPopConfig(View view ) {

    this.setContentView(view);//设置要显示的视图

    this.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);

    this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);

    this.setOutsideTouchable(true);// 设置外部触摸会关闭窗口

    //获取自身的长宽高

    view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

    popupHeight = view.getMeasuredHeight();

    popupWidth = view.getMeasuredWidth();

    }

    /**

    * 设置显示在v上方(以v的左边距为开始位置)

    * @param v

    */

    public void showUp(View v) {

    //获取需要在其上方显示的控件的位置信息

    int[] location = new int[2];

    v.getLocationOnScreen(location);

    //在控件上方显示

    showAtLocation(v, Gravity.NO_GRAVITY, (location[0]) - popupWidth / 2, location[1] - popupHeight);

    }

    /**

    * 设置显示在v上方(以v的中心位置为开始位置)

    * @param v

    */

    public void showUp2(View v) {

    //获取需要在其上方显示的控件的位置信息

    int[] location = new int[2];

    v.getLocationOnScreen(location);

    //在控件上方显示

    showAtLocation(v, Gravity.NO_GRAVITY, (location[0] + v.getWidth() / 2) - popupWidth / 2, location[1] - popupHeight);

    }

    /**

    * 设置显示在v上方(以v的中心位置为开始位置)

    * @param v, x, y

    */

    public void showUp2(View v, int x, int y) {

    //获取需要在其上方显示的控件的位置信息

    int[] location = new int[2];

    v.getLocationOnScreen(location);

    //在控件上方显示

    showAtLocation(v, Gravity.NO_GRAVITY, (location[0] + v.getWidth()/2) - popupWidth / 2 + x, location[1] - popupHeight + y);

    }

    }

    2.4 侧边栏View:

    MainActivity.java应用:

    binding.viewSidebar.setLetterTouchListener(new SideBarView.LetterTouchListener(){

    @Override

    public void setLetter(String letter) {

    for(int i = 0 ; i < mContact.size(); i++ ){

    if(letter.equals(mContact.get(i).getLetter())){

    binding.recyclerview.scrollToPosition(i);

    }

    }

    }

    });

    SideBarView: 自定义View,主要实现侧边栏.

    2.5 通讯录 个人界面:

    ca0e4523332a

    image.png

    这里也是定义一个RecyclerView,将MainActivity传过来的值进行展示,这里不做详细讲解了.

    Contact user = (Contact)intent.getSerializableExtra("contact");

    if(user != null){

    String number = user.getNumber();

    numbers = number.split("\\n");

    letter = user.getLetter();

    name = user.getName();

    }

    就是对号码进行简单处理,将字符串转成数组.

    getSerializableExtra()方法是intent传对象时使用的,实体类要继承Serializable接口.

    这里还有一个动态申请打电话的权限,

    numberAdapter.setOnItemClickListener(new UserNumberAdapter.MyItemOnClickListener() {

    @Override

    public void onItemOnClick(View view, String number) throws IOException {

    selectNumber = number;

    if(ContextCompat.checkSelfPermission(UserActivity.this, Manifest.permission.CALL_PHONE)

    != PackageManager.PERMISSION_GRANTED){

    String[] list = { Manifest.permission.CALL_PHONE };

    ActivityCompat.requestPermissions(UserActivity.this, list, 1);

    }else {

    call();

    }

    }

    });

    重写回调

    @Override

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == 1){

    if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){

    call();

    }else{

    Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();

    }

    }

    }

    call(),调用系统接口,实现打电话.

    private void call(){

    try {

    if(selectNumber != null){

    Intent intent = new Intent(Intent.ACTION_CALL);

    intent.setData(Uri.parse("tel: " + selectNumber));

    startActivity(intent);

    }

    }catch (SecurityException e){

    e.printStackTrace();

    }

    }

    2.6

    这里的资源文件和样式文件没有把代码贴出来,可以根据自己需求进行更改.

    这里贴一下目录结构:

    ca0e4523332a

    image.png

    ca0e4523332a

    image.png

    9.png图片是绘制的9-Patch图片,也可根据自己需求进行更改.

    2.7

    注意:

    不要忘了添加权限申请

    2.8

    3 项目地址:

    展开全文
  • android通讯录简单实现

    2016-11-16 23:00:47
    android4.3通讯录的简单实现,基本的增删改查都都实现,运用了SQLite数据库
  • 主要介绍了Android仿微信通讯录滑动快速定位功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
  • 源码参考,欢迎下载
  • PAGE PAGE 2 Android实验报告 课程名称 Android应用程序开发 题目名称 Android通讯录 学生学院 计算机学院 班 级 学 号 学生姓名 指导教师 2012年 06 程序名称 Android通讯录 主要功能 本手机通讯录工具主要实现五大...
  • 基于SQLite开发的简易通讯录 共两个页面:启动页+主页面 主页面实现增删改查、读取系统联系人、拨号等功能 非常非常非常简陋,所有功能都在主页面实现,没有封装类
  • Android手机通讯录实验报告 学院安徽机电职业技术学院 专业软件技术 班级软件3141 姓名张程庆小分组 指导老师范宏宇 小组分组详细信息 组长张程庆 文档赵晶蓉 编程蔡婷 刘朝群 宋昱昊 界面江晓雨 测试王健康 目录 ...
  • Android 通讯录

    2017-07-03 17:26:45
    Android 通讯录demo,包含了自定义ItemDecoration实现分类标题以及自定义View实现右侧导航栏
  • Android通讯录详细demo

    2016-04-27 16:53:01
    关于Android通讯录获取及操作详细demo
  • AndroidStduio上开发的,使用开源库Sticky-Header-RecyclerView实现头部挤压效果,具有音序检索和搜索框的简单筛选功能。
  • 安卓简单通讯录 安卓简单通讯录,可以根据侧边字母索引,还有搜索框模糊搜索,添加删除修改通讯录,可以给指定用户拨号或发送短信 接下来就是展示下界面: 主界面 字母索引 添加通讯录 修改通讯录 指定用户功能 ...
  • Android 完整的通讯录项目源码,开源源码,比较适合安卓初学者学习,界面看着还可以,系统能在手机上正常运行!
  • Android通讯录源码.rar

    2021-12-29 12:10:20
    本APP主要实现联系人信息的本地存取,同时兼具打电话和发短信的功能。可适合作为毕业设计使用,欢迎下载
  • 完整的通讯录项目源码.zip

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,850
精华内容 11,140
关键字:

安卓通讯录

友情链接: yycde.zip