当前位置: 编程技术>移动开发
本页文章导读:
▪ContentProvider MIME部类 ContentProvider MIME类型
Android程序的主要4部分:1、Activiyt2、Broadcast Intent Receiver3、Service4、Content Provider一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此Cont.........
▪ 格局像素单位 布局像素单位
Android的layout文件中有时候可能会指定具体的单位,比如有时候为px、dip或者sp等。他们的区别如下:1. px (pixels)像素:这个大家用得比较多, 一般我们HVGA代表320x480像素。2. di.........
▪ 一些技能 一些技巧
1:查看是否有存储卡插入String status=Environment.getExternalStorageState();if(status.equals(Enviroment.MEDIA_MOUNTED)){ 说明有SD卡插入}2:让某个Activity透明OnCreate中不设Layoutthis.setTheme(R.style.Theme_.........
[1]ContentProvider MIME部类
来源: 互联网 发布时间: 2014-02-18
ContentProvider MIME类型
Android程序的主要4部分:
1、Activiyt
2、Broadcast Intent Receiver
3、Service
4、Content Provider
一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。
下面列举一些常用的接口:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
52、ContentResolver
外界程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用ContentResolver实例。其提供的接口与ContentProvider提供的接口对应:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
【实例】
提供ContentProvider的程序:TestSQLite_2_ContentProvider
对其进行访问访问的程序:TestContentProvider_useStudentData
下面进行分析:
【1】要为当前应用程序的私有数据定义URI,就需要专门定义个继承自ContentProvider的类,然后实现各个不同的操作所调用的方法。
首先在该应用程序的某个类中定义所有与数据库操作有关的静态字段,以便打包成jar文件供其他应用程序调用(本例中引用打包好的jar包后会有“找不到类”的错误,故直接将该类,连同包名一同复制到另一个程序中,如)
此例子没有新定义一个专门的类来存放这些字段,而是在继承了SQLiteOpenHelper的类StudentData中定义:
package com.shutao.testsqlite2;
public class StudentData extends SQLiteOpenHelper {
/*
* 分别定义了数据库和表的名称、表中各个字段的名称、数据库的版本号
*/
public final static String DB_NAME = "student";
public final static String TABLE_NAME = "hero";
public final static String SNAME = "name";
public final static String SID = "_id";
public final static int DB_VERSION = 1;
/*
* AUTHORITY:定义了标识ContentProvider的字符串 ;
* ITEM和ITEM_ID分别用于UriMatcher(资源标识符匹配器)中对路径item和item/id的匹配号码
* CONTENT_TYPE和CONTENT_ITEM_TYPE定义了数据的MIME类型。需要注意的是: 单一数据的MIME 类型字符串应该以
* vnd.android.cursor.item/开头,数据集的MIME类型字符串应该以vnd.android.cursor.dir开头
* CONTENT_URI定义的是查询当前表数据的content://样式URI
*/
public static final String AUTHORITY = "com.shutao.testsqlite2.provider.studentdata";
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.shutao.testsqlite2.studentdata";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.shutao.testsqlite2.studentdata";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/item");
public StudentData(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(" + SID
+ " VARCHAR PRIMARY KEY," + SNAME + " VARCHAR NOT NULL);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
}
【2】接下来定义一个继承自ContentProvider的类:MyProvider.java,来实现对数据进行操作的各个方法。这里将用到StudentData来辅助得到SQLiteDatabase对象:
package com.shutao.testsqlite2;
public class MyProvider extends ContentProvider {
StudentData sd;
private static final UriMatcher sMatcher;
static {
// 传入匹配码如果大于0表示匹配根路径或传入-1,即常量UriMatcher.NO_MATCH表示不匹配根路径
// addURI()方法是用来增加其他URI匹配路径的:
// 第一个参数代表传入标识ContentProvider的AUTHORITY字符串
// 第二个参数是要匹配的路径,#代表任意数字,另外还可以用*来匹配任意文本
// 第三个参数必须传入一个大于零的匹配码,用于match()方法对相匹配的URI返回相对应的匹配码
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI(StudentData.AUTHORITY, "item", StudentData.ITEM);
sMatcher.addURI(StudentData.AUTHORITY, "item/#", StudentData.ITEM_ID);
}
/*
* 每当ContentProvider启动时都会回调onCreate()方法。此方法主要执行一些ContentProvider初始化
* 的工作,返回true表示初始化成功,返回false则初始化失败。
*/
@Override
public boolean onCreate() {
sd = new StudentData(this.getContext());
return true;
}
// getType()是用来返回数据的MIME类型的方法。使用sMatcher对URI进行匹配,并返回相应的MIME类型字符串
@Override
public String getType(Uri uri) {
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
return StudentData.CONTENT_TYPE;
case StudentData.ITEM_ID:
return StudentData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
/*
* 插入数据,返回新插入数据的URI,只接受数据集的URI,即指向表的URI
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase sdb = sd.getWritableDatabase();
long rowId;
if (sMatcher.match(uri) != StudentData.ITEM) {
throw new IllegalArgumentException("Unknow URI " + uri);
}
rowId = sdb.insert(StudentData.TABLE_NAME, StudentData.SID, values);
if (rowId > 0) {
Uri noteUri = ContentUris.withAppendedId(StudentData.CONTENT_URI,
rowId);
this.getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
/*
* 用于数据的删除,返回的是所影响数据的数目,首先利用数据库辅助对象获取一个SQLiteDatabase对象
* 然后根据传入Uri用sMatcher进行匹配,对单个数据或数据集进行删除或修改。notifyChange()方法
* 用来通知注册在次URI上的观察者(observer)数据发生了改变。
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.delete(StudentData.DB_NAME, selection, selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.delete(StudentData.DB_NAME, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
/*
* 查询数据,将数据装入一个Cursor对象并返回
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase sdb = sd.getReadableDatabase();
Cursor c;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
c = sdb.query(StudentData.TABLE_NAME, projection, selection,
selectionArgs, null, null, sortOrder);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
c = sdb.query(StudentData.TABLE_NAME, projection, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs, null, null, sortOrder);
break;
default:
Log.i("sMatcher.match(uri)", String.valueOf(sMatcher.match(uri)));
throw new IllegalArgumentException("Query with unknown URI: " + uri);
}
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// 更新,与删除类方法类似
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.update(StudentData.TABLE_NAME, values, selection,
selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.update(StudentData.DB_NAME, values, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
【3】完成以上方法以后,还要AndroidManifest.xml中对这个ContentProvider声明:
<provider
android:name="MyProvider"
android:authorities="com.shutao.testsqlite2.provider.studentdata"/>
<!-- 其中 android:name必须跟定义的ContentProvider的类名一样
android:authorities则指定了content://样式的URI中标识这个ContentProvider的字符串-->
【4】接下来在另一个程序中使用ContentResolver来操作数据:
package com.shutao.contentprovider;
public class TestContentProvider extends Activity {
private EditText stu_name;
private EditText stu_sid;
Button commit;
ListView studList;
ContentResolver resolver;
// 由于在AlertDialog中用到,所以定义为全局变量。
String sid = "";
private final int DIALOG_IN_USED = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stu_name = (EditText) this.findViewById(R.id.edit_name);
stu_sid = (EditText) this.findViewById(R.id.edit_sid);
commit = (Button) this.findViewById(R.id.butt_add);
studList = (ListView) this.findViewById(R.id.show_stud);
//【重要】得到ContentResolver()
resolver = this.getContentResolver();
String[] projection = { StudentData.SNAME, StudentData.SID };
Cursor c = resolver.query(StudentData.CONTENT_URI, null, null, null,
StudentData.SID);
CursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, c, projection, new int[] {
android.R.id.text1, android.R.id.text2 });
studList.setAdapter(adapter);
commit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!(stu_name.getText().length() > 0)) {
Toast.makeText(TestContentProvider.this,
"Please input the student's name!",
Toast.LENGTH_LONG).show();
} else if (!(stu_sid.getText().length() > 0)) {
Toast
.makeText(TestContentProvider.this,
"Please input the student's ID!",
Toast.LENGTH_LONG).show();
} else {
String name = stu_name.getText().toString();
sid = stu_sid.getText().toString();
Uri quri = Uri.parse(StudentData.CONTENT_URI + "/" + sid);
Cursor c = resolver.query(quri, null, null, null, null);
if (c.moveToFirst()) {
// 采用Toast方式提醒
/*
* Toast.makeText(TestContentProvider.this,
* "Fail to add!This ID is already in used!",
* Toast.LENGTH_LONG).show();
*/
// 采用AlertDialog方式提醒
TestContentProvider.this.showDialog(DIALOG_IN_USED);
} else {
ContentValues values = new ContentValues();
values.put(StudentData.SNAME, name);
values.put(StudentData.SID, sid);
resolver.insert(StudentData.CONTENT_URI, values);
}
}
}
});
}
//如果插入的Id已经存在则用提示框进行提示
@Override
protected Dialog onCreateDialog(int id, Bundle args) {
// // TODO Auto-generated method stub
// return super.onCreateDialog(id, args);
switch (id) {
case DIALOG_IN_USED:
return new AlertDialog.Builder(this).setTitle("Fail to add!")
.setIcon(R.drawable.fail).setMessage(
"This ID:" + sid + " is already in used!")
.setPositiveButton("确定",
// 特别注意:必须为:new DialogInterface.OnClickListener()
// 不能为new
// OnClickListener(),否则会跟View.OnClickListener冲突。
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
}
}).create();
default:
return super.onCreateDialog(id, args);
}
}
}
53、ContentProvider与ContentResolver中用到的Uri
【注】:在ContentProvider与ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据,如:
1、content://contacts/people/:这个Uri指定的就是全部联系人的数据。
2、content://contacts/people/1:这个Uri指定的就是ID为1的联系人的数据。
Uri一般由3部分组成:
1、"content://"
2、要获得数据的一个字符串片段
3、最后就是ID,如果没有ID则返回全部数据。
但因为URI通常比较长,容易出错,所以在Android当中定义了一些辅助类,并定义了一些常量来代替这些这些字符串的使用,如:
Contacts.People.CONTENT_URI:联系人的URI.
Android程序的主要4部分:
1、Activiyt
2、Broadcast Intent Receiver
3、Service
4、Content Provider
一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。
下面列举一些常用的接口:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
52、ContentResolver
外界程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用ContentResolver实例。其提供的接口与ContentProvider提供的接口对应:
1、query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder):通过Uri进行查询,返回一个Cursor.
2、insert(Uri uri,ContentValues values):将一组数据插入到Uri指定的地方。
3、update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri指定位置的数据。
4、delete(Uri uri,String where,String[] selectionArgs):删除指定Uri并且符合一定条件的数据。
【实例】
提供ContentProvider的程序:TestSQLite_2_ContentProvider
对其进行访问访问的程序:TestContentProvider_useStudentData
下面进行分析:
【1】要为当前应用程序的私有数据定义URI,就需要专门定义个继承自ContentProvider的类,然后实现各个不同的操作所调用的方法。
首先在该应用程序的某个类中定义所有与数据库操作有关的静态字段,以便打包成jar文件供其他应用程序调用(本例中引用打包好的jar包后会有“找不到类”的错误,故直接将该类,连同包名一同复制到另一个程序中,如)
此例子没有新定义一个专门的类来存放这些字段,而是在继承了SQLiteOpenHelper的类StudentData中定义:
package com.shutao.testsqlite2;
public class StudentData extends SQLiteOpenHelper {
/*
* 分别定义了数据库和表的名称、表中各个字段的名称、数据库的版本号
*/
public final static String DB_NAME = "student";
public final static String TABLE_NAME = "hero";
public final static String SNAME = "name";
public final static String SID = "_id";
public final static int DB_VERSION = 1;
/*
* AUTHORITY:定义了标识ContentProvider的字符串 ;
* ITEM和ITEM_ID分别用于UriMatcher(资源标识符匹配器)中对路径item和item/id的匹配号码
* CONTENT_TYPE和CONTENT_ITEM_TYPE定义了数据的MIME类型。需要注意的是: 单一数据的MIME 类型字符串应该以
* vnd.android.cursor.item/开头,数据集的MIME类型字符串应该以vnd.android.cursor.dir开头
* CONTENT_URI定义的是查询当前表数据的content://样式URI
*/
public static final String AUTHORITY = "com.shutao.testsqlite2.provider.studentdata";
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.shutao.testsqlite2.studentdata";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.shutao.testsqlite2.studentdata";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/item");
public StudentData(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(" + SID
+ " VARCHAR PRIMARY KEY," + SNAME + " VARCHAR NOT NULL);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
}
【2】接下来定义一个继承自ContentProvider的类:MyProvider.java,来实现对数据进行操作的各个方法。这里将用到StudentData来辅助得到SQLiteDatabase对象:
package com.shutao.testsqlite2;
public class MyProvider extends ContentProvider {
StudentData sd;
private static final UriMatcher sMatcher;
static {
// 传入匹配码如果大于0表示匹配根路径或传入-1,即常量UriMatcher.NO_MATCH表示不匹配根路径
// addURI()方法是用来增加其他URI匹配路径的:
// 第一个参数代表传入标识ContentProvider的AUTHORITY字符串
// 第二个参数是要匹配的路径,#代表任意数字,另外还可以用*来匹配任意文本
// 第三个参数必须传入一个大于零的匹配码,用于match()方法对相匹配的URI返回相对应的匹配码
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI(StudentData.AUTHORITY, "item", StudentData.ITEM);
sMatcher.addURI(StudentData.AUTHORITY, "item/#", StudentData.ITEM_ID);
}
/*
* 每当ContentProvider启动时都会回调onCreate()方法。此方法主要执行一些ContentProvider初始化
* 的工作,返回true表示初始化成功,返回false则初始化失败。
*/
@Override
public boolean onCreate() {
sd = new StudentData(this.getContext());
return true;
}
// getType()是用来返回数据的MIME类型的方法。使用sMatcher对URI进行匹配,并返回相应的MIME类型字符串
@Override
public String getType(Uri uri) {
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
return StudentData.CONTENT_TYPE;
case StudentData.ITEM_ID:
return StudentData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
/*
* 插入数据,返回新插入数据的URI,只接受数据集的URI,即指向表的URI
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase sdb = sd.getWritableDatabase();
long rowId;
if (sMatcher.match(uri) != StudentData.ITEM) {
throw new IllegalArgumentException("Unknow URI " + uri);
}
rowId = sdb.insert(StudentData.TABLE_NAME, StudentData.SID, values);
if (rowId > 0) {
Uri noteUri = ContentUris.withAppendedId(StudentData.CONTENT_URI,
rowId);
this.getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
/*
* 用于数据的删除,返回的是所影响数据的数目,首先利用数据库辅助对象获取一个SQLiteDatabase对象
* 然后根据传入Uri用sMatcher进行匹配,对单个数据或数据集进行删除或修改。notifyChange()方法
* 用来通知注册在次URI上的观察者(observer)数据发生了改变。
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.delete(StudentData.DB_NAME, selection, selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.delete(StudentData.DB_NAME, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
/*
* 查询数据,将数据装入一个Cursor对象并返回
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase sdb = sd.getReadableDatabase();
Cursor c;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
c = sdb.query(StudentData.TABLE_NAME, projection, selection,
selectionArgs, null, null, sortOrder);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
c = sdb.query(StudentData.TABLE_NAME, projection, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs, null, null, sortOrder);
break;
default:
Log.i("sMatcher.match(uri)", String.valueOf(sMatcher.match(uri)));
throw new IllegalArgumentException("Query with unknown URI: " + uri);
}
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// 更新,与删除类方法类似
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase sdb = sd.getWritableDatabase();
int count;
switch (sMatcher.match(uri)) {
case StudentData.ITEM:
count = sdb.update(StudentData.TABLE_NAME, values, selection,
selectionArgs);
break;
case StudentData.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = sdb.update(StudentData.DB_NAME, values, StudentData.SID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ")" : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
this.getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
【3】完成以上方法以后,还要AndroidManifest.xml中对这个ContentProvider声明:
<provider
android:name="MyProvider"
android:authorities="com.shutao.testsqlite2.provider.studentdata"/>
<!-- 其中 android:name必须跟定义的ContentProvider的类名一样
android:authorities则指定了content://样式的URI中标识这个ContentProvider的字符串-->
【4】接下来在另一个程序中使用ContentResolver来操作数据:
package com.shutao.contentprovider;
public class TestContentProvider extends Activity {
private EditText stu_name;
private EditText stu_sid;
Button commit;
ListView studList;
ContentResolver resolver;
// 由于在AlertDialog中用到,所以定义为全局变量。
String sid = "";
private final int DIALOG_IN_USED = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
stu_name = (EditText) this.findViewById(R.id.edit_name);
stu_sid = (EditText) this.findViewById(R.id.edit_sid);
commit = (Button) this.findViewById(R.id.butt_add);
studList = (ListView) this.findViewById(R.id.show_stud);
//【重要】得到ContentResolver()
resolver = this.getContentResolver();
String[] projection = { StudentData.SNAME, StudentData.SID };
Cursor c = resolver.query(StudentData.CONTENT_URI, null, null, null,
StudentData.SID);
CursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, c, projection, new int[] {
android.R.id.text1, android.R.id.text2 });
studList.setAdapter(adapter);
commit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!(stu_name.getText().length() > 0)) {
Toast.makeText(TestContentProvider.this,
"Please input the student's name!",
Toast.LENGTH_LONG).show();
} else if (!(stu_sid.getText().length() > 0)) {
Toast
.makeText(TestContentProvider.this,
"Please input the student's ID!",
Toast.LENGTH_LONG).show();
} else {
String name = stu_name.getText().toString();
sid = stu_sid.getText().toString();
Uri quri = Uri.parse(StudentData.CONTENT_URI + "/" + sid);
Cursor c = resolver.query(quri, null, null, null, null);
if (c.moveToFirst()) {
// 采用Toast方式提醒
/*
* Toast.makeText(TestContentProvider.this,
* "Fail to add!This ID is already in used!",
* Toast.LENGTH_LONG).show();
*/
// 采用AlertDialog方式提醒
TestContentProvider.this.showDialog(DIALOG_IN_USED);
} else {
ContentValues values = new ContentValues();
values.put(StudentData.SNAME, name);
values.put(StudentData.SID, sid);
resolver.insert(StudentData.CONTENT_URI, values);
}
}
}
});
}
//如果插入的Id已经存在则用提示框进行提示
@Override
protected Dialog onCreateDialog(int id, Bundle args) {
// // TODO Auto-generated method stub
// return super.onCreateDialog(id, args);
switch (id) {
case DIALOG_IN_USED:
return new AlertDialog.Builder(this).setTitle("Fail to add!")
.setIcon(R.drawable.fail).setMessage(
"This ID:" + sid + " is already in used!")
.setPositiveButton("确定",
// 特别注意:必须为:new DialogInterface.OnClickListener()
// 不能为new
// OnClickListener(),否则会跟View.OnClickListener冲突。
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
}
}).create();
default:
return super.onCreateDialog(id, args);
}
}
}
53、ContentProvider与ContentResolver中用到的Uri
【注】:在ContentProvider与ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据,如:
1、content://contacts/people/:这个Uri指定的就是全部联系人的数据。
2、content://contacts/people/1:这个Uri指定的就是ID为1的联系人的数据。
Uri一般由3部分组成:
1、"content://"
2、要获得数据的一个字符串片段
3、最后就是ID,如果没有ID则返回全部数据。
但因为URI通常比较长,容易出错,所以在Android当中定义了一些辅助类,并定义了一些常量来代替这些这些字符串的使用,如:
Contacts.People.CONTENT_URI:联系人的URI.
[2] 格局像素单位
来源: 互联网 发布时间: 2014-02-18
布局像素单位
Android的layout文件中有时候可能会指定具体的单位,比如有时候为px、dip或者sp等。他们的区别如下:
1. px (pixels)像素:这个大家用得比较多, 一般我们HVGA代表320x480像素。
2. dip或dp (device independent pixels)设备独立像素:这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA cwj推荐使用这个,不依赖像素。
在android上开发的程序将会在不同分辨率的手机上运行。为了让程序外观不至于相差太大,所以引入了dip的概念。比如定义一个矩形10 x 10dip. 在分辨率为160dpi 的屏上,比如G1,正好是10 x 10像素。
而在240 dpi 的屏,则是15 x 15 像素.
换算公式为 pixs = dips * (density/160). density 就是屏的分辨率
3. sp (scaled pixels — best for text size)放大像素: 主要处理字体的大小。
下面的不经常用到:
4. in (inches)英寸
5. mm (millimeters)毫米
6. pt (points)点
Android的layout文件中有时候可能会指定具体的单位,比如有时候为px、dip或者sp等。他们的区别如下:
1. px (pixels)像素:这个大家用得比较多, 一般我们HVGA代表320x480像素。
2. dip或dp (device independent pixels)设备独立像素:这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA cwj推荐使用这个,不依赖像素。
在android上开发的程序将会在不同分辨率的手机上运行。为了让程序外观不至于相差太大,所以引入了dip的概念。比如定义一个矩形10 x 10dip. 在分辨率为160dpi 的屏上,比如G1,正好是10 x 10像素。
而在240 dpi 的屏,则是15 x 15 像素.
换算公式为 pixs = dips * (density/160). density 就是屏的分辨率
3. sp (scaled pixels — best for text size)放大像素: 主要处理字体的大小。
下面的不经常用到:
4. in (inches)英寸
5. mm (millimeters)毫米
6. pt (points)点
[3] 一些技能
来源: 互联网 发布时间: 2014-02-18
一些技巧
1:查看是否有存储卡插入
String status=Environment.getExternalStorageState();
if(status.equals(Enviroment.MEDIA_MOUNTED))
{
说明有SD卡插入
}
2:让某个Activity透明
OnCreate中不设Layout
this.setTheme(R.style.Theme_Transparent);
以下是Theme_Transparent的定义(注意transparent_bg是一副透明的图片)
3:在屏幕元素中设置句柄
使用Activity.findViewById来取得屏幕上的元素的句柄. 使用该句柄您可以设置或获取任何该对象外露的值.
TextView msgTextView = (TextView)findViewById(R.id.msg);
msgTextView.setText(R.string.push_me);
4:发送短信
String body=”this is mms demo”;
Intent mmsintent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(”smsto”, number, null));
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY, body);
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE, true);
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT, true);
startActivity(mmsintent);
5:发送彩信
StringBuilder sb = new StringBuilder();
sb.append(”file://”);
sb.append(fd.getAbsoluteFile());
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(”mmsto”, number, null));
// Below extra datas are all optional.
intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_SUBJECT, subject);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY, body);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_CONTENT_URI, sb.toString());
intent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE, composeMode);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT, exitOnSent);
startActivity(intent);
7:发送Mail
mime = “img/jpg”;
shareIntent.setDataAndType(Uri.fromFile(fd), mime);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(fd));
shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
shareIntent.putExtra(Intent.EXTRA_TEXT, body);
8:注册一个BroadcastReceiver
registerReceiver(mMasterResetReciever, new IntentFilter(”oms.action.MASTERRESET”));
private BroadcastReceiver mMasterResetReciever = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
if(”oms.action.MASTERRESET”.equals(action)){
RecoverDefaultConfig();
}
}
};
9:定义ContentObserver,监听某个数据表
private ContentObserver mDownloadsObserver = new DownloadsChangeObserver(Downloads.CONTENT_URI);
private class DownloadsChangeObserver extends ContentObserver {
public DownloadsChangeObserver(Uri uri) {
super(new Handler());
}
@Override
public void onChange(boolean selfChange) {}
}
10:获得 手机UA
public String getUserAgent()
{
String user_agent = ProductProperties.get(ProductProperties.USER_AGENT_KEY, null);
return user_agent;
}
11:清空手机上Cookie
CookieSyncManager.createInstance(getApplicationContext());
CookieManager.getInstance().removeAllCookie();
12:建立GPRS连接
//Dial the GPRS link.
private boolean openDataConnection() {
// Set up data connection.
DataConnection conn = DataConnection.getInstance();
if (connectMode == 0) {
ret = conn.openConnection(mContext, “cmwap”, “cmwap”, “cmwap”);
} else {
ret = conn.openConnection(mContext, “cmnet”, “”, “”);
}
}
13:PreferenceActivity 用法
public class Setting extends PreferenceActivity
{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
Setting.xml:
android:key=”seting2″
android:title=”@string/seting2″
android:summary=”@string/seting2″/>
android:key=”seting1″
android:title=”@string/seting1″
android:summaryOff=”@string/seting1summaryOff”
android:summaryOn=”@stringseting1summaryOff”/>
14:通过HttpClient从指定server获取数据
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet method = new HttpGet(“http://www.baidu.com/1.html”);
HttpResponse resp;
Reader reader = null;
try {
// AllClientPNames.TIMEOUT
HttpParams params = new BasicHttpParams();
params.setIntParameter(AllClientPNames.CONNECTION_TIMEOUT, 10000);
httpClient.setParams(params);
resp = httpClient.execute(method);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) return false;
// HttpStatus.SC_OK;
return true;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (reader != null) try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
15:显示toast
Toast.makeText(this._getApplicationContext(), R.string._item, Toast.LENGTH_SHORT).show();
1:查看是否有存储卡插入
String status=Environment.getExternalStorageState();
if(status.equals(Enviroment.MEDIA_MOUNTED))
{
说明有SD卡插入
}
2:让某个Activity透明
OnCreate中不设Layout
this.setTheme(R.style.Theme_Transparent);
以下是Theme_Transparent的定义(注意transparent_bg是一副透明的图片)
3:在屏幕元素中设置句柄
使用Activity.findViewById来取得屏幕上的元素的句柄. 使用该句柄您可以设置或获取任何该对象外露的值.
TextView msgTextView = (TextView)findViewById(R.id.msg);
msgTextView.setText(R.string.push_me);
4:发送短信
String body=”this is mms demo”;
Intent mmsintent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(”smsto”, number, null));
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY, body);
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE, true);
mmsintent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT, true);
startActivity(mmsintent);
5:发送彩信
StringBuilder sb = new StringBuilder();
sb.append(”file://”);
sb.append(fd.getAbsoluteFile());
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(”mmsto”, number, null));
// Below extra datas are all optional.
intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_SUBJECT, subject);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_MESSAGE_BODY, body);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_CONTENT_URI, sb.toString());
intent.putExtra(Messaging.KEY_ACTION_SENDTO_COMPOSE_MODE, composeMode);
intent.putExtra(Messaging.KEY_ACTION_SENDTO_EXIT_ON_SENT, exitOnSent);
startActivity(intent);
7:发送Mail
mime = “img/jpg”;
shareIntent.setDataAndType(Uri.fromFile(fd), mime);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(fd));
shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
shareIntent.putExtra(Intent.EXTRA_TEXT, body);
8:注册一个BroadcastReceiver
registerReceiver(mMasterResetReciever, new IntentFilter(”oms.action.MASTERRESET”));
private BroadcastReceiver mMasterResetReciever = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
if(”oms.action.MASTERRESET”.equals(action)){
RecoverDefaultConfig();
}
}
};
9:定义ContentObserver,监听某个数据表
private ContentObserver mDownloadsObserver = new DownloadsChangeObserver(Downloads.CONTENT_URI);
private class DownloadsChangeObserver extends ContentObserver {
public DownloadsChangeObserver(Uri uri) {
super(new Handler());
}
@Override
public void onChange(boolean selfChange) {}
}
10:获得 手机UA
public String getUserAgent()
{
String user_agent = ProductProperties.get(ProductProperties.USER_AGENT_KEY, null);
return user_agent;
}
11:清空手机上Cookie
CookieSyncManager.createInstance(getApplicationContext());
CookieManager.getInstance().removeAllCookie();
12:建立GPRS连接
//Dial the GPRS link.
private boolean openDataConnection() {
// Set up data connection.
DataConnection conn = DataConnection.getInstance();
if (connectMode == 0) {
ret = conn.openConnection(mContext, “cmwap”, “cmwap”, “cmwap”);
} else {
ret = conn.openConnection(mContext, “cmnet”, “”, “”);
}
}
13:PreferenceActivity 用法
public class Setting extends PreferenceActivity
{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
Setting.xml:
android:key=”seting2″
android:title=”@string/seting2″
android:summary=”@string/seting2″/>
android:key=”seting1″
android:title=”@string/seting1″
android:summaryOff=”@string/seting1summaryOff”
android:summaryOn=”@stringseting1summaryOff”/>
14:通过HttpClient从指定server获取数据
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet method = new HttpGet(“http://www.baidu.com/1.html”);
HttpResponse resp;
Reader reader = null;
try {
// AllClientPNames.TIMEOUT
HttpParams params = new BasicHttpParams();
params.setIntParameter(AllClientPNames.CONNECTION_TIMEOUT, 10000);
httpClient.setParams(params);
resp = httpClient.execute(method);
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK) return false;
// HttpStatus.SC_OK;
return true;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (reader != null) try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
15:显示toast
Toast.makeText(this._getApplicationContext(), R.string._item, Toast.LENGTH_SHORT).show();
最新技术文章: