2012-01-18 16 views
5

CursorLoader(v4互換ライブラリを使用)を使用するようにAndroid 2.2アプリケーションを更新しています。なぜコンテンツプロバイダCursorLoaderクエリに関連付けられたコンテンツの変更を通知します。Android CursorLoaderがContentProvider通知に応答しない

CursorLoaderは、顧客のコンテンツプロバイダーに問い合わせています。私のプロバイダは、そのクエリメソッドで通知URIを設定します。

cursor.setNotificationUri(getContext().getContentResolver(), uri); 

をし、その挿入/更新の変更を通知/メソッドを削除します。

getContext().getContentResolver().notifyChange(uri, null); 

私は、URIはどちらの場合も同じであることをチェックしました。以前は同じコンテンツプロバイダでManagedQueryを使用していましたが、照会されたコンテンツはうまく更新されていたため、コンテンツプロバイダはおそらく大丈夫です。

私はNexus Oneで実行した場合、興味深いことに、連絡先の名前の変更(サンプルアプリと連絡先アプリの切り替え)は反映されません。すべき?もしそうなら、私が気づいていないいくつかの根底にある問題はありますか?

+0

問題を特定するためにいくつかのコードを提供できますか? –

+0

デバッグを有効にすると、 'LoaderManager.enableDebugLogging(true)' –

+0

デバッグのヒントをありがとう。私のクライアントコードは、私が参照したLoaderCursorSupportの例と本質的に同じです。これは同じ問題を呈しているので、私はCursorLoaderがどのように動作するのか誤解しましたか?つまり、連絡先のリストを表示するためのサポート例を実行し、アドレス帳の連絡先を編集します。サンプルアプリですか? – siwatson

答えて

-1

たぶん、あなたは、アプリケーション・コンテキストを使用する必要があります。通常の方法であると私は最終的に、このの底になったと

getContext().getApplicationContext().getContentResolver().notifyChange(uri, null); 
+0

これは私が恐れているどんな違いもありませんでした。 – siwatson

4

、それは私の一部の愚かな間違いでした。私はonLoadFinished()メソッドでcursor.close()を呼び出していました。返されたカーソルを使ってArrayAdapterを作成しました(リストの先頭に手動で項目を挿入する必要があります)。そして、カーソルを閉じることはManagedQuery CursorLoaderを使用するように移行する前に

これを見つける過程で、簡単なテストクラスを作成して、ブックマークのリストを表示し、オプションメニューを使用してランダムブックマークを追加しました。これは、アイテムが追加された後にonLoadFinished()が呼び出されるように機能します。

package com.test; 

import android.content.ContentValues; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.provider.Browser; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.ListFragment; 
import android.support.v4.app.LoaderManager; 
import android.support.v4.content.CursorLoader; 
import android.support.v4.content.Loader; 
import android.support.v4.view.MenuItemCompat; 
import android.support.v4.widget.SimpleCursorAdapter; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 

public class CursorLoaderTestActivity extends FragmentActivity 
{ 
    private static final String TAG = CursorLoaderTestActivity.class.getSimpleName(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     FragmentManager fm = getSupportFragmentManager(); 

     // Create the list fragment and add it as our sole content. 
     if (fm.findFragmentById(android.R.id.content) == null) 
     { 
      CursorLoaderListFragment list = new CursorLoaderListFragment(); 
      fm.beginTransaction().add(android.R.id.content, list).commit(); 
     } 
    } 


    public static class CursorLoaderListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> 
    { 

     // This is the Adapter being used to display the list's data. 
     SimpleCursorAdapter mAdapter; 

     // If non-null, this is the current filter the user has provided. 
     String mCurFilter; 

     @Override public void onActivityCreated(Bundle savedInstanceState) 
     { 
      super.onActivityCreated(savedInstanceState); 

      // Give some text to display if there is no data. In a real 
      // application this would come from a resource. 
      setEmptyText("No data"); 

      // We have a menu item to show in action bar. 
      setHasOptionsMenu(true); 

      // Create an empty adapter we will use to display the loaded data. 
      mAdapter = new SimpleCursorAdapter(getActivity(), 
        android.R.layout.simple_list_item_1, null, 
        new String[] { Browser.BookmarkColumns.TITLE }, 
        new int[] { android.R.id.text1}, 0); 

      setListAdapter(mAdapter); 

      // Start out with a progress indicator. 
      setListShown(false); 

      // Prepare the loader. Either re-connect with an existing one, 
      // or start a new one. 
      getLoaderManager().initLoader(0, null, this); 
     } 

     //@Override 
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
     { 
      // Place an action bar item for searching. 
      MenuItem item = menu.add("Add Item"); 
      //item.setIcon(android.R.drawable.ic_menu_search); 
      MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); 
     } 

     @Override 
     public boolean onOptionsItemSelected (MenuItem item) 
     { 
      ContentValues cv=new ContentValues(); 
      cv.put(Browser.BookmarkColumns.TITLE, "!AA " + System.currentTimeMillis()); 
      cv.put(Browser.BookmarkColumns.URL, "http://test/"); 
      cv.put(Browser.BookmarkColumns.BOOKMARK, 1); 
      getActivity().getContentResolver().insert(Browser.BOOKMARKS_URI, cv); 
      return true; 
     } 

     //columns to query 
     static final String[] PROJECTION = new String[] { Browser.BookmarkColumns.TITLE }; 


     public Loader<Cursor> onCreateLoader(int id, Bundle args) 
     { 
      Log.i(TAG, "onCreateLoader"); 

      return new CursorLoader(getActivity(), Browser.BOOKMARKS_URI, 
        PROJECTION, null, null, 
        Browser.BookmarkColumns.TITLE + " ASC"); 
     } 

     public void onLoadFinished(Loader<Cursor> loader, Cursor data) 
     { 
      Log.i(TAG, "onLoadFinished"); 

      // Swap the new cursor in. (The framework will take care of closing the 
      // old cursor once we return.) 
      mAdapter.swapCursor(data); 

      // The list should now be shown. 
      if (isResumed()) 
       setListShown(true); 
      else 
       setListShownNoAnimation(true); 
     } 

     public void onLoaderReset(Loader<Cursor> loader) 
     { 
      // This is called when the last Cursor provided to onLoadFinished() 
      // above is about to be closed. We need to make sure we are no 
      // longer using it. 
      mAdapter.swapCursor(null); 
     } 
    } 

} 
+0

はい。 onLoadFinished()で別のものが提供されるまで、カーソルは生きていなければなりません。 – f470071

関連する問題