实例解析Android系统中的ContentProvider组件用法

ContentProvider为Android四大组件之一,主要用来应用程序之间的数据共享,也就是说一个应用程序用ContentProvider将自己的数据暴露出来,其他应用程序通过ContentResolver来对其暴露出来的数据进行增删改查。
ContenProvider与ContentResolver之间的对话同过Uri(通用资源标识符),一个不恰当的比喻就好像浏览器要显示一个网页要有一个东西发送请求,这相当于ContentResolver,你要拿东西就要知道去哪里拿,你就得知道服务器的域名或网址,而这个网址就相当于Uri,当到达服务器的时候服务器要有个东西来处理,这就相当于ContenProvider。

A程序通过ContenProvider来暴露数据的基本步骤:
1、实现一个ContenProvider的子类,并重写query,insert,update,delete等这几个方法,
2、在androidmanifest.xml中注册ContenProvider,指定的android:authorities属性
B程序通过ContentResolver来操作A程序暴露出来的数据的基本步骤
1、通过content的getContentResolver()来获取ContentResolver对象
2、通过ContentResolver对象来query,insert,update,delete来进行操作
在实现query,insert,update,delete时有一个重要的参数Uri类,Uri一个中要的方法Uri.parse(String str)用来解析str字符串,而str字符串格式一般都有A程序提供给B程序,B程序按照指定的格式去请求 。比如:content//:com.android.xiong.ConentProviderTestA.firstContentProvider/xiong 其格式一般分为三个部分:content//:这部分是固定不变的 而com.android.xiong.ConentProviderTestA.firstContentProvider表A程序在androidmanifest.xml注册的android:authorities属性,xiong则表示资源部分

<provider
      android:name="com.android.xiong.conentprovidertesta.FirstContentProvider"
      android:authorities="com.android.xiong.ConentProviderTestA.firstContentProvider"
      android:exported="true" >
</provider>

实例如下

A程序:
UserInfo.java

package com.android.xiong.conentprovidertesta; 

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; 

public class FirstContentProvider extends ContentProvider { 

  // UriMatcher类主要用来匹配Uri
  private static final UriMatcher uriMatcher = new UriMatcher(
      UriMatcher.NO_MATCH);
  private MySqlite mysqlite;
  static {
    // 注册向外部程序提供的Uri
    uriMatcher.addURI(UserInfo.AUTOR, "userinfo", 1);
    uriMatcher.addURI(UserInfo.AUTOR, "userinfoall", 2);
  }
  //删除数据
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    int number = 0;
    if (uriMatcher.match(uri) == 1) {
      // 根据条件删除数据,并获取删除的行数
      number = mysqlite.getReadableDatabase().delete("user_info",
          selection, selectionArgs);
    }
    // 通知数据已经改变
    getContext().getContentResolver().notifyChange(uri, null);
    return number;
  } 

  @Override
  public String getType(Uri uri) { 

    return null;
  }
  //插入数据
  @Override
  public Uri insert(Uri uri, ContentValues values) {
    String name = values.getAsString(UserInfo.User.NAME).toString();
    String age = values.getAsInteger(UserInfo.User.AGE).toString();
    String maxId = "select max(id) id from user_info";
    Cursor cursor = mysqlite.getReadableDatabase().rawQuery(maxId, null);
    cursor.moveToFirst();
    int userid = cursor.getInt(0) + 1;
    if (uriMatcher.match(uri) == 1) { 

      mysqlite.getWritableDatabase().execSQL(
          "insert into user_info values(?,?,?)",
          new String[] { String.valueOf(userid), name, age });
    }
    return uri;
  } 

  // 连接数据库
  @Override
  public boolean onCreate() {
    mysqlite = new MySqlite(getContext(), "userinfo.db", null, 1);
    return true;
  }
  //查询数据
  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
      String[] selectionArgs, String sortOrder) {
    SQLiteDatabase sqlite = mysqlite.getReadableDatabase();
    String str = "select name,age from user_info";
    if (uriMatcher.match(uri) == 1) {
      str += " where " + selection;
    }
    Cursor cursor = sqlite.rawQuery(str, selectionArgs);
    return cursor;
  }
  //修改数据
  @Override
  public int update(Uri uri, ContentValues values, String selection,
      String[] selectionArgs) {
    SQLiteDatabase sqlite = mysqlite.getReadableDatabase();
    int number = 0;
    if (uriMatcher.match(uri) == 1) {
      number = sqlite.update("user_info", values, selection,
          selectionArgs);
    }
    return number;
  } 

}

FirstContentProvider.java

package com.android.xiong.conentprovidertesta; 

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; 

public class FirstContentProvider extends ContentProvider { 

  // UriMatcher类主要用来匹配Uri
  private static final UriMatcher uriMatcher = new UriMatcher(
      UriMatcher.NO_MATCH);
  private MySqlite mysqlite;
  static {
    // 注册向外部程序提供的Uri
    uriMatcher.addURI(UserInfo.AUTOR, "userinfo", 1);
    uriMatcher.addURI(UserInfo.AUTOR, "userinfoall", 2);
  }
  //删除数据
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    int number = 0;
    if (uriMatcher.match(uri) == 1) {
      // 根据条件删除数据,并获取删除的行数
      number = mysqlite.getReadableDatabase().delete("user_info",
          selection, selectionArgs);
    }
    // 通知数据已经改变
    getContext().getContentResolver().notifyChange(uri, null);
    return number;
  } 

  @Override
  public String getType(Uri uri) { 

    return null;
  }
  //插入数据
  @Override
  public Uri insert(Uri uri, ContentValues values) {
    String name = values.getAsString(UserInfo.User.NAME).toString();
    String age = values.getAsInteger(UserInfo.User.AGE).toString();
    String maxId = "select max(id) id from user_info";
    Cursor cursor = mysqlite.getReadableDatabase().rawQuery(maxId, null);
    cursor.moveToFirst();
    int userid = cursor.getInt(0) + 1;
    if (uriMatcher.match(uri) == 1) { 

      mysqlite.getWritableDatabase().execSQL(
          "insert into user_info values(?,?,?)",
          new String[] { String.valueOf(userid), name, age });
    }
    return uri;
  } 

  // 连接数据库
  @Override
  public boolean onCreate() {
    mysqlite = new MySqlite(getContext(), "userinfo.db", null, 1);
    return true;
  }
  //查询数据
  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
      String[] selectionArgs, String sortOrder) {
    SQLiteDatabase sqlite = mysqlite.getReadableDatabase();
    String str = "select name,age from user_info";
    if (uriMatcher.match(uri) == 1) {
      str += " where " + selection;
    }
    Cursor cursor = sqlite.rawQuery(str, selectionArgs);
    return cursor;
  }
  //修改数据
  @Override
  public int update(Uri uri, ContentValues values, String selection,
      String[] selectionArgs) {
    SQLiteDatabase sqlite = mysqlite.getReadableDatabase();
    int number = 0;
    if (uriMatcher.match(uri) == 1) {
      number = sqlite.update("user_info", values, selection,
          selectionArgs);
    }
    return number;
  } 

}

MySqlite.java

package com.android.xiong.conentprovidertesta; 

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper; 

public class MySqlite extends SQLiteOpenHelper { 

  static final String sql = "create table user_info(id int,name varchar(30),age int)"; 

  public MySqlite(Context context, String name, CursorFactory factory,
      int version) {
    super(context, name, factory, version);
    // TODO Auto-generated constructor stub
  } 

  @Override
  public void onCreate(SQLiteDatabase db) {
    //创建数据表
    db.execSQL(sql); 

  } 

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub 

  } 

}

MainActivity.java

package com.android.xiong.conentprovidertesta; 

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper; 

public class MySqlite extends SQLiteOpenHelper { 

  static final String sql = "create table user_info(id int,name varchar(30),age int)"; 

  public MySqlite(Context context, String name, CursorFactory factory,
      int version) {
    super(context, name, factory, version);
    // TODO Auto-generated constructor stub
  } 

  @Override
  public void onCreate(SQLiteDatabase db) {
    //创建数据表
    db.execSQL(sql); 

  } 

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub 

  } 

}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context=".MainActivity" > 

  <TextView
    android:id="@+id/txt1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:text="添加信息"
    android:textSize="20dp" /> 

  <EditText
    android:id="@+id/ed1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="添加name" /> 

  <EditText
    android:id="@+id/ed2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="添加age"
    android:inputType="number" /> 

  <Button
    android:id="@+id/bt1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="提交数据" /> 

    <ListView
      android:id="@+id/lists"
      android:layout_width="match_parent"
      android:layout_height="wrap_content" >
    </ListView> 

</LinearLayout>

item.xml

<?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/item_txt1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    <TextView
    android:id="@+id/item_txt2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/> 

</LinearLayout>

B程序
UserInfo.java

package com.android.xiong.contentprovidertestb; 

//向外部程序提供一个工具类
public class UserInfo { 

  // 获取ContentProvider的“域名”
  public static final String AUTOR = "com.android.xiong.ConentProviderTestA.firstContentProvider"; 

  //定义一个静态内部类,提供ContentProvider可操作的列
  public static final class User { 

    public static final String ID="id";
    public static final String NAME="name";
    public static final String AGE="age";
    //定义该content提供服务的一个Uri
    public static final String uri="content://"+AUTOR+"/userinfo";
    public static final String uriall="content://"+AUTOR+"/userinfoall"; 

  } 

}

MainActivity.java

package com.android.xiong.contentprovidertestb; 

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; 

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.SimpleAdapter;
import android.widget.Toast; 

public class MainActivity extends Activity { 

  private Button bt1, bt2, bt3, bt4;
  private EditText ed1, ed2;
  private ListView list1;
  private ScrollView sc1; 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bt1 = (Button) findViewById(R.id.bt1);
    bt2 = (Button) findViewById(R.id.bt2);
    bt3 = (Button) findViewById(R.id.bt3);
    bt4 = (Button) findViewById(R.id.bt4);
    ed1 = (EditText) findViewById(R.id.ed1);
    ed2 = (EditText) findViewById(R.id.ed2);
    list1 = (ListView) findViewById(R.id.list);
    // 显示所有数据
    list1.setAdapter(adapter(0));
    sc1 = (ScrollView) findViewById(R.id.scr1);
    // 向添加ContentProviderA应用的数据
    bt1.setOnClickListener(new OnClickListener() { 

      @Override
      public void onClick(View v) {
        String eds1 = ed1.getText().toString();
        String eds2 = ed2.getText().toString();
        ContentValues content = new ContentValues();
        if (!eds1.equals("") && !eds2.equals("")) {
          content.put(UserInfo.User.NAME, eds1);
          content.put(UserInfo.User.AGE, eds2);
          MainActivity.this.getContentResolver().insert(
              Uri.parse(UserInfo.User.uri), content);
          Toast.makeText(MainActivity.this, "数据插入成功",
              Toast.LENGTH_LONG).show();
          // 刷新ListView界面
          list1.setAdapter(adapter(0));
        } else {
          Toast.makeText(MainActivity.this, "name和age不能为空",
              Toast.LENGTH_LONG).show();
        } 

      }
    });
    // 根据条件删除ContentProviderA应用的数据
    bt2.setOnClickListener(new OnClickListener() { 

      @Override
      public void onClick(View v) {
        String eds1 = ed1.getText().toString();
        String eds2 = ed2.getText().toString();
        if (!eds1.equals("") || !eds2.equals("")) {
          HashMap<String, String[]> wheres = wheres(eds1, eds2);
          String sql = wheres.get("sql")[0];
          String[] selectags = wheres.get("selectages");
          MainActivity.this.getContentResolver().delete(
              Uri.parse(UserInfo.User.uri), sql, selectags); 

        } else {
          Toast.makeText(MainActivity.this, "请输入删除条件",
              Toast.LENGTH_LONG).show();
        }
        // 刷新ListView界面
        list1.setAdapter(adapter(0));
      }
    });
    // 修改数据
    bt3.setOnClickListener(new OnClickListener() { 

      @Override
      public void onClick(View v) {
        String eds1 = ed1.getText().toString();
        String eds2 = ed2.getText().toString();
        ContentValues values = new ContentValues();
        // 根据条件将列修改为xiong,23
        values.put(UserInfo.User.NAME, "xiong");
        values.put(UserInfo.User.AGE, "23");
        if (!eds1.equals("") || !eds2.equals("")) {
          HashMap<String, String[]> wheres = wheres(eds1, eds2);
          String sql = wheres.get("sql")[0];
          String[] selectags = wheres.get("selectages");
          int i=MainActivity.this.getContentResolver().update(
              Uri.parse(UserInfo.User.uri), values, sql,
              selectags); 

        } else {
          Toast.makeText(MainActivity.this, "请输入删除条件",
              Toast.LENGTH_LONG).show();
        }
        // 刷新ListView界面
        list1.setAdapter(adapter(0)); 

      }
    });
    // 根据条件查询ContentProviderA应用的数据
    bt4.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        if (!ed1.getText().toString().equals("")
            || !ed2.getText().toString().equals(""))
          list1.setAdapter(adapter(1));
        else
          list1.setAdapter(adapter(0));
      }
    });
  } 

  // 用来判别条件
  public HashMap<String, String[]> wheres(String eds1, String eds2) {
    HashMap<String, String[]> where = new HashMap<String, String[]>();
    if (!eds1.equals("") && !eds2.equals("")) {
      String[] sql = { UserInfo.User.NAME + "=? and " + UserInfo.User.AGE
          + " =?" };
      String[] selectages = { eds1, eds2 };
      where.put("sql", sql);
      where.put("selectages", selectages); 

    }
    if (!eds1.equals("") && eds2.equals("")) {
      String[] sql = { UserInfo.User.NAME + "=? " };
      String[] selectages = { eds1 };
      where.put("sql", sql);
      where.put("selectages", selectages); 

    }
    if (eds1.equals("") && !eds2.equals("")) {
      String[] sql = { UserInfo.User.AGE + " =?" };
      String[] selectages = { eds2 };
      where.put("sql", sql);
      where.put("selectages", selectages); 

    }
    return where;
  } 

  // 用来显示数据
  public SimpleAdapter adapter(int i) {
    Cursor cs = MainActivity.this.getContentResolver().query(
        Uri.parse(UserInfo.User.uriall), null, null, null, null);
    String eds1 = ed1.getText().toString();
    String eds2 = ed2.getText().toString();
    if (i == 1) {
      if (!eds1.equals("") || !eds2.equals("")) {
        HashMap<String, String[]> wheres = wheres(eds1, eds2);
        String sql = wheres.get("sql")[0];
        String[] selectags = wheres.get("selectages");
        cs = MainActivity.this.getContentResolver().query(
            Uri.parse(UserInfo.User.uri), null, sql, selectags,
            null);
      } 

    } 

    List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
    while (cs.moveToNext()) {
      Map<String, Object> map = new HashMap<String, Object>();
      map.put("name", cs.getString(0));
      map.put("age", cs.getString(1));
      lists.add(map);
    }
    SimpleAdapter simepl = new SimpleAdapter(MainActivity.this, lists,
        R.layout.item, new String[] { "name", "age" }, new int[] {
            R.id.item_txt1, R.id.item_txt2 });
    return simepl;
  } 

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  } 

}

activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context=".MainActivity" > 

  <ScrollView
    android:id="@+id/scr1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" > 

    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical" > 

      <Button
        android:id="@+id/bt1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="添加" /> 

      <Button
        android:id="@+id/bt2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="删除" /> 

      <Button
        android:id="@+id/bt3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="更改" /> 

      <Button
        android:id="@+id/bt4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="查询" /> 

      <EditText
        android:id="@+id/ed1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入name条件进行增删改查" /> 

      <EditText
        android:id="@+id/ed2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输age条件进行增删改查" />
    </LinearLayout>
  </ScrollView> 

  <ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
  </ListView> 

</LinearLayout>

item.xml

<?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/item_txt1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    <TextView
    android:id="@+id/item_txt2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/> 

</LinearLayout>

监听ContentProvider数据改变
当程序A在执行insert、update、delete时,通过getContext().getContentResolver().notifyChange(uri, null)方法来告诉所有注册在该Uri的监听者数据发生改变

//删除数据
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    int number = 0;
    if (uriMatcher.match(uri) == 1) {
      // 根据条件删除数据,并获取删除的行数
      number = mysqlite.getReadableDatabase().delete("user_info",
          selection, selectionArgs);
    }
    // 通知数据已经改变
    getContext().getContentResolver().notifyChange(uri, null);
    return number;
  }

在B程序通过registerContentObserver(Uri uri,boolean notifyForDescendents, ContentObserver observer)方法来监听A程序的数据改变

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  // 为uri的数据改变注册监听器
  getContentResolver().registerContentObserver(
      Uri.parse("content://com.android.xiong.ConentProviderTestA.firstContentProvider/userinfo"), true,
      new SmsObserver(new Handler()));
}

registerContentObserver中第三个参数为监听实例 ,需要通过继承ContentObserver类,并重写onChange(booleab selfChange)方法,该方法在监听Uri的ContentProvider的数据发生改变时触发该方法

// 提供方自定义的ContentOberver监听器
private final class Observer extends ContentObserver { 

  public SmsObserver(Handler handler) {
    super(handler);
  } 

  @Override
  public void onChange(boolean selfChange, Uri uri) { 

    // 查询发送邮箱中的短息(处于正在发送状态的短信放在发送箱)
    Cursor cursor = getContentResolver().query(
        Uri.parse("content://com.android.xiong.ConentProviderTestA.firstContentProvider/userinfo"), null, null, null, null);
    }
  } 

}
(0)

相关推荐

  • 实例讲解Android中ContentProvider组件的使用方法

    ContentProvider基本使用 为了在应用程序之间交换数据,android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过提供ContentPRovider来实现,其他应用程序就可以通过ContentResolver来操作ContentProvider暴露的数据. 实现ContentProvider的步骤: 1)编写一个类,继承ContentProvid

  • Android ContentProvider实现获取手机联系人功能

    在之前项目中有用到关于获取手机联系人的部分,闲置就想和大家分享一下,话不多说,上代码: java部分: package com.example.content; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle

  • Android ContentProvider查看/读取手机联系人实例

    看到某些App里面有读取联系人的功能,然后自己尝试了一下.发现这个挺简单的.然后自己就做了一个demo给大家,希望借这个demo可以让大家学习一下怎么实现读取手机联系人. 这里我用了两种方法去读取:第一张图片是跳转到系统自带的联系人界面,第二种就是直接去读取让后绑上来显示在主页面.话不多说直接上代码. 记得在AndroidManifest.xml 记得加入这两句,不然就读取不到联系人. <uses-permission android:name="android.permission.RE

  • Android ContentProvider获取手机联系人实例

    在做项目的时候,因为要用到我们自动获取联系人的姓名和电话,就想到了ContentProvider分享数据的功能,这样做既节省了时间,也减少了我们输入错误号码的几率,所以,想在这里把小demo分享给大家,方便以后要用的时候可以看看 我们先看下获取所有联系人的方式,把所有联系人展示在listView上 public void getLinkMan(View view){ //获取联系人 Uri uri=Uri.parse("content://com.android.contacts/raw_con

  • Android 中ContentProvider的实例详解

    Android 中ContentProvider的实例详解 Content Provider 的简单介绍: * Android中的Content Provider 机制可支持在多个应用中存储和读取数据.这也是跨应用 共享数据的唯一方式.在Android系统中,没有一个公共的内存区域,供多个应用共享存储数据: * Android 提供了一些主要数据类型的ContentProvider ,比如:音频.视频.图片和私人通讯录等: 在android.provider 包下面找到一些android提供的C

  • Android数据持久化之ContentProvider机制详解

    本文实例讲述了Android数据持久化之ContentProvider机制.分享给大家供大家参考,具体如下: 一般而言,android操作系统的应用程序所建立的数据只允许自己使用,应用程序彼此间无法借助公用存储器来共享数据,android系统提供了一个机制,即内容提供器(ContentProvider),来公开自己私有的数据到数据内容器,通过该机制,可以供其他应用程序来读取自己内部的数据,当然也可以访问其他应用程序的数据.通常,内容提供器背后都有SQLite数据库的支持,用以存储内容提供内部数据

  • Android应用中使用ContentProvider扫描本地图片并显示

    之前群里面有朋友问我,有没有关于本地图片选择的Demo,类似微信的效果,他说网上没有这方面的Demo,问我能不能写一篇关于这个效果的Demo,于是我研究了下微信的本地图片选择的Demo,自己仿照的写了下分享给大家,希望对以后有这样子需求的朋友有一点帮助吧,主要使用的是ContentProvider扫描手机中的图片,并用GridView将图片显示出来,关于GridView和ListView显示图片的问题,一直是一个很头疼的问题,因为我们手机的内存有限,手机给每个应用程序分配的内存也有限,所以图片多

  • 实例解析Android系统中的ContentProvider组件用法

    ContentProvider为Android四大组件之一,主要用来应用程序之间的数据共享,也就是说一个应用程序用ContentProvider将自己的数据暴露出来,其他应用程序通过ContentResolver来对其暴露出来的数据进行增删改查. ContenProvider与ContentResolver之间的对话同过Uri(通用资源标识符),一个不恰当的比喻就好像浏览器要显示一个网页要有一个东西发送请求,这相当于ContentResolver,你要拿东西就要知道去哪里拿,你就得知道服务器的域

  • 深入解析Android系统中应用程序前后台切换的实现要点

    在介绍程序实现之前,我们先看下Android中Activities和Task的基础知识. 我们都知道,一个Activity 可以启动另一个Activity,即使这个Activity是定义在别一个应用程序里的,比如说,想要给用户展示一个地图的信息,现在已经有一个Activity可以做这件事情,那么现在你的Activity需要做的就是将请求信息放进一个Intent对象里,并且将这个Intent对象传递给startActivity(),那么地图就可显示出来了,但用户按下Back键之后,你的Activi

  • 在Android系统中使用gzip进行数据传递实例代码

    接下来,让我解说一下如何在Android系统中使用gzip进行数据传递 HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术.大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间.作者在写这篇博客时经过测试,4.4MB的文本数据经过Gzip传输到客户端之后变为392KB,压缩效率极高. 一.服务端 服务端有2种方式去压缩,一种可以自己压缩,但是更推荐第二种方式,用PrintWrite

  • Android编程中selector背景选择器用法实例分析

    本文实例讲述了Android编程中selector背景选择器用法.分享给大家供大家参考,具体如下: 在Android开发过程中,经常对某一View的背景在不同的状态下,设置不同的背景,增强用户体验.如果按钮,在按下时,背景变化,如果在代码中动态设置,相对比较麻烦.Android为我们提供了selector背景选择器可以非常方便的解决这一问题. Selector的结构描述: 1.android:state_pressed="true/false" true:表示按下状态下使用,false

  • Android开发中的重力传感器用法实例详解

    本文实例讲述了Android开发中的重力传感器用法.分享给大家供大家参考,具体如下: 重力传感器与方向传感器的开发步骤类似,只要理清了期中的x,y,z的值之后就可以根据他们的变化来进行编程了,首先来看一副图 假设当地的重力加速度值为g 当手机正面朝上的时候,z的值为q,反面朝上的时候,z的值为-g 当手机右侧面朝上的时候,x的值为g,右侧面朝上的时候,x的值为-g 当手机上侧面朝上的时候,y的值为g,右侧面朝上的时候,y的值为-g 了解了重力传感器中X,Y,Z的含义之后下面我们就开始学习如何使用

  • 全面解析Android系统指纹启动流程

    本章主要整理Android 指纹启动流程,侧重于hal和framework部分. 一.从Android系统启动流程看指纹启动流程 下图图片出处  → 第一阶段 Boot ROM,Android设备上电后,首先会从处理器片上ROM的启动引导代码开始执行,片上ROM会寻找Bootloader代码,并加载到内存.主要就是上电让系统启动. 第二阶段 Bootloader开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存. 启动过程中,bootloader(默认是bootable

  • 一文理解Android系统中强指针的实现

    强指针和弱指针基础 android中的智能指针包括:轻量级指针.强指针.弱指针. 强指针:它主要是通过强引用计数来进行维护对象的生命周期. 弱指针:它主要是通过弱引用计数来进行维护所指向对象的生命周期. 如果在一个类中使用了强指针或者弱指针的技术,那么这个类就必须从RefBase这个类进行做继承,因为强指针和弱指针是通过RefBase这个类来提供实现的引用计数器. 强指针和弱指针关系相对于轻量级指针来说更加亲密,因此他们一般是相互配合使用的. 强指针原理分析 以下针对源码的分析都是来源于andr

  • Android开发中include控件用法分析

    本文实例讲述了Android开发中include控件用法.分享给大家供大家参考,具体如下: 我们知道,基于Android系统的应用程序的开发,界面设计是非常重要的,它关系着用户体验的好坏.一个好的界面设计,不是用一个xml布局就可以搞定的.当一个activity中的控件非常多的时候,所有的布局文件都放在一个xml文件中,很容易想象那是多么糟糕的事情!笔者通过自身的经历,用include控件来解决这个问题,下面是一个小例子,仅仅实现的是布局,没有响应代码的设计. user.xml文件内容如下: <

  • Android开发中的数据库事务用法分析

    本文实例讲述了Android开发中的数据库事务用法.分享给大家供大家参考,具体如下: 在android应用程序开发中,在使用到数据库的时候,事务处理是非常重要的. 首先Android数据库操作(特别是写操作)是非常慢的,将所有操作打包成一个事务能大大提高处理速度. 其次是保证数据的一致性,让一个事务中的所有操作都成功执行,或者失败,或者所有操作回滚. 如果您喜欢使用其他平台(如PHP + MySQL),代码通常在一个功能强大的服务器上运行,一般不会被意外中止,但在android平台上,您将会因为

  • Android编程中软键盘基本用法分析

    本文实例讲述了Android编程中软键盘基本用法.分享给大家供大家参考,具体如下: 调用下面代码:(第一次调用显示,再次调用则隐藏,如此反复),this指activity InputMethodManager imm = (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); imm.sh

随机推荐