我正在尝试取消内容提供商,但我陷入了一件事, 光标通知不起作用,如果我在查询方法中更新光标一切正常。我哪里出错了。谢谢!这是完整的源代码 https://github.com/denmariupol/StartAndroid/tree/master/lesson101_contentprovider_creation_h/src/main
MainActivity
package com.example.lesson101_contentprovider_creation_h;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.database.Cursor;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.example.lesson101_contentprovider_creation_h.databinding.ActivityMainBinding;
import com.example.lesson101_contentprovider_creation_h.interfaces.IUpdateCursor;
import com.example.lesson101_contentprovider_creation_h.fragments.Insert;
import com.facebook.stetho.Stetho;
import java.util.ArrayList;
public class MainActivity extends FragmentActivity implements IUpdateCursor {
public final static Uri PROVIDER_URI = Uri.parse("com.example.lesson101_contentprovider_creation_h");
private Cursor cursor;
private MyAdapter scAdapter;
private ActivityMainBinding mainActivity;
private OnClickListener clickListener;
private int colId;
private int colText;
private ArrayList<Integer> chekedItems = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stethoInit();
mainActivity = DataBindingUtil.setContentView(this, R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
cursor = getContentResolver().query(MyProvider.CONTENT_URI, null, null, null, null, null);
}
colId = cursor.getColumnIndex(MyProvider.ID);
colText = cursor.getColumnIndex(MyProvider.TEXT);
String[] from = new String[]{MyProvider.ID, MyProvider.TEXT};
int[] to = new int[]{R.id.itemId, R.id.itemText};
scAdapter = new MyAdapter(this, R.layout.item, cursor, from, to, 0);
mainActivity.listItem.setAdapter(scAdapter);
scAdapter.notifyDataSetChanged();
mainActivity.listItem.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final View v = view;
final LinearLayout itemUpdateLayout = (LinearLayout)view.findViewById(R.id.itemUpdateLayout);
final LinearLayout itemViewLayout = (LinearLayout)view.findViewById(R.id.itemViewLayout);
TextView idView = (TextView)view.findViewById(R.id.itemId);
TextView textView = (TextView)view.findViewById(R.id.itemText);
final EditText editText = (EditText)view.findViewById(R.id.updateTextField);
Button updateButton = (Button)view.findViewById(R.id.updateRecButton);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("!!!","onTextChanged -> "+s.toString());
// ed
}
@Override
public void afterTextChanged(Editable s) {
}
});
final String updId = idView.getText().toString();
updateButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ContentValues cv = new ContentValues();
String text = editText.getText().toString();
Log.d("!!!","clicked text -> "+editText.getText().toString());
if(text.length() > 0) {
cv.put(MyProvider.TEXT, text);
Uri newUri = ContentUris.withAppendedId(MyProvider.CONTENT_URI,Long.valueOf(updId));
getContentResolver().update(newUri, cv,null,null);
// Cursor cursor = null;
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
// cursor = getContentResolver().query(MyProvider.CONTENT_URI,null,null,null,null,null);
// }
// updateCursor(cursor);
}
itemUpdateLayout.setVisibility(View.GONE);
itemViewLayout.setVisibility(View.VISIBLE);
}
});
editText.setText(textView.getText());
itemUpdateLayout.setVisibility(View.VISIBLE);
itemViewLayout.setVisibility(View.INVISIBLE);
}
});
mainActivity.insert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment insertFragment = new Insert();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, insertFragment);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
});
mainActivity.delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(chekedItems.size() > 0){
for (int i = 0; i < chekedItems.size(); i++) {
Uri newUri = ContentUris.withAppendedId(MyProvider.CONTENT_URI,chekedItems.get(i));
getContentResolver().delete(newUri,null,null);
// Cursor cursor = null;
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
// cursor = getContentResolver().query(MyProvider.CONTENT_URI,null,null,null,null,null);
// }
// updateCursor(cursor);
}
chekedItems.clear();
}else{
Toast.makeText(MainActivity.this,"Nothing selected",Toast.LENGTH_SHORT).show();
}
}
});
}
private void stethoInit() {
// Create an InitializerBuilder
Stetho.InitializerBuilder initializerBuilder =
Stetho.newInitializerBuilder(this);
// Enable Chrome DevTools
initializerBuilder.enableWebKitInspector(
Stetho.defaultInspectorModulesProvider(this)
);
// Enable command line interface
initializerBuilder.enableDumpapp(
Stetho.defaultDumperPluginsProvider(this)
);
// Use the InitializerBuilder to generate an Initializer
Stetho.Initializer initializer = initializerBuilder.build();
// Initialize Stetho with the Initializer
Stetho.initialize(initializer);
}
@Override
public void updateCursor(Cursor newCusor) {
scAdapter.changeCursor(newCusor);
scAdapter.notifyDataSetChanged();
//hide keyboard
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
private class MyAdapter extends SimpleCursorAdapter{
private int layout;
public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.layout = layout;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final String id = cursor.getString(colId);
String title = cursor.getString(colText);
TextView idView = (TextView)view.findViewById(R.id.itemId);
idView.setText(id);
TextView textView = (TextView)view.findViewById(R.id.itemText);
textView.setText(title);
CheckBox checkBox = (CheckBox)view.findViewById(R.id.itemCheckBox);
checkBox.setChecked(false);
checkBox.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(!chekedItems.contains(Integer.valueOf(id))){
chekedItems.add(Integer.valueOf(id));
}else{
chekedItems.remove(chekedItems.indexOf(Integer.valueOf(id)));
}
}
});
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = getLayoutInflater().inflate(layout,parent,false);
return view;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return getCount();
}
}
}
插入片段
package com.example.lesson101_contentprovider_creation_h.fragments;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.lesson101_contentprovider_creation_h.MainActivity;
import com.example.lesson101_contentprovider_creation_h.MyProvider;
import com.example.lesson101_contentprovider_creation_h.R;
import com.example.lesson101_contentprovider_creation_h.databinding.FragmentInsertBinding;
import com.example.lesson101_contentprovider_creation_h.interfaces.IUpdateCursor;
/**
* A simple {@link Fragment} subclass.
*/
public class Insert extends Fragment{
Activity activity;
public Insert() {
// Required empty public constructor
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.activity = (Activity)context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FragmentInsertBinding insertBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_insert,container,false);
View v = insertBinding.getRoot();
insertBinding.insertRecButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues cv = new ContentValues();
String text = insertBinding.insertTextField.getText().toString();
if(text.length() > 0) {
cv.put(MyProvider.TEXT, text);
getContext().getContentResolver().insert(MyProvider.CONTENT_URI, cv);
getActivity().getSupportFragmentManager().beginTransaction().remove(Insert.this).commit();
insertBinding.insertTextField.clearFocus();
// Cursor cursor = null;
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
// cursor = getContext().getContentResolver().query(MyProvider.CONTENT_URI,null,null,null,null,null);
// }
// ((IUpdateCursor)activity).updateCursor(cursor);
}
}
});
// Inflate the layout for this fragment
return v;
}
// public interface IUpdateCursor{
// void updateCursor(Cursor newCursor);
// }
}
MYPROVIDER
package com.example.lesson101_contentprovider_creation_h;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* Created by den on 2017-03-31.
*/
public class MyProvider extends ContentProvider{
private final String DB_NAME = "my";
private int DB_VERSION = 1;
private static final String AUTHORITY = "com.example.lesson101_contentprovider_creation_h";
private static final String PATH = "table";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + PATH);
public static final String DB_TABLE = "MYTABLE";
public static final String ID = "_id";
public static final String TEXT = "text";
private final String CREATE_DB = "CREATE TABLE " + DB_TABLE + " ("
+ ID + " integer primary key autoincrement, "
+ TEXT + " text);";
private DBHelper dbHelper;
private SQLiteDatabase database;
private static final int TABLE = 1;
private static final int TABLE_ID = 2;
static final String CONTACT_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd."
+ AUTHORITY + "." + PATH;
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, PATH, TABLE);
uriMatcher.addURI(AUTHORITY, PATH + "/#", TABLE_ID);
}
@Override
public boolean onCreate() {
dbHelper = new DBHelper(getContext());
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection,
@Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
database = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)){
case TABLE:
sortOrder = ID;
break;
case TABLE_ID:
String id = uri.getLastPathSegment();
sortOrder = TEXT;
break;
}
Cursor cursor = database.query(DB_TABLE,projection,selection,selectionArgs,null,null,sortOrder);
Log.d("!!!","query -> "+uri.toString());
cursor.setNotificationUri(getContext().getContentResolver(),CONTENT_URI);
return cursor;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
switch (uriMatcher.match(uri)){
case TABLE:
break;
case TABLE_ID:
return CONTACT_CONTENT_ITEM_TYPE;
}
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
database = dbHelper.getWritableDatabase();
Log.d("!!!","insert -> "+uri.toString());
if(uriMatcher.match(uri) != TABLE)
throw new IllegalArgumentException("Wrong URI: "+uri);
long id = database.insert(DB_TABLE,null,values);
Uri resultUri = ContentUris.withAppendedId(CONTENT_URI,id);
Log.d("!!!","insert after -> "+resultUri.toString());
getContext().getContentResolver().notifyChange(resultUri,null);
return resultUri;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
database = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)){
case TABLE:
break;
case TABLE_ID:
String id = uri.getLastPathSegment();
selection = ID + " = " + id;
break;
}
int c = database.delete(DB_TABLE,selection,selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return c;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
database = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)){
case TABLE:
break;
case TABLE_ID:
String id = uri.getLastPathSegment();
selection = ID + " = " +id;
Log.d("!!!",id);
break;
}
int c = database.update(DB_TABLE,values,selection,null);
getContext().getContentResolver().notifyChange(uri, null);
return c;
}
private class DBHelper extends SQLiteOpenHelper{
public DBHelper(Context context) {
super(context,DB_NAME,null,DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
updateDB(db,0,DB_VERSION);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
private void updateDB(SQLiteDatabase db, int oldVersion, int newVersion){
if(oldVersion < 1)
db.execSQL(CREATE_DB);
}
}
}
答案 0 :(得分:0)
您是否检查过setNotificationUri中使用的uri是否与getContext()中使用的uri相匹配.getContentResolver()。notifyChange()?
Cursor.setNotificationUri()
将注册
的下划线urigetContext().getContentResolver().notifyChange(uri, null);
在ContentProvider的insert(),update()和delete()调用时调用,因此将通知Cursor(具有setNotificationUri())。
如果您正在使用CursorAdapter,默认情况下,CursorAdapter对象将获取getContext()。getContentResolver()。notifyChange。
发出的此通知。确保不执行cursor.close()的另一件事是,close()将导致取消注册由CursorLoader注册的内容观察者。并且光标关闭由CursorLoader管理。