Урок 101. Создаем свой ContentProvider
Re: Урок 101. Создаем свой ContentProvider
контент-провадер использовался?
нотификейшен в query() контент-провадера верный?
нотификейшен в query() контент-провадера верный?
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 101. Создаем свой ContentProvider
ContentProvider полностью из урока. изменения делал только в MainActivity
Re: Урок 101. Создаем свой ContentProvider
код курсор-лоадера и код контент-провайдера
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 101. Создаем свой ContentProvider
Код контент-провайдера:
Код активити с использованием курсор-лоадера:
Код: Выделить всё
package ru.startandroid.develop.p1011contentprovider;
import android.content.*;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
public class MyContactsProvider extends ContentProvider {
final String LOG_TAG = "myLogs";
static final String DB_NAME = "mydb";
static final int DB_VERSION = 1;
static final String CONTACT_TABLE = "contacts";
static final String CONTACT_ID = "_id";
static final String CONTACT_NAME = "name";
static final String CONTACT_EMAIL = "email";
static final String DB_CREATE = "create table " + CONTACT_TABLE + "("
+ CONTACT_ID + " integer primary key autoincrement, "
+ CONTACT_NAME + " text, " + CONTACT_EMAIL + " text" + ");";
static final String AUTHORITY = "ru.startandroid.providers.AdressBook";
static final String CONTACT_PATH = "contacts";
public static final Uri CONTACT_CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/" + CONTACT_PATH);
static final String CONTACT_CONTENT_TYPE = "vnd.android.cursor.dir/vnd."
+ AUTHORITY + "." + CONTACT_PATH;
static final String CONTACT_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd."
+ AUTHORITY + "." + CONTACT_PATH;
static final int URI_CONTACTS = 1;
static final int URI_CONTACTS_ID = 2;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, CONTACT_PATH, URI_CONTACTS);
uriMatcher.addURI(AUTHORITY, CONTACT_PATH + "/#", URI_CONTACTS_ID);
}
DBHelper dbHelper;
SQLiteDatabase db;
@Override
public boolean onCreate() {
Log.d(LOG_TAG, "onCreate");
dbHelper = new DBHelper(getContext());
return true;
}
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Log.d(LOG_TAG, "query, " + uri.toString());
switch (uriMatcher.match(uri)) {
case URI_CONTACTS:
Log.d(LOG_TAG, "URI_CONTACTS");
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = CONTACT_NAME + " ASC";
}
break;
case URI_CONTACTS_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id);
if (TextUtils.isEmpty(selection)) {
selection = CONTACT_ID + " = " + id;
} else {
selection = selection + " AND " + CONTACT_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
Cursor cursor = db.query(CONTACT_TABLE, projection, selection,
selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), CONTACT_CONTENT_URI);
return cursor;
}
public Uri insert(Uri uri, ContentValues values) {
Log.d(LOG_TAG, "insert, " + uri.toString());
if (uriMatcher.match(uri) != URI_CONTACTS)
throw new IllegalArgumentException("Wrong URI: " + uri);
db = dbHelper.getWritableDatabase();
long rowID = db.insert(CONTACT_TABLE, null, values);
Uri resultUri = ContentUris.withAppendedId(CONTACT_CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(resultUri, null);
return resultUri;
}
public int delete(Uri uri, String selection, String[] selectionArgs) {
Log.d(LOG_TAG, "delete, " + uri.toString());
switch (uriMatcher.match(uri)) {
case URI_CONTACTS:
Log.d(LOG_TAG, "URI_CONTACTS");
break;
case URI_CONTACTS_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id);
if (TextUtils.isEmpty(selection)) {
selection = CONTACT_ID + " = " + id;
} else {
selection = selection + " AND " + CONTACT_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
int cnt = db.delete(CONTACT_TABLE, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return cnt;
}
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
Log.d(LOG_TAG, "update, " + uri.toString());
switch (uriMatcher.match(uri)) {
case URI_CONTACTS:
Log.d(LOG_TAG, "URI_CONTACTS");
break;
case URI_CONTACTS_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id);
if (TextUtils.isEmpty(selection)) {
selection = CONTACT_ID + " = " + id;
} else {
selection = selection + " AND " + CONTACT_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
int cnt = db.update(CONTACT_TABLE, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return cnt;
}
public String getType(Uri uri) {
Log.d(LOG_TAG, "getType, " + uri.toString());
switch (uriMatcher.match(uri)) {
case URI_CONTACTS:
return CONTACT_CONTENT_TYPE;
case URI_CONTACTS_ID:
return CONTACT_CONTENT_ITEM_TYPE;
}
return null;
}
private class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_CREATE);
ContentValues cv = new ContentValues();
for (int i = 1; i <= 3; i++) {
cv.put(CONTACT_NAME, "name " + i);
cv.put(CONTACT_EMAIL, "email " + i);
db.insert(CONTACT_TABLE, null, cv);
}
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
Код: Выделить всё
package ru.startandroid.develop.p1012contprovclient;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {
final String LOG_TAG = "myLogs";
final Uri CONTACT_URI = Uri.parse("content://ru.startandroid.providers.AdressBook/contacts");
final String CONTACT_NAME = "name";
final String CONTACT_EMAIL = "email";
Cursor cursor;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cursor = getContentResolver().query(CONTACT_URI, null, null, null, null);
String from[] = { "name", "email" };
int to[] = { android.R.id.text1, android.R.id.text2 };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, from, to, 0);
ListView lvContact = (ListView) findViewById(R.id.lvContact);
lvContact.setAdapter(adapter);
getSupportLoaderManager().initLoader(0, null, this);
}
public void onClickInsert(View v) {
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, "name 4");
cv.put(CONTACT_EMAIL, "email 4");
Uri newUri = getContentResolver().insert(CONTACT_URI, cv);
Log.d(LOG_TAG, "insert, result Uri : " + newUri.toString());
}
public void onClickUpdate(View v) {
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, "name 5");
cv.put(CONTACT_EMAIL, "email 5");
Uri uri = ContentUris.withAppendedId(CONTACT_URI, 2);
int cnt = getContentResolver().update(uri, cv, null, null);
Log.d(LOG_TAG, "update, count = " + cnt);
}
public void onClickDelete(View v) {
Uri uri = ContentUris.withAppendedId(CONTACT_URI, 3);
int cnt = getContentResolver().delete(uri, null, null);
Log.d(LOG_TAG, "delete, count = " + cnt);
}
public void onClickError(View v) {
Uri uri = Uri.parse("content://ru.startandroid.providers.AdressBook/phones");
try {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
} catch (Exception ex) {
Log.d(LOG_TAG, "Error: " + ex.getClass() + ", " + ex.getMessage());
}
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(this, CONTACT_URI, null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}
Re: Урок 101. Создаем свой ContentProvider
среди констант бардак. Убери константы с URIиз кода активити, используй только из контент-провадера.
Вот в этой строчке
return new CursorLoader(this, CONTACT_URI, null, null, null, null);
и вот в этой
getContext().getContentResolver().notifyChange(uri, null);
должна использоваться одна и та же константа. Если будет другая - то нотификация не произойдет.
Вот в этой строчке
return new CursorLoader(this, CONTACT_URI, null, null, null, null);
и вот в этой
getContext().getContentResolver().notifyChange(uri, null);
должна использоваться одна и та же константа. Если будет другая - то нотификация не произойдет.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 101. Создаем свой ContentProvider
забыла сказать, и в setNotificationUri тоже самое, та же константа.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 101. Создаем свой ContentProvider
Пытался передавать в CursorLoader те же Uri, что и в контент-провайдере таким способом:
ничего не вышло. Очевидно что-то недопонял
Код: Выделить всё
package ru.startandroid.develop.p1012contprovclient;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {
final String LOG_TAG = "myLogs";
static final String AUTHORITY = "ru.startandroid.providers.AdressBook";
static final String CONTACT_PATH = "contacts";
public static final Uri CONTACT_CONTENT_URI = Uri.parse("content://"
+ AUTHORITY + "/" + CONTACT_PATH);
final String CONTACT_NAME = "name";
final String CONTACT_EMAIL = "email";
Cursor cursor;
LoaderManager loadermanager;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Uri uri = Uri.parse("content://ru.startandroid.providers.AdressBook/contacts");
loadermanager = getSupportLoaderManager();
cursor = getContentResolver().query(CONTACT_CONTENT_URI, null, null, null, null);
String from[] = { "name", "email" };
int to[] = { android.R.id.text1, android.R.id.text2 };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, from, to, 0);
ListView lvContact = (ListView) findViewById(R.id.lvContact);
lvContact.setAdapter(adapter);
Bundle bundle = new Bundle();
bundle.putString("URI", CONTACT_CONTENT_URI.toString());
loadermanager.initLoader(0, bundle, this);
}
public void onClickInsert(View v) {
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, "name 4");
cv.put(CONTACT_EMAIL, "email 4");
Uri newUri = getContentResolver().insert(CONTACT_CONTENT_URI, cv);
Log.d(LOG_TAG, "insert, result Uri : " + newUri.toString());
Bundle bundle = new Bundle();
bundle.putString("URI", newUri.toString());
loadermanager.restartLoader(0, bundle, this);
}
public void onClickUpdate(View v) {
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, "name 5");
cv.put(CONTACT_EMAIL, "email 5");
Uri uri = ContentUris.withAppendedId(CONTACT_CONTENT_URI, 2);
int cnt = getContentResolver().update(uri, cv, null, null);
Log.d(LOG_TAG, "update, count = " + cnt);
Bundle bundle = new Bundle();
bundle.putString("URI", uri.toString());
loadermanager.restartLoader(0, bundle, this);
}
public void onClickDelete(View v) {
Uri uri = ContentUris.withAppendedId(CONTACT_CONTENT_URI, 3);
int cnt = getContentResolver().delete(uri, null, null);
Log.d(LOG_TAG, "delete, count = " + cnt);
Bundle bundle = new Bundle();
bundle.putString("URI", uri.toString());
loadermanager.restartLoader(0, bundle, this);
}
public void onClickError(View v) {
Uri uri = Uri.parse("content://ru.startandroid.providers.AdressBook/phones");
try {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
} catch (Exception ex) {
Log.d(LOG_TAG, "Error: " + ex.getClass() + ", " + ex.getMessage());
}
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String data = args.getString("URI");
Uri loader_uri = Uri.parse(data);
return new CursorLoader(this, loader_uri, null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}
Re: Урок 101. Создаем свой ContentProvider
ты должен был в контент-провайдере или другом публичном классе создать константы
public static final String URI_CONTACTS=""
и использовать их как обычно return new CursorLoader(this, URI_CONTACTS, null, null, null, null);
А не с этими заворотами, что у тебя в коде, это раз.
Поубирай мусор оттуда
типа этого Uri uri = Uri.parse("content://ru.startandroid.providers.AdressBook/contacts");
и три - приведи в соответствие сказанному выше код контент-провайдера.
public static final String URI_CONTACTS=""
и использовать их как обычно return new CursorLoader(this, URI_CONTACTS, null, null, null, null);
А не с этими заворотами, что у тебя в коде, это раз.
Поубирай мусор оттуда
типа этого Uri uri = Uri.parse("content://ru.startandroid.providers.AdressBook/contacts");
и три - приведи в соответствие сказанному выше код контент-провайдера.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 101. Создаем свой ContentProvider
Насчет мусора согласен
Что-то совсем запутался
Но почему константа public static final String URI_CONTACTS=, а не Uri? и как я могу использовать ее в CursorLoader, который в другом проекте? Я же как раз использовал в CursorLoader те Uri, которые поступали в getContext().getContentResolver().notifyChange(uri, null), как было предложено ранее.Foenix писал(а):ты должен был в контент-провайдере или другом публичном классе создать константы
public static final String URI_CONTACTS=""
и использовать их как обычно return new CursorLoader(this, URI_CONTACTS, null, null, null, null);
Что-то совсем запутался
Re: Урок 101. Создаем свой ContentProvider
Uri - это объект, который ты потом создаешь, подавая ему в конструктор строку.
В каком еще другом проекте?
В каком еще другом проекте?
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 101. Создаем свой ContentProvider
Можно попросить, кто-нибудь пожалуйста выложите файл манифеста для урока "p1011_contentprovider",
а то у меня пока ничего не работает
а то у меня пока ничего не работает
Re: Урок 101. Создаем свой ContentProvider
раз используется CursorLoader, то нет смысла использовать старый адаптер. пометил его красным, его надо убрать.Exciter писал(а):Код контент-провайдера:Код активити с использованием курсор-лоадера:Код: Выделить всё
package ru.startandroid.develop.p1011contentprovider; import android.content.*; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.text.TextUtils; import android.util.Log; public class MyContactsProvider extends ContentProvider { final String LOG_TAG = "myLogs"; static final String DB_NAME = "mydb"; static final int DB_VERSION = 1; static final String CONTACT_TABLE = "contacts"; static final String CONTACT_ID = "_id"; static final String CONTACT_NAME = "name"; static final String CONTACT_EMAIL = "email"; static final String DB_CREATE = "create table " + CONTACT_TABLE + "(" + CONTACT_ID + " integer primary key autoincrement, " + CONTACT_NAME + " text, " + CONTACT_EMAIL + " text" + ");"; static final String AUTHORITY = "ru.startandroid.providers.AdressBook"; static final String CONTACT_PATH = "contacts"; public static final Uri CONTACT_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + CONTACT_PATH); static final String CONTACT_CONTENT_TYPE = "vnd.android.cursor.dir/vnd." + AUTHORITY + "." + CONTACT_PATH; static final String CONTACT_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd." + AUTHORITY + "." + CONTACT_PATH; static final int URI_CONTACTS = 1; static final int URI_CONTACTS_ID = 2; private static final UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, CONTACT_PATH, URI_CONTACTS); uriMatcher.addURI(AUTHORITY, CONTACT_PATH + "/#", URI_CONTACTS_ID); } DBHelper dbHelper; SQLiteDatabase db; @Override public boolean onCreate() { Log.d(LOG_TAG, "onCreate"); dbHelper = new DBHelper(getContext()); return true; } public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.d(LOG_TAG, "query, " + uri.toString()); switch (uriMatcher.match(uri)) { case URI_CONTACTS: Log.d(LOG_TAG, "URI_CONTACTS"); if (TextUtils.isEmpty(sortOrder)) { sortOrder = CONTACT_NAME + " ASC"; } break; case URI_CONTACTS_ID: String id = uri.getLastPathSegment(); Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id); if (TextUtils.isEmpty(selection)) { selection = CONTACT_ID + " = " + id; } else { selection = selection + " AND " + CONTACT_ID + " = " + id; } break; default: throw new IllegalArgumentException("Wrong URI: " + uri); } db = dbHelper.getWritableDatabase(); Cursor cursor = db.query(CONTACT_TABLE, projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), CONTACT_CONTENT_URI); return cursor; } public Uri insert(Uri uri, ContentValues values) { Log.d(LOG_TAG, "insert, " + uri.toString()); if (uriMatcher.match(uri) != URI_CONTACTS) throw new IllegalArgumentException("Wrong URI: " + uri); db = dbHelper.getWritableDatabase(); long rowID = db.insert(CONTACT_TABLE, null, values); Uri resultUri = ContentUris.withAppendedId(CONTACT_CONTENT_URI, rowID); getContext().getContentResolver().notifyChange(resultUri, null); return resultUri; } public int delete(Uri uri, String selection, String[] selectionArgs) { Log.d(LOG_TAG, "delete, " + uri.toString()); switch (uriMatcher.match(uri)) { case URI_CONTACTS: Log.d(LOG_TAG, "URI_CONTACTS"); break; case URI_CONTACTS_ID: String id = uri.getLastPathSegment(); Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id); if (TextUtils.isEmpty(selection)) { selection = CONTACT_ID + " = " + id; } else { selection = selection + " AND " + CONTACT_ID + " = " + id; } break; default: throw new IllegalArgumentException("Wrong URI: " + uri); } db = dbHelper.getWritableDatabase(); int cnt = db.delete(CONTACT_TABLE, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return cnt; } public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.d(LOG_TAG, "update, " + uri.toString()); switch (uriMatcher.match(uri)) { case URI_CONTACTS: Log.d(LOG_TAG, "URI_CONTACTS"); break; case URI_CONTACTS_ID: String id = uri.getLastPathSegment(); Log.d(LOG_TAG, "URI_CONTACTS_ID, " + id); if (TextUtils.isEmpty(selection)) { selection = CONTACT_ID + " = " + id; } else { selection = selection + " AND " + CONTACT_ID + " = " + id; } break; default: throw new IllegalArgumentException("Wrong URI: " + uri); } db = dbHelper.getWritableDatabase(); int cnt = db.update(CONTACT_TABLE, values, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return cnt; } public String getType(Uri uri) { Log.d(LOG_TAG, "getType, " + uri.toString()); switch (uriMatcher.match(uri)) { case URI_CONTACTS: return CONTACT_CONTENT_TYPE; case URI_CONTACTS_ID: return CONTACT_CONTENT_ITEM_TYPE; } return null; } private class DBHelper extends SQLiteOpenHelper { public DBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } public void onCreate(SQLiteDatabase db) { db.execSQL(DB_CREATE); ContentValues cv = new ContentValues(); for (int i = 1; i <= 3; i++) { cv.put(CONTACT_NAME, "name " + i); cv.put(CONTACT_EMAIL, "email " + i); db.insert(CONTACT_TABLE, null, cv); } } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } }
Код: Выделить всё
package ru.startandroid.develop.p1012contprovclient; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.util.Log; import android.view.View; import android.widget.ListView; public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> { final String LOG_TAG = "myLogs"; final Uri CONTACT_URI = Uri.parse("content://ru.startandroid.providers.AdressBook/contacts"); final String CONTACT_NAME = "name"; final String CONTACT_EMAIL = "email"; Cursor cursor; /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); cursor = getContentResolver().query(CONTACT_URI, null, null, null, null); String from[] = { "name", "email" }; int to[] = { android.R.id.text1, android.R.id.text2 }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, from, to, 0); ListView lvContact = (ListView) findViewById(R.id.lvContact); lvContact.setAdapter(adapter); getSupportLoaderManager().initLoader(0, null, this); } public void onClickInsert(View v) { ContentValues cv = new ContentValues(); cv.put(CONTACT_NAME, "name 4"); cv.put(CONTACT_EMAIL, "email 4"); Uri newUri = getContentResolver().insert(CONTACT_URI, cv); Log.d(LOG_TAG, "insert, result Uri : " + newUri.toString()); } public void onClickUpdate(View v) { ContentValues cv = new ContentValues(); cv.put(CONTACT_NAME, "name 5"); cv.put(CONTACT_EMAIL, "email 5"); Uri uri = ContentUris.withAppendedId(CONTACT_URI, 2); int cnt = getContentResolver().update(uri, cv, null, null); Log.d(LOG_TAG, "update, count = " + cnt); } public void onClickDelete(View v) { Uri uri = ContentUris.withAppendedId(CONTACT_URI, 3); int cnt = getContentResolver().delete(uri, null, null); Log.d(LOG_TAG, "delete, count = " + cnt); } public void onClickError(View v) { Uri uri = Uri.parse("content://ru.startandroid.providers.AdressBook/phones"); try { Cursor cursor = getContentResolver().query(uri, null, null, null, null); } catch (Exception ex) { Log.d(LOG_TAG, "Error: " + ex.getClass() + ", " + ex.getMessage()); } } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader(this, CONTACT_URI, null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { } @Override public void onLoaderReset(Loader<Cursor> loader) { } }
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, from, to, 0);
новый вызов будет такой
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, from, to, 0);
т.е. никаких запросов в UI, курсор отработает только в методе onCreateLoader.
метод onLoadFinished будет выглядеть вот так-
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
//сюда добавляем обработку пришедшего асинхронно курсора (уничтожение старого если надо)
//К тому же по ИД - loader.getId() можно будет выяснить какой из лоадеров обрабатывать. Их может быть больше одного.
mAdapter.swapCursor(cursor);
}
Во всем остальном не вижу отличий, у меня все работает и обновляется.
Upd. Кстати из предыдущего кода, из-за использования Loader-а, можно (как вариант №2), убрать все оповещения об изменениях(cursor.setNotificationUri), и сделать вместо этого оповещения через UI поток, используя метод get(Support)LoaderManager().restartLoader(LOADER_ID, null, this);
Этот вызов добавить в каждый из методов CRUD-a(onClickInsert, update и тп), после чего он будет обновлять данные.
Вот ссылка на источник: http://www.androiddesignpatterns.com/20 ... nager.html
Re: Урок 101. Создаем свой ContentProvider
Подскажите пожалуйста, если я в приложении хочу в одном Activity добавлять данные в базу, а в другом эти данные выводить на экран, то целесообразно будет пользоваться ContentProviderом или можно это как-то сделать через SQLiteOpenHelper?
Re: Урок 101. Создаем свой ContentProvider
целесообразно
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
-
- Сообщения: 36
- Зарегистрирован: 28 июн 2015, 03:13
Re: Урок 101. Создаем свой ContentProvider
Спасибо за урок.
К сожалению по уроку не всё понятно. Остаются вопросы:
1. Не понятен жизненный цикл контент провайдера. Есть какая-то схожесть с сервисом.
Когда его (провайдера) процесс/поток завершается? При выключении телефона что ли?
2. Соединение с БД у нас тоже никогда не разрывается. На сколько это правильно и безопасно никогда не закрывать подключение к БД?
3. Выходит что с помощью контент провайдера можно практически полностью заменить сервис? При этом без лишних заморочек с передачей данных клиентам и потокам.
4. Зачем всё-таки нужны эти MIME-типы
К сожалению по уроку не всё понятно. Остаются вопросы:
1. Не понятен жизненный цикл контент провайдера. Есть какая-то схожесть с сервисом.
Когда его (провайдера) процесс/поток завершается? При выключении телефона что ли?
2. Соединение с БД у нас тоже никогда не разрывается. На сколько это правильно и безопасно никогда не закрывать подключение к БД?
3. Выходит что с помощью контент провайдера можно практически полностью заменить сервис? При этом без лишних заморочек с передачей данных клиентам и потокам.
4. Зачем всё-таки нужны эти MIME-типы
5. Не очень понятен механизм обновления курсора// Типы данных
// набор строк
static final String CONTACT_CONTENT_TYPE = "vnd.android.cursor.dir/vnd."
+ AUTHORITY + "." + CONTACT_PATH;
// одна строка
static final String CONTACT_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd."
+ AUTHORITY + "." + CONTACT_PATH;
// просим ContentResolver уведомлять этот курсор
// об изменениях данных в CONTACT_CONTENT_URI
cursor.setNotificationUri(getContext().getContentResolver(), CONTACT_CONTENT_URI);
Re: Урок 101. Создаем свой ContentProvider
Ты лучше уйди от абстракций типа "соединение", "механизм", "подключение", "жизненный цикл" - и думай о классах, методах и переменных класса. Тогда какая-то ясность придет. Потому что это никакой не живой организм, обладающий жизненным циклом, и никакой не механизм, который существует сам по себе.
А с мимами не заморачивайся, особого смысла они не несут на начальном этапе. Представляют информацию об получаемых данных - курсор, строчка.
А с мимами не заморачивайся, особого смысла они не несут на начальном этапе. Представляют информацию об получаемых данных - курсор, строчка.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
-
- Сообщения: 42
- Зарегистрирован: 25 янв 2015, 18:57
Re: Урок 101. Создаем свой ContentProvider
Для новых версий Андроид чтобы избежать ошибки Security необходимо изменить манифесты провайдера и клиента:
1)Манифест провайдера:
Манифест клиента:
1)Манифест провайдера:
Код: Выделить всё
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="p1011contentprovider.develop.startandroid.ru.p1011_contentprovider" >
<permission android:name="ru.startandroid.providers.AdressBook.READ_DATABASE" android:protectionLevel="normal" />
<permission android:name="ru.startandroid.providers.AdressBook.WRITE_DATABASE" android:protectionLevel="normal" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<provider
android:authorities="ru.startandroid.providers.AdressBook"
android:name=".MyContactsProvider"
android:exported="true"
android:readPermission="ru.startandroid.providers.AdressBook.READ_DATABASE"
android:writePermission="ru.startandroid.providers.AdressBook.WRITE_DATABASE">
</provider>
</application>
</manifest>
Код: Выделить всё
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="p1012contprovclient.develop.startandroid.ru.p1012_contprovclient" >
<uses-permission android:name="ru.startandroid.providers.AdressBook.READ_DATABASE" />
<uses-permission android:name="ru.startandroid.providers.AdressBook.WRITE_DATABASE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Re: Урок 101. Создаем свой ContentProvider
Добавил разрешения в манифесты. Но выходит новая ошибка.
Основная ошибка такая
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
Ошибка на строке кода 32:
startManagingCursor(cursor);
Вот полный лог ошибки (не знаю как добавить в сжатом виде, сори)
03-02 16:02:53.908 21212-21212/com.example.kz.p1012_contprovclient E/ActivityThread: Failed to find provider info for com.example.kz.providers.AdressBook
03-02 16:02:53.910 21212-21212/com.example.kz.p1012_contprovclient E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kz.p1012_contprovclient, PID: 21212
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.kz.p1012_contprovclient/com.example.kz.p1012_contprovclient.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2462)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524)
at android.app.ActivityThread.access$800(ActivityThread.java:167)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1419)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at android.app.Activity.startManagingCursor(Activity.java:2041)
at com.example.kz.p1012_contprovclient.MainActivity.onCreate(MainActivity.java:32)
at android.app.Activity.performCreate(Activity.java:5977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2415)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524)
at android.app.ActivityThread.access$800(ActivityThread.java:167)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1419)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
Основная ошибка такая
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
Ошибка на строке кода 32:
startManagingCursor(cursor);
Вот полный лог ошибки (не знаю как добавить в сжатом виде, сори)
03-02 16:02:53.908 21212-21212/com.example.kz.p1012_contprovclient E/ActivityThread: Failed to find provider info for com.example.kz.providers.AdressBook
03-02 16:02:53.910 21212-21212/com.example.kz.p1012_contprovclient E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kz.p1012_contprovclient, PID: 21212
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.kz.p1012_contprovclient/com.example.kz.p1012_contprovclient.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2462)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524)
at android.app.ActivityThread.access$800(ActivityThread.java:167)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1419)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
at android.app.Activity.startManagingCursor(Activity.java:2041)
at com.example.kz.p1012_contprovclient.MainActivity.onCreate(MainActivity.java:32)
at android.app.Activity.performCreate(Activity.java:5977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2415)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524)
at android.app.ActivityThread.access$800(ActivityThread.java:167)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1419)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
Re: Урок 101. Создаем свой ContentProvider
Android 5.0.2
MIUI 7
Xiaomi Redmi Note 2
MIUI 7
Xiaomi Redmi Note 2
Re: Урок 101. Создаем свой ContentProvider
Код программы надо приводить.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198