android中利用ContentProvider管理系统联系人

我们都知道ContentProvider是用来共享数据的,然而android本身就提供了大量的ContentProvider,例如联系人信息,系统的多媒体信息等,这些系统的ContentProvider都提供了供其他应用程序访问的Uri,开发者可以通过ContentResolver来调用系统的ContentProvider提供的insert()/update()/delete()/query()方法,从而实现自己的需求。

1、了解系统联系人的结构

(1)android系统对联系人管理提供了很多的Uri,其中用到最多的几个如下:

  ContactsContract.Contacts.CONTENT_URI:管理联系人的Uri

  ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理联系人电话的Uri

  ContactsContract.CommonDataKinds.Email.CONTENT_URI:管理联系人邮箱的Uri

  ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI:管理联系人地址的Uri

  我们可以根据系统提供的这些Uri去操作系统联系人信息,具体的还有很多CONTENT_URI,可以到ContactsContract.class文件中去查看源码。

(2)表结构

  我们之前说过,ContentProvider是以表的形式来存放这些数据的,系统联系人也是这样,一般存放在data/data/com.android.providers.contacts/databases/contacts2.db中,我们可以通过adb shell命令行的方式来看,也可以将这个contacts2.db文件导出,通过sqlite工具来查看,这里为了方便我们导出来看一下。

找到对应的文件,然后选中点击右上角的导出按钮,将文件导出到系统中的某一个地方

 

将导出的文件用工具打开,我这里使用的是:Navicat Premium

表和视图:

 

我们经常用的到有:contacts、data、raw_contacts三张表:

contacts表:

  _id :表的ID,主要用于其它表通过contacts 表中的ID可以查到相应的数据。
  display_name: 联系人名称
  photo_id:头像的ID,如果没有设置联系人头像,这个字段就为空
  times_contacted:通话记录的次数
  last_time_contacted: 最后的通话时间
  lookup :是一个持久化的储存 因为用户可能会改名子 但是它改不了lookup

data表:

  raw_contact_id:通过raw_contact_id可以找到 raw_contact表中相对的数据。

  data1 到 data15 这里保存着联系人的信息 联系人名称 联系人电话号码 电子邮件 备注 等等

raw_contacts表:

   version :版本号,用于监听变化
  deleted :删除标志, 0为默认 1 表示这行数据已经删除
  display_name : 联系人名称
  last_time_contacts : 最后联系的时间

 【说明:由于这些表的字段都特别多,截图不全,可以自己试着导出一份看看】

2、代码实现

(1)首先要在AndroidManifest.xml文件中配置对系统联系人的读写权限:

<!-- 添加操作联系人的权限 -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />

(2)布局文件

  首先是列表展示页面:

<?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
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:gravity="center_vertical"
        android:text="我的联系人"
        android:textSize="25dp" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="@android:color/darker_gray" >

        <TextView
            android:id="@+id/id"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:text="ID"
            android:gravity="center" />

        <TextView
            android:id="@+id/name"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:text="姓名"
            android:gravity="center" />

        <TextView
            android:id="@+id/phone"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:text="手机号码"
            android:gravity="center" />
        
    </LinearLayout>

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:divider="#FF0000"
        android:dividerHeight="1dp"
        android:focusable="true"
        android:minHeight="40dp"
        android:footerDividersEnabled="false" >
    </ListView>

</LinearLayout>

  列表展示中需要用的listview页面布局:

<?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="horizontal" >
    
    <TextView
        android:id="@+id/id"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:layout_height="40dp"
        />
    <TextView
        android:id="@+id/name"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:layout_height="40dp"
        />
    <TextView
        android:id="@+id/phone"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:layout_height="40dp"
        />

</LinearLayout>

  添加联系人界面:

<?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" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:gravity="center_vertical|right"
            android:text="姓名:"
            android:textSize="20dp" />

        <EditText
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:gravity="center_vertical|right"
            android:layout_marginRight="20dp"
            android:text="手机号码:"
            android:textSize="20dp" />

        <EditText
            android:id="@+id/phone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    
     <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal" >
        
         <Button
             android:id="@+id/save"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="保存"
             android:textSize="20sp"
             />
         
          <Button
             android:id="@+id/cancel"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="取消"
             android:layout_marginLeft="30dp"
             android:textSize="20sp"
             />
         </LinearLayout>

</LinearLayout>

  联系人详细界面:

<?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="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginTop="10dp"
    android:background="@android:color/darker_gray" >

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@android:color/white"
        android:gravity="center_vertical|right"
        android:text="姓名:"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/tv_name"
        android:layout_toRightOf="@+id/tv_name"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:text=""
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_name"
        android:layout_marginTop="20dp"
        android:background="@android:color/white"
        android:gravity="center_vertical|right"
        android:text="手机号:"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/et_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/tv_phone"
        android:layout_toRightOf="@+id/tv_phone"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:text=""
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_email"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_phone"
        android:layout_marginTop="20dp"
        android:background="@android:color/white"
        android:gravity="center_vertical|right"
        android:text="Email:"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/et_email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/tv_email"
        android:layout_toRightOf="@+id/tv_email"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:text=""
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_address"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_email"
        android:layout_marginTop="20dp"
        android:background="@android:color/white"
        android:gravity="center_vertical|right"
        android:text="地址:"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/et_address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/tv_address"
        android:layout_toRightOf="@+id/tv_address"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:text=""
        android:textSize="20sp" />

</RelativeLayout>

  程序中需要用的menu菜单配置在menu文件中:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <group android:id="@+id/group1">
        <item android:id="@+id/detail" android:title="详情"></item>
        <item android:id="@+id/update" android:title="修改"></item>
        <item android:id="@+id/delete" android:title="删除"></item>
    </group>
    
</menu>

(3)Activity代码:

  列表页面以及适配器Adapter

ContactsActivity.java

package com.demo.contentprovider;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.Toast;

import com.demo.adapter.ContactsAdapter;
import com.demo.model.Contact;

/**
 * 手机联系人操作
 * @author yinbenyang
 */
public class ContactsActivity extends Activity {

    private static final int ADD = 0;

    private static final int REQUEST_ADD = 100;

    // 存储联系人的列表
    private ArrayList<Contact> contactList = null;
    // 联系人适配器
    private ContactsAdapter adapter;

    private ListView listview;

    // 弹出式菜单
    public PopupMenu popupmenu = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.contentprovider);
        listview = (ListView) findViewById(R.id.listview);
        init();
        listview.setOnItemLongClickListener(new OnItemLongClickListenerImpl());
        // registerForContextMenu(listview);
    }

    // ----------------------------------------------------选项菜单---------------------------------------------------
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub
        menu.add(0, ADD, 0, "添加");
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        switch (item.getItemId()) {
        case ADD:
            Intent intent = new Intent(this, AddContactActivity.class);
            startActivityForResult(intent, REQUEST_ADD);
            break;
        default:
            break;
        }
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        switch (requestCode) {
        case REQUEST_ADD:
            init();
            break;
        default:
            break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    // 初始化,获取联系人
    private void init() {
        ContentResolver resolver = getContentResolver();
        /**
         * ContactsContract.Contacts.CONTENT_URI:手机联系人的Uri:content://com.android
         * .contacts/contacts
         * sort_key_alt:它里面保存的是联系人名字的拼音字母,例如联系人名字是“李明”,则sort_key保存的是“LI李MING明”,
         * 这样如果是按sort_key或sort_key_alt排序的话,就可以将联系人按顺序排列
         */
        Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,
                null, null, null, "sort_key_alt");
        contactList = new ArrayList<Contact>();
        while (cursor.moveToNext()) {
            Contact contact = new Contact();
            String phoneNumber = null;
            String name = cursor.getString(cursor
                    .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String id = cursor.getString(cursor
                    .getColumnIndex(ContactsContract.Contacts._ID));
            Cursor phoneCursor = resolver.query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "
                            + id, null, null);
            while (phoneCursor.moveToNext()) {
                phoneNumber = phoneCursor
                        .getString(phoneCursor
                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            }
            contact.setId(Integer.parseInt(id));
            contact.setName(name);
            contact.setPhone(phoneNumber);
            contactList.add(contact);
        }
        adapter = new ContactsAdapter(this, contactList);
        listview.setAdapter(adapter);
    }

    private class OnItemLongClickListenerImpl implements
            OnItemLongClickListener {

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                final int position, long id) {
            final ContentResolver resolver = getContentResolver();
            popupmenu = new PopupMenu(ContactsActivity.this, listview);
            popupmenu.getMenuInflater().inflate(R.menu.my_menu,
                    popupmenu.getMenu());
            popupmenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()) {
                    case R.id.detail:
                        String id = contactList.get(position).getId() + "";
                        Intent intent = new Intent(ContactsActivity.this,
                                ContactDetailActivity.class);
                        intent.putExtra("id", id);
                        startActivity(intent);
                        break;
                    case R.id.update:
                        Toast.makeText(ContactsActivity.this, "执行修改操作",
                                Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.delete:
                        new AlertDialog.Builder(ContactsActivity.this)
                                .setTitle("?h除联系人")
                                .setMessage("你确定要删除该联系人吗?")
                                .setPositiveButton("确定", new OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog,
                                            int which) {
                                        int i = resolver
                                                .delete(ContactsContract.RawContacts.CONTENT_URI,
                                                        ContactsContract.Data._ID
                                                                + " = "
                                                                + contactList
                                                                        .get(position)
                                                                        .getId(),
                                                        null);
                                        Toast.makeText(ContactsActivity.this,
                                                i == 1 ? "?h除成功!" : "?h除失?。?quot;,
                                                Toast.LENGTH_SHORT).show();
                                        init();
                                    }
                                })
                                .setNegativeButton("取消", new OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog,
                                            int which) {
                                        dialog.dismiss();
                                    }
                                }).create().show();
                        break;
                    default:
                        break;
                    }
                    // Toast.makeText(ContactsActivity.this,
                    // "你点击了:" + item.getTitle(), Toast.LENGTH_SHORT)
                    // .show();
                    // popupmenu.dismiss();
                    return true;
                }
            });
            popupmenu.show();
            return true;
        }
    }
}

/**
 * <!-- 联系人相关的uri --> content://com.android.contacts/contacts 操作的数据是联系人信息Uri
 * content://com.android.contacts/data/phones 联系人电话Uri
 * content://com.android.contacts/data/emails 联系人Email Uri
 */

ContactsAdapter.java

package com.demo.adapter;

import java.util.ArrayList;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.demo.contentprovider.R;
import com.demo.model.Contact;

/**
 * 联系人的Adapter
 *
 * @author yinbenyang
 */
public class ContactsAdapter extends BaseAdapter {

    private Context context;
    private ArrayList<Contact> listContact;

    public ContactsAdapter(Context context, ArrayList<Contact> listContact) {
        this.context = context;
        this.listContact = listContact;
    }

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

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

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = View
                    .inflate(context, R.layout.listview_contact, null);
            holder = new ViewHolder();
            holder.id = (TextView) convertView.findViewById(R.id.id);
            holder.name = (TextView) convertView.findViewById(R.id.name);
            holder.phone = (TextView) convertView.findViewById(R.id.phone);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Contact con = listContact.get(position);
        holder.id.setText(con.getId().toString());
        holder.name.setText(con.getName());
        holder.phone.setText(con.getPhone());
        return convertView;
    }

    static class ViewHolder {
        TextView id;
        TextView name;
        TextView phone;
    }

}

  添加联系人Activity:

AddContactActivity.java

package com.demo.contentprovider;

import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

/**
 * 添加联系人信息
 * @author yinbenyang
 *
 */
public class AddContactActivity extends Activity implements OnClickListener{

    private EditText name,phone;
    private Button save,cancel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.addcontact);
        name = (EditText) findViewById(R.id.name);
        phone = (EditText) findViewById(R.id.phone);
        save = (Button) findViewById(R.id.save);
        cancel = (Button) findViewById(R.id.cancel);
        save.setOnClickListener(this);
        cancel.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.save:
            String _name = name.getText().toString().replaceAll(" ", "");
            String _phone = phone.getText().toString().replaceAll(" ","");
            ContentValues values = new ContentValues();
             //首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
            Uri rawContactUri =getContentResolver().insert(RawContacts.CONTENT_URI, values);
            long rawContactId = ContentUris.parseId(rawContactUri);
            //往data表入姓名数据
            values.clear();
            values.put(Data.RAW_CONTACT_ID, rawContactId);
            //设置内容类型
            values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
            //设置内容名字
            values.put(StructuredName.GIVEN_NAME, _name);
            getContentResolver().insert(
                    ContactsContract.Data.CONTENT_URI, values);
            
          //往data表入电话数据
            values.clear();
            values.put(Data.RAW_CONTACT_ID, rawContactId);
            values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
            //设置电话号码
            values.put(Phone.NUMBER, _phone);
            //设置电话类型
            values.put(Phone.TYPE, Phone.TYPE_MOBILE);
            getContentResolver().insert(
                    ContactsContract.Data.CONTENT_URI, values);
            this.finish();
            break;
        case R.id.cancel:
            this.finish();
            break;
        default:
            break;
        }
    }
}

  联系人详细页面:

ContactDetailActivity.java

package com.demo.contentprovider;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.TextView;

/**
 * 联系人详细信息
 *
 * @author yinbenyang
 *
 */
public class ContactDetailActivity extends Activity {

    private TextView et_name, et_phone, et_email, et_address;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.contactdetail);
        et_name = (TextView) findViewById(R.id.et_name);
        et_phone = (TextView) findViewById(R.id.et_phone);
        et_email = (TextView) findViewById(R.id.et_email);
        et_address = (TextView) findViewById(R.id.et_address);
        Intent intent = getIntent();
        String id = intent.getStringExtra("id");
        ContentResolver resolver = getContentResolver();

        // 查找姓名
        Cursor nameCursor = resolver.query(
                ContactsContract.Contacts.CONTENT_URI,
                null,
                ContactsContract.Contacts._ID + " = " + id,
                null, null);
        while(nameCursor.moveToNext()){
            et_name.setText(nameCursor.getString(nameCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
        }
        // 查找手机号
        Cursor phoneCursor = resolver.query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
                null, null);
        while (phoneCursor.moveToNext()) {
            et_phone.setText(phoneCursor.getString(phoneCursor
                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
        }
        // 查找邮箱
        Cursor emailCursor = resolver.query(
                ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
                ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + id,
                null, null);
        while (emailCursor.moveToNext()) {
            et_email.setText(emailCursor.getString(emailCursor
                    .getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)));
        }

        // 查找地址
        Cursor addressCursor = resolver.query(
                ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
                null,
                ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID
                        + " = " + id, null, null);
        while (addressCursor.moveToNext()) {
            et_address
                    .setText(addressCursor.getString(addressCursor
                            .getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.DATA)));
        }
    }
}

最后效果图如下。可以实现联系人的添加,删除和修改功能:

 

 
  

时间: 2024-09-27 22:32:39

android中利用ContentProvider管理系统联系人的相关文章

Android 中自定义ContentProvider与ContentObserver的使用简单实例

Android 中自定义ContentProvider与ContentObserver的使用简单实例 示例说明: 该示例中一共包含两个工程.其中一个工程完成了自定义ContentProvider,另外一个工程用于测试该自定义ContentProvider且在该工程中使用了ContentObserver监听自定义ContentProvider的数据变化 以下代码为工程TestContentProvider ContentProviderTest如下: package cn.testcontentp

edittext bitmap-我想在Android中利用EditText(TextView)实现在控件的最右边添加一张位图。。

问题描述 我想在Android中利用EditText(TextView)实现在控件的最右边添加一张位图.. 解决方案 外面一个FramLayou框起来就解决了 解决方案二: 最好的是自定控件,通过canvas画上去,或者再简单点就是做个背景图你懂的 解决方案三: 给你的edittext设置一个下面这个属性,试试 android:drawableRight="@drawable/right_icon" 解决方案四: Android控件之TextView和EditTextAndroid系统

有木有大神提供一下android中利用Service后台服务进行手机截屏功能的代码?

问题描述 有木有大神提供一下android中利用Service后台服务进行手机截屏功能的代码? 有木有大神提供一下android中利用Service后台服务进行手机截屏功能的代码,?跪求!是在已经root权限下的

Android中利用viewflipper动画切换屏幕效果_Android

整个项目的 package com.example.viewflipper; import android.R.integer; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector.OnDoubleTapListener; import android.view.Menu; import android.view.Me

Android中利用NetworkInfo判断网络状态时出现空指针(NullPointerException)问题的解决方法_Android

在Android中,很多人会用如下的方法判断当前网络是否可用: /** * 获取当前网络状态(是否可用) */ public static boolean isNetworkAvailable() { boolean isAalable = false; ConnectivityManager connManager = (ConnectivityManager) BaseApplication.getApplication().getSystemService(Context.CONNECTI

Android中利用动态加载实现手机淘宝的节日特效_Android

相信去年圣诞节打开过手机淘宝的童鞋都会对当时的特效记忆犹新吧:全屏飘雪,旁边还有个小雪人来控制八音盒背景音乐的播放,让人有种身临其境的感觉,甚至忍不住想狠狠购物了呢(误),大概就是下面这个样子滴: 嗯,确实很炫,那么我们一步步去分析是如何实现的: 一.实现下雪的 View 首先,最上面一层的全屏雪花极有可能是一个顶层的View,而这个View是通过动态加载去控制显示的(不更新淘宝也能看到这个效果).那么我们先得实现雪花效果的 View,人生苦短,拿来就用.打开 gank.io,搜索"雪花&quo

Android中利用动态加载实现手机淘宝的节日特效

相信去年圣诞节打开过手机淘宝的童鞋都会对当时的特效记忆犹新吧:全屏飘雪,旁边还有个小雪人来控制八音盒背景音乐的播放,让人有种身临其境的感觉,甚至忍不住想狠狠购物了呢(误),大概就是下面这个样子滴: 嗯,确实很炫,那么我们一步步去分析是如何实现的: 一.实现下雪的 View 首先,最上面一层的全屏雪花极有可能是一个顶层的View,而这个View是通过动态加载去控制显示的(不更新淘宝也能看到这个效果).那么我们先得实现雪花效果的 View,人生苦短,拿来就用.打开 gank.io,搜索"雪花&quo

Android中利用C++处理Bitmap对象的实现方法

相信有些Android&图像算法开发者和我一样,遇到过这样的状况:要对Bitmap对象做一些密集计算(例如逐像素的滤波),但是在java层写循环代码来逐像素操作明显是不现实的,因为Java代码的运行速度太慢,而一副很小的240*320图像就有76800个像素,如果考虑到RGB三通道(或者ARGB四通道),还要对这个数量乘以3/4.因此对图像的密集计算一般都利用Jni接口,用C++实现.那么问题来了,怎么把Bitmap中的像素数据从Java层传到C++层? 做法1:之前的做法 我之前的做法是这样的

Android中利用viewflipper动画切换屏幕效果

整个项目的 package com.example.viewflipper; import android.R.integer; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector.OnDoubleTapListener; import android.view.Menu; import android.view.Me