getContext()。getContentResolver()。notifyChange(uri,null)没有通知游标

时间:2017-04-05 10:41:48

标签: android

我正在尝试取消内容提供商,但我陷入了一件事, 光标通知不起作用,如果我在查询方法中更新光标一切正常。我哪里出错了。谢谢!这是完整的源代码 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);
        }
    }



}

1 个答案:

答案 0 :(得分:0)

您是否检查过setNotificationUri中使用的uri是否与getContext()中使用的uri相匹配.getContentResolver()。notifyChange()?

Cursor.setNotificationUri() 

将注册

的下划线uri
getContext().getContentResolver().notifyChange(uri, null); 

在ContentProvider的insert(),update()和delete()调用时调用,因此将通知Cursor(具有setNotificationUri())。

如果您正在使用CursorAdapter,默认情况下,CursorAdapter对象将获取getContext()。getContentResolver()。notifyChange。

发出的此通知。

确保不执行cursor.close()的另一件事是,close()将导致取消注册由CursorLoader注册的内容观察者。并且光标关闭由CursorLoader管理。