Android-ContentProvider数据库操作

来源:互联网 发布:数据库select into 编辑:程序博客网 时间:2024/06/05 06:47

在实际的开发过程中,Android提供了5种方式存储数据:   

1.文件存储数据    
2.使用 Sharedpreferences 存储数据    
3.SQLite数据库存储数据    
4.使用ContentProvider存储数据    
5.网络存储数据

首先我们先简单了解下文件、SharedPreferred如何进行数据存储

1.文件存储操作

    文件存储一般存储在sdcard或者ROM,当文件存储在ROM上时,如果是存储在除自己私有空间外(data/data/包名/),在其他地方是需要system系统权限的(http://my.oschina.net/zhoulc/blog/119282)。

    文件IO流创建比较简单,就不详述了,在进行文件存储的时候注意两个路径方法就行。
    存储到ROM
        Context mContext = XXXActivity.this;

        mContext.getFilesDir().getAbsolutePath();
        获取路径:/data/data/包名/files
    存储到sdCard :
        首先判断sdcard是否可用

         Environment.getExternalStorageState()是否等于Environment.MEDIA_MOUNTED
         Environment.getExternalStorageDirectory().getAbsolutePath()
         对sdcard目录操作需要添加权限: 
         <!-- 添加对SDCARD的写权限 -->   
         < uses-permission   android:name          ="android.permission.WRITE_EXTERNAL_STORAGE" >
         获取路径:/sdcard
    拓展下 :支持u盘的移动设备,u盘一般都是挂载mnt/sda/sdal外设上面
    顺带说下以前一直纠结的一个问题:
        getApplicationContext() 生命周期是整个应用,应用摧毁它才摧毁
        Activity.this的context属于activity ,activity 摧毁他就摧毁

2.通过Sharedpreferences进行数据存储

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<span style="line-height:19px;">privatefinal static String PERFS_NAME = "com.zlc.test";
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //存放
        //第一个参数是存储时的名称,第二个参数则是文件的打开方式(Context.
MODE_PRIVATE)
        SharedPreferences userInfo = getSharedPreferences(PERFS_NAME,0);
        SharedPreferences.Editor editor = userInfo.edit();
        editor.putString("userName","zhoulc");
        editor.putString("passWord","ds");
        editor.commit();
        //读取
        System.out.println("##########################################");
        SharedPreferences readInfo = getSharedPreferences(PERFS_NAME, 0);
        String name = readInfo.getString("userName","no_name");
        String psword = readInfo.getString("passWord","000000");
        System.out.println("name = "+name+" password = "+psword);
    }</span>
使用过程中注意三个问题: 

    1)getSharedPreferences有两个参数,第一个参数是存储时的名称, 第二个参数则是文件的打开方式(一般使用0或者Context.MODE_PRIVATE) 
    2)默认的模式为0或MODE_PRIVATE,如果访问其他应用中的Preference,前提条件是:该 preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。 
    3)千万不要偷懒写成 
        userInfo.edit().putString("userName", "zhoulc"); 
        userInfo.edit().putString("passWord", "ds"); 
        userInfo.edit().commit(); 
        edit()方法每次都要产生一个新的SharedPreferences.Edit类的对象,所以commit 
之后数据没有存储成功。 


3.其他几个就不详细介绍了,说下今天的重点ContentProvider

    创建一个可对数据库进行操作的ContentProvider我们先要了解涉及到的知识点:
    (1)Parcelable(实体类数据一般会用在进程之间通信)
           http://my.oschina.net/zhoulc/blog/172163
    (2)BaseColumns,这个类只是提供了两个字段,一个是"_id"一个是"_count",便于调用数据库时导致拼写错误,你也可以扩展它,或者自定义这么个,然后直接调用它的常量名,防止写sql语句时把列名拼错。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<span style="line-height:19px;">packageandroid.provider;
 
publicinterface BaseColumns
{
    /**
     * The unique ID for a row.
     * <P>Type: INTEGER (long)</P>
     */
    publicstatic final String _ID = "_id";
 
    /**
     * The count of rows in a directory.
     * <P>Type: INTEGER</P>
     */
    publicstatic final String _COUNT = "_count";
}</span>
    (3)SQLiteOpenHelper,包装了数据库的创建、打开、更新的抽象类,通过实现和使用SQLiteOpenHandle可以隐去数据库打开的之前判断数据库是否需要创建或更新的逻辑。 
            主要实现三个方法 
            创建数据库:public DatabaseHelper(Context context) 
             创建表:public void onCreate(SQLiteDatabase db) 
            更新表:public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
     (4)UriMatcher用来匹配URI。 
            主要实现两个接口: 
             添加需要匹配的URI:MATCHER.addURI(String authority, String path, int code) 进行匹配返回定义的value;MATCHER.match(Uri uri) 
            例: 
                MATCHER.addURI(Information.AUTHORITY, "informations", INFORMATIONS); 
                MATCHER.addURI(Information.AUTHORITY, "informations/#", INFORMATION); 
                # 号为通配符 
                * 号为任意字符 
    (5)ContentUris一个工具类,主要是用来处理使用 "content" 约束的Uri对象,经常用到条件查询某个_ID的数据。 
            主要实现两个接口: 
            static long parseId(Uri contentUri)  将uri中的id解析出来,此方法返回的是一个long型的id。 
            static Uri withAppendedId(Uri contentUri, long id)在指定的uri后面添加一条id 
为指定参数的记录。  
    (6)SQLiteDatabase,这个类是核心类,用于管理和操作SQLite数据库,几乎所有的数据库操作,最终都将由这个类完成。 
    (7)ContentProvider,提供数据库增删改查的接口。 
            主要实现接口: 
            public int delete(Uri uri, String selection, String[] selectionArgs) 
            public String getType(Uri uri) 
            public Uri insert(Uri uri, ContentValues values) 
            public boolean onCreate() 
            public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) 
            public int update(Uri uri, ContentValues values, String selection, 
String[] selectionArgs) 
    (8)ContentResolver接口和ContentProvider类似,两个区别一个是用户是通过ContentResolver调用ContentProvider提供的接口。 
    以上类都只是简单介绍,有兴趣的朋友可以去研究下源码和实现过程。这里主要讲使用过程和一些注意细节。 


4.ContentProvider 在使用过程中需要注意两点: 

    (1)在AndroidManifest.xml里面需要注册这个ContentProvider      
            <provider android:name=".MyProvider" android:authorities="com.zlc.provider.MyProvider" /> 
    (2)当提供给其他进程调用(假如是其他应用),如果当前提供ContentProvider的应用在退出的时候把自己给kill掉了(这个时候ContentProvider也无法使用),则我们需要在AndroidManifest.xml里面再添加一条属性 
            android:process="com.zlc.provider.MyProvider" 
            为该组件指定一个不同的默认进程 


5.下面贴一下具体实现代码

     (1)ContentProvider提供者TestContentProvider.apk 
            实体类:Information.java 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
packagecom.zlc.provider;
 
importandroid.net.Uri;
importandroid.os.Parcel;
importandroid.os.Parcelable;
importandroid.provider.BaseColumns;
 
publicclass Information implementsParcelable,BaseColumns{
    publicfinal static String AUTHORITY = "com.zlc.provider.MyProvider";
    publicfinal static Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY+"/informations");
    //表字段
    publicfinal static String INFO_ID = "info_id";
    publicfinal static String INFO_NAME = "info_name";
    publicfinal static String INFO_AGE = "info_age";
     
    privateString info_id,info_name,info_age;
 
    publicInformation(Parcel source){
        info_id = source.readString();
        info_name = source.readString();
        info_age = source.readString();
    }
    publicString getInfo_id() {
        returninfo_id;
    }
 
    publicvoid setInfo_id(String info_id) {
        this.info_id = info_id;
    }
 
    publicString getInfo_name() {
        returninfo_name;
    }
 
    publicvoid setInfo_name(String info_name) {
        this.info_name = info_name;
    }
 
    publicString getInfo_age() {
        returninfo_age;
    }
 
    publicvoid setInfo_age(String info_age) {
        this.info_age = info_age;
    }
 
    @Override
    publicint describeContents() {
        // TODO Auto-generated method stub
        return0;
    }
 
    @Override
    publicvoid writeToParcel(Parcel dest, intflags) {
        // TODO Auto-generated method stub
        dest.writeString(info_id);
        dest.writeString(info_name);
        dest.writeString(info_age);
    }
    publicfinal static Parcelable.Creator<Information> CREATOR = newParcelable.Creator<Information>() {
 
        @Override
        publicInformation createFromParcel(Parcel source) {
            // TODO Auto-generated method stub
            returnnew Information(source);
        }
 
        @Override
        publicInformation[] newArray(intsize) {
            // TODO Auto-generated method stub
            returnnew Information[size];
        }
    };
}
            MyProvider.java 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
packagecom.zlc.provider;
 
importandroid.content.ContentProvider;
importandroid.content.ContentUris;
importandroid.content.ContentValues;
importandroid.content.Context;
importandroid.content.UriMatcher;
importandroid.database.Cursor;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteOpenHelper;
importandroid.net.Uri;
importandroid.provider.BaseColumns;
importandroid.util.Log;
 
publicclass MyProvider extendsContentProvider {
    privateSQLiteDatabase sqDb;
    privateDatabaseHelper helper;
    // 数据库名
    privatefinal static String DATABASE_NAME = "zhoulc.db";
    // 版本
    privatestatic final int DATABASE_VERSION = 1;
    // 表名
    privatestatic final String TABLE_NAME = "Information";
    // 创建表的sql语句
    privatefinal static String CREATE_TABLE = "Create table " + TABLE_NAME
            +"( "+Information._ID+" integer primary key autoincrement," + Information.INFO_ID
            +" TEXT," + Information.INFO_NAME + " TEXT," + Information.INFO_AGE
            +" TEXT);";
 
    // Declaration Datababsehelper
    privatestatic class DatabaseHelper extendsSQLiteOpenHelper {
 
        publicDatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
 
        @Override
        publicvoid onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
            db.execSQL(CREATE_TABLE);
        }
 
        @Override
        publicvoid onUpgrade(SQLiteDatabase db, intoldVersion, intnewVersion) {
            // TODO Auto-generated method stub
            db.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME);
            onCreate(db);
        }
 
    }
 
    // UriMatcher add URI
    privatestatic final UriMatcher MATCHER = newUriMatcher(
            UriMatcher.NO_MATCH);
    privatefinal static int INFORMATIONS = 1;
    privatefinal static int INFORMATION = 2;
    static{
        MATCHER.addURI(Information.AUTHORITY,"informations", INFORMATIONS);
        MATCHER.addURI(Information.AUTHORITY,"informations/#", INFORMATION);
    }
 
    @Override
    publicint delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        sqDb = helper.getWritableDatabase();
        intcount = 0;
        switch(MATCHER.match(uri)) {
        caseINFORMATIONS:
            count = sqDb.delete(TABLE_NAME, selection, selectionArgs);
            break;
        default:
            thrownew IllegalArgumentException("Unkwon Uri:" + uri.toString());
        }
        returncount;
    }
 
    @Override
    publicString getType(Uri uri) {
        // TODO Auto-generated method stub
        switch(MATCHER.match(uri)) {
        caseINFORMATIONS:
            return"vnd.android.cursor.dir/Information";
        caseINFORMATION:
            return"vnd.android.cursor.item/Information";
        default:
            thrownew IllegalArgumentException("Unkwon Uri:" + uri.toString());
        }
    }
 
    @Override
    publicUri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        sqDb = helper.getWritableDatabase();
        Uri insertUri = null;
        longrowid = 0;
        switch(MATCHER.match(uri)) {
        caseINFORMATIONS:
            rowid = sqDb.insert(TABLE_NAME, Information.INFO_ID, values);
            insertUri = ContentUris.withAppendedId(uri, rowid);
            Log.i("zhoulc","insert record...values:" + values.toString());
            break;
        default:
            thrownew IllegalArgumentException("Unkwon Uri:" + uri.toString());
        }
        returninsertUri;
    }
 
    @Override
    publicboolean onCreate() {
        // TODO Auto-generated method stub
        helper = newDatabaseHelper(getContext());
        returnhelper == null? false: true;
    }
 
    @Override
    publicCursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        sqDb = helper.getWritableDatabase();
        switch(MATCHER.match(uri)) {
        caseINFORMATIONS:
            Cursor cursor = sqDb.query(TABLE_NAME, projection, selection,
                    selectionArgs,null,null, sortOrder);
            returncursor;
        caseINFORMATION://条件查询,
            longid = ContentUris.parseId(uri);
            String where = Information._ID + "="+ id;
             if(selection != null&& !"".equals(selection)) 
             
                 where = where + " and " + selection; 
             
             returnsqDb.query(TABLE_NAME, projection, where, selectionArgs, null
                 null, sortOrder); 
        default:
            thrownew IllegalArgumentException("unknow uri" + uri.toString());
        }
    }
 
    @Override
    publicint update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        sqDb = helper.getWritableDatabase();
        intcount = 0;
        switch(MATCHER.match(uri)) {
        caseINFORMATIONS:
            count = sqDb.update(TABLE_NAME, values, selection, selectionArgs);
            returncount;
        default:
            thrownew IllegalArgumentException("unknow uri" + uri.toString());
        }
         
    }
 
}

            在同一个应用本身里面(进程)测试插入数据:MainActivity.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
packagecom.zlc.provider;
 
importandroid.app.Activity;
importandroid.content.ContentValues;
importandroid.content.Context;
importandroid.content.pm.ApplicationInfo;
importandroid.content.pm.PackageManager;
importandroid.content.pm.PackageManager.NameNotFoundException;
importandroid.net.Uri;
importandroid.os.Bundle;
 
publicclass MainActivity extendsActivity {
 
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Context mContext = MainActivity.this;
        Uri myUri = Information.CONTENT_URI;
        ContentValues values = newContentValues();
        values.put(Information.INFO_NAME,"zhoulc");
        values.put(Information.INFO_AGE,"99");
        getContentResolver().insert(myUri, values);
         
    }
}
运行结果:  
               

其他应用里面测试(跨进程使用)

            TestActivity.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
packagecom.zlc.database;
 
importandroid.app.Activity;
importandroid.content.ContentResolver;
importandroid.content.ContentValues;
importandroid.database.Cursor;
importandroid.net.Uri;
importandroid.os.Bundle;
 
publicclass TestActivity extendsActivity {
    privateContentResolver resolver;
    publicfinal static String AUTHORITY = "com.zlc.provider.MyProvider";
    private final static Uri CONTENT_URIS = Uri.parse("content://"+AUTHORITY+"/informations");
    private final static Uri CONTENT_URI =  Uri.parse("content://"+AUTHORITY+"/informations/1");
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        resolver = getContentResolver();
        //step 1 insert data
        ContentValues values = newContentValues();
        values.put("info_name","zhoulc");
        values.put("info_age","24");
        insert(CONTENT_URIS,values);
        //查询
        Cursor cursor = query(CONTENT_URI,null,null,null,null);
        if(cursor != null){
            if(cursor.moveToFirst()){
                intindex[] = newint[]{
                    cursor.getColumnIndex("info_id"),
                    cursor.getColumnIndex("info_name"),
                    cursor.getColumnIndex("info_age")
                };
                do{
                    System.out.println(cursor.getString(index[1]));
                    System.out.println(cursor.getString(index[2]));
                }while(cursor.moveToNext());
            }
        }
    }
//  该方法用于往ContentProvider添加数据。
    publicUri insert(Uri uri,ContentValues values){
        Uri dst = resolver.insert(uri, values);
        returndst;
    }
//  该方法用于从ContentProvider删除数据。
    publicint delete(Uri uri,String where, String[] selectionArgs){
        intcolums = resolver.delete(CONTENT_URI, where, selectionArgs);
        returncolums;
    }
//  该方法用于更新ContentProvider中的数据。
    publicint update(Uri uri,ContentValues values, String where, String[] selectionArgs){
        intcolums = resolver.update(CONTENT_URI, values, where, selectionArgs);
        returncolums;
    }
//  该方法用于从ContentProvider中获取数据。
    publicCursor query(Uri uri,String[] projection, String where, String[] selectionArgs, String sortOrder){
        Cursor cursor = resolver.query(CONTENT_URI, projection, where, selectionArgs, sortOrder);
        returncursor;
    }
         
}

6.运行过程中遇到的一些问题以及如何解决

?
1
2
3
(1)Open quote is expected forattribute "{1}"associated with an element type"
android:authorities".
  android:authorities="com.zlc.provider.MyProvider"/
解决:不能使用中文的引号
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(2)E/AndroidRuntime( 4509): FATAL EXCEPTION: main
E/AndroidRuntime( 4509): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.zlc.provider/com.zlc.provider.MainActivity}: java.lang.IllegalArgumentException: Unknown URL content://com.zlc.provider.MyProviderinformations
E/AndroidRuntime( 4509):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
E/AndroidRuntime( 4509):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
E/AndroidRuntime( 4509):        at android.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime( 4509):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
E/AndroidRuntime( 4509):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 4509):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 4509):        at android.app.ActivityThread.main(ActivityThread.java:5041)
E/AndroidRuntime( 4509):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 4509):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 4509):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime( 4509):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime( 4509):        at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 4509): Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.zlc.provider.MyProviderinformations
E/AndroidRuntime( 4509):        at android.content.ContentResolver.insert(ContentResolver.java:862)
E/AndroidRuntime( 4509):        at com.zlc.provider.MainActivity.onCreate(MainActivity.java:17)
E/AndroidRuntime( 4509):        at android.app.Activity.performCreate(Activity.java:5104)
E/AndroidRuntime( 4509):        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
E/AndroidRuntime( 4509):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
E/AndroidRuntime( 4509):        ... 11 more
W/ActivityManager( 2138):   Force finishing activity com.zlc.provider/.MainActivity
D/dalvikvm( 2138): GC_FOR_ALLOC freed 596K, 13% free7327K/8412K, paused 63ms, total 63ms
声明的时候掉了一个public final static Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY+"/informations");
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(3)E/AndroidRuntime( 5411): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.zlc.provider/com.zlc.provider.MainActivity}: android.database.sqlite.SQLiteException: near "tableInformation": syntax error (code 1): , whilecompiling: Create tableInformation(_id integer primary key autoincrement,info_idTEXT,info_nameTEXT,info_ageTEXT);
E/AndroidRuntime( 5411):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
E/AndroidRuntime( 5411):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
E/AndroidRuntime( 5411):        at android.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime( 5411):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
E/AndroidRuntime( 5411):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 5411):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 5411):        at android.app.ActivityThread.main(ActivityThread.java:5041)
E/AndroidRuntime( 5411):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 5411):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 5411):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime( 5411):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime( 5411):        at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 5411): Caused by: android.database.sqlite.SQLiteException: near "tableInformation": syntax error (code 1): , whilecompiling: Create tableInformation(_id integer primary key autoincrement,info_idTEXT,info_nameTEXT,info_ageTEXT);
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1663)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1594)
E/AndroidRuntime( 5411):        at com.zlc.provider.MyProvider$DatabaseHelper.onCreate(MyProvider.java:39)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
E/AndroidRuntime( 5411):        at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
E/AndroidRuntime( 5411):        at com.zlc.provider.MyProvider.insert(MyProvider.java:92)
E/AndroidRuntime( 5411):        at android.content.ContentProvider$Transport.insert(ContentProvider.java:201)
E/AndroidRuntime( 5411):        at android.content.ContentResolver.insert(ContentResolver.java:866)
E/AndroidRuntime( 5411):        at com.zlc.provider.MainActivity.onCreate(MainActivity.java:17)
E/AndroidRuntime( 5411):        at android.app.Activity.performCreate(Activity.java:5104)
E/AndroidRuntime( 5411):        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
E/AndroidRuntime( 5411):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
E/AndroidRuntime( 5411):        ... 11 more
W/ActivityManager( 2138):   Force finishing activity com.zlc.provider/.MainActivity
private final static String CREATE_TABLE = "Create table " + TABLE_NAME 
+ "( _id integer primary key autoincrement," + Information.INFO_ID 
+ " TEXT," + Information.INFO_NAME + " TEXT," + Information.INFO_AGE+ " TEXT);"; 
注意空格 

代码下载

0 0
原创粉丝点击