2

カスタム アダプター、2 つのカーソル (ベースの展開可能なリスト アダプターから)、およびコンテンツ プロバイダーを備えた展開可能なリストがあります。

ここでの主な目的は、インテントで呼び出されるアクティビティを使用して新しいデータを挿入した後、この展開可能なリストを更新することです。コンテンツ オブザーバーを試していますが、更新が行われないため成功しません。

関連するコードを入れました(と思います)。どうもありがとうございました。

public class ActPlacesManagement extends Activity{
private static final int DELETE_ID = Menu.FIRST;

private static final String TAG = null; 

public Cursor mPlacesCursor;
public Cursor mBoxesCursor;
ExpandableListView lstCategorias;
AdpPlacesManagement adapter;
String message, message1, message2;
String novo_local, nova_caixa;
Button btnNewPlace, btnNewBox;
Handler handler;

private static final String[] PROJECTION_PLACES = new String[] {
    ProvPersonalArchive.KEY_ROWID_PLACES,
    ProvPersonalArchive.KEY_DESIG_PLACES,
};

private static final String[] PROJECTION_BOXES = new String[] {
    ProvPersonalArchive.KEY_ROWID_BOXES,
    ProvPersonalArchive.KEY_DESIG_BOXES,
    ProvPersonalArchive.KEY_PLACE_BOXES,
};



protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.act_places_management);       

    mPlacesCursor = getContentResolver().query(ProvPersonalArchive.CONTENT_URI_PLACES, 
            PROJECTION_PLACES, null, null, null);

    mBoxesCursor = getContentResolver().query(ProvPersonalArchive.CONTENT_URI_BOXES, 
            PROJECTION_BOXES, null, null, null);



    lstCategorias = (ExpandableListView)this.findViewById(R.id.expandableGestaoCategorias);

    adapter = new AdpPlacesManagement(this, mPlacesCursor, mBoxesCursor, this);     

    lstCategorias.setAdapter(adapter);

    lstCategorias.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {

        @Override
        public boolean onGroupClick(ExpandableListView parent, View v,
                int groupPosition, long id) {
            return lstCategorias_onGroupClick(parent, v, groupPosition, id);
        }
    });

    lstCategorias.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

        @Override
        public boolean onChildClick(ExpandableListView parent, View v,
                int groupPosition, int childPosition, long id) {
            return lstCategorias_onChildClick(parent, v, groupPosition, childPosition, id);
        }
    });



    btnNewPlace = (Button)this.findViewById(R.act_gestao_categorias.novo_lugar);
    btnNewBox = (Button)this.findViewById(R.act_gestao_categorias.nova_caixa);

    btnNewPlace.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            btnNewPlace_onClick(v);
        }
    });

    btnNewBox.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            btnNewBox_onClick(v);
        }
    });

    registerForContextMenu(lstCategorias);


    mPlacesCursor.registerContentObserver(new ObsPersonalArchive(handler));
    mBoxesCursor.registerContentObserver(new ObsPersonalArchive(handler));

}


// Eventos da lista de locais e caixas

public boolean lstCategorias_onGroupClick(ExpandableListView parent, View v,
        int groupPosition, long id) {
    return false;
}

public boolean lstCategorias_onChildClick(ExpandableListView parent, View v,
        int groupPosition, int childPosition, long id) {        
    return false;
}

// Termina a actividade e volta à ActInicial, levando o local

public void finish() {
  // Prepare data intent 
  Intent data = new Intent();
  setResult(RESULT_OK, data);
  data.putExtra("local", message);
  // Activity finished ok, return the data
  super.finish();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.act_start, menu);
    return true;
}


// Eventos dos botões para criar novo local e caixa

public void btnNewPlace_onClick(View view) {
    Intent intent = new Intent(this, ActNewPlace.class);
    startActivityForResult(intent, 1);
}

public void btnNewBox_onClick(View view) {
    Intent intent = new Intent(this, ActNewBox.class);
    startActivityForResult(intent, 2);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (resultCode == RESULT_OK && requestCode == 1) {
        if (data.hasExtra("novo_local") && data.hasExtra("nova_caixa")) {

            // Chama o método para gravar o local na base de dados
            Toast.makeText(this, "New place created!", Toast.LENGTH_LONG).show();
        }
      }
      if (resultCode == RESULT_OK && requestCode == 2) {
        if (data.hasExtra("novo_local") && data.hasExtra("nova_caixa")) {
            String novo_local = data.getExtras().getString("novo_local");
            String nova_caixa = data.getExtras().getString("nova_caixa");
            Toast.makeText(this, novo_local + nova_caixa, Toast.LENGTH_LONG).show();
        }
      }
    }




public class ObsPersonalArchive extends ContentObserver {

    public ObsPersonalArchive(Handler handler) {
        super(handler);        
        }
       @Override
       public void onChange(boolean selfChange) {
            super.onChange(selfChange);
       }        
}

}

マイケル、私が書いた新しいクラス:

import android.app.Activity;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Toast;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;


public class ActPlacesManagement extends FragmentActivity
implements LoaderManager.LoaderCallbacks<Cursor>{


private static final int DELETE_ID = Menu.FIRST;

private static final String TAG = null;


public Cursor mPlacesCursor;
public Cursor mBoxesCursor;
ExpandableListView lstCategorias;
AdpPlacesManagement adapter;
String message, message1, message2;
String novo_local, nova_caixa;
Button btnNewPlace, btnNewBox;
Handler handler;
LoaderManager loaderManager = getSupportLoaderManager();

private static final String[] PROJECTION_PLACES = new String[] {
    ProvPersonalArchive.KEY_ROWID_PLACES, // 0
    ProvPersonalArchive.KEY_DESIG_PLACES, // 1
};

private static final String[] PROJECTION_BOXES = new String[] {
    ProvPersonalArchive.KEY_ROWID_BOXES, // 0
    ProvPersonalArchive.KEY_DESIG_BOXES, // 1
    ProvPersonalArchive.KEY_PLACE_BOXES, // 2
};

private static final int PLACES_LOADER = 1;
private static final int BOXES_LOADER = 2;


private LoaderManager.LoaderCallbacks<Cursor> mCallbacks;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.act_places_management);       

    mPlacesCursor = getContentResolver().query(ProvPersonalArchive.CONTENT_URI_PLACES, 
            PROJECTION_PLACES, null, null, null);

    mBoxesCursor = getContentResolver().query(ProvPersonalArchive.CONTENT_URI_BOXES, 
            PROJECTION_BOXES, null, null, null);


    // Lista de locais e caixas

    lstCategorias = (ExpandableListView)this.findViewById(R.id.expandableGestaoCategorias);

    adapter = new AdpPlacesManagement(this, mPlacesCursor, mBoxesCursor, this);     

    lstCategorias.setAdapter(adapter);

    lstCategorias.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {

        @Override
        public boolean onGroupClick(ExpandableListView parent, View v,
                int groupPosition, long id) {
            return lstCategorias_onGroupClick(parent, v, groupPosition, id);
        }
    });

    lstCategorias.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

        @Override
        public boolean onChildClick(ExpandableListView parent, View v,
                int groupPosition, int childPosition, long id) {
            return lstCategorias_onChildClick(parent, v, groupPosition, childPosition, id);
        }
    });


    // Botões para novo lugar e caixa

    btnNewPlace = (Button)this.findViewById(R.act_gestao_categorias.novo_lugar);
    btnNewBox = (Button)this.findViewById(R.act_gestao_categorias.nova_caixa);

    btnNewPlace.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            btnNewPlace_onClick(v);
        }
    });

    btnNewBox.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            btnNewBox_onClick(v);
        }
    });

    registerForContextMenu(lstCategorias);

    getSupportLoaderManager().initLoader(BOXES_LOADER, null, mCallbacks);
    getSupportLoaderManager().initLoader(PLACES_LOADER, null, mCallbacks);

}


// Eventos da lista de locais e caixas

public boolean lstCategorias_onGroupClick(ExpandableListView parent, View v,
        int groupPosition, long id) {
    return false;
}

public boolean lstCategorias_onChildClick(ExpandableListView parent, View v,
        int groupPosition, int childPosition, long id) {
    return false;
}


public void finish() { 
  Intent data = new Intent();
  setResult(RESULT_OK, data);
  data.putExtra("local", message);
  super.finish();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.act_start, menu);
    return true;
}


// Eventos dos botões para criar novo local e caixa

public void btnNewPlace_onClick(View view) {
    Intent intent = new Intent(this, ActNewPlace.class);
    startActivityForResult(intent, 1);
}

public void btnNewBox_onClick(View view) {
    Intent intent = new Intent(this, ActNewBox.class);
    startActivityForResult(intent, 2);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (resultCode == RESULT_OK && requestCode == 1) {
        if (data.hasExtra("novo_local") && data.hasExtra("nova_caixa")) {
            Toast.makeText(this, "New place created!", Toast.LENGTH_LONG).show();
        }
      }
      if (resultCode == RESULT_OK && requestCode == 2) {
        if (data.hasExtra("novo_local") && data.hasExtra("nova_caixa")) {
            String novo_local = data.getExtras().getString("novo_local");
            String nova_caixa = data.getExtras().getString("nova_caixa");
            Toast.makeText(this, novo_local + nova_caixa, Toast.LENGTH_LONG).show();
        }
      }
    }



// Menu de contexto

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
ExpandableListView.ExpandableListContextMenuInfo info;

try {
    // Casts the incoming data object into the type for AdapterView objects.
    info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
    // If the menu object can't be cast, logs an error.
    Log.e(TAG, "bad menuInfo", e);
    return;
}


int place = ExpandableListView.getPackedPositionGroup(info.packedPosition);
int box = ExpandableListView.getPackedPositionChild(info.packedPosition);
int tipo_clic = ExpandableListView.getPackedPositionType(info.packedPosition);
String titulo = null;

if (tipo_clic == ExpandableListView.PACKED_POSITION_TYPE_CHILD){
    titulo = (String) adapter.getChild(place, box);
    menu.add(0, DELETE_ID, 0, R.string.delete_box);
}

if (tipo_clic == ExpandableListView.PACKED_POSITION_TYPE_GROUP){
    titulo = (String) adapter.getGroup(place);
    menu.add(0, DELETE_ID, 0, R.string.delete_place);
}

if (titulo == null) {
    // For some reason the requested item isn't available, do nothing
    return;
}
menu.setHeaderTitle(titulo);

}


public boolean onContextItemSelected(MenuItem item) {
ExpandableListView.ExpandableListContextMenuInfo info =     
(ExpandableListView.ExpandableListContextMenuInfo) item.getMenuInfo();
int tipo_clic = ExpandableListView.getPackedPositionType(info.packedPosition);
switch(item.getItemId()) {
case DELETE_ID:
    if (tipo_clic == ExpandableListView.PACKED_POSITION_TYPE_CHILD){
        Toast.makeText(this, "The box was deleted", Toast.LENGTH_LONG).show();
    }

    if (tipo_clic == ExpandableListView.PACKED_POSITION_TYPE_GROUP){
        Toast.makeText(this, "The place was deleted", Toast.LENGTH_LONG).show();
    }
    return true;
}
return super.onContextItemSelected(item);
}


public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {

CursorLoader cursorLoader = new CursorLoader(getBaseContext());

if (id == BOXES_LOADER){
    cursorLoader = new CursorLoader(ActPlacesManagement.this,
 ProvPersonalArchive.CONTENT_URI_BOXES, PROJECTION_BOXES, null, null, null);
 };

 if (id == PLACES_LOADER){
     cursorLoader = new CursorLoader(ActPlacesManagement.this,
  ProvPersonalArchive.CONTENT_URI_PLACES, PROJECTION_PLACES, null, null, null);
  };

return cursorLoader;
}



public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {

switch (loader.getId()) {
case BOXES_LOADER:
    mPlacesCursor = cursor;
  break;
case PLACES_LOADER:
    mBoxesCursor = cursor;
    break;
} 

adapter = new AdpPlacesManagement(this, mPlacesCursor, mBoxesCursor, this);     

lstCategorias.setAdapter(adapter);
}



public void onLoaderReset(Loader<Cursor> loader) {
switch (loader.getId()) {
case BOXES_LOADER:
    mPlacesCursor = null;
  break;
case PLACES_LOADER:
    mBoxesCursor = null;
    break;
} 

adapter = new AdpPlacesManagement(this, mPlacesCursor, mBoxesCursor, this);

}

public class ObsPersonalArchive extends ContentObserver {

    public ObsPersonalArchive(Handler handler) {
        super(handler);        
        }
       @Override
       public void onChange(boolean selfChange) {
            super.onChange(selfChange);
       }        
}   
}   

そして、エラー

12-17 17:28:59.775: I/ActivityThread(16376): プロセス アクティビティ メッセージに入る = 101 12-17 17:28:59.795: I/ActivityThread(16376): プロセス アクティビティ メッセージを終了する = 101 12-17 17:28 :59.805: I/ActivityThread(16376): プロセス アクティビティに入る msg = 100 12-17 17:28:59.905: W/dalvikvm(16376): threadid=1: キャッチされない例外で終了するスレッド (group=0x2aacc8a0) 12-17 17 :28:59.915: E/AndroidRuntime(16376): 致命的な例外: メイン 12-17 17:28:59.915: E/AndroidRuntime(16376): java.lang.RuntimeException: アクティビティを開始できません ComponentInfo{com.smartmobilelife.personal. archive/com.smartmobilelife.personal.archive.ActPlacesManagement}: java.lang.NullPointerException 12-17 17:28:59.915: E/AndroidRuntime(16376): android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2705) で 12 -17 17:28:59.915: E/AndroidRuntime(16376): android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2721) 12-17 17:28:59.915: E/AndroidRuntime(16376): android.app.ActivityThread.access$2300(ActivityThread.java:132) 12-17 17:28:59.915 : E/AndroidRuntime(16376): android.app.ActivityThread$H.handleMessage(ActivityThread.java:2071) 12-17 17:28:59.915: E/AndroidRuntime(16376): android.os.Handler.dispatchMessage( Handler.java:99) 12-17 17:28:59.915: E/AndroidRuntime(16376): android.os.Looper.loop(Looper.java:123) 12-17 17:28:59.915: E/AndroidRuntime( 16376): android.app.ActivityThread.main(ActivityThread.java:4669) 12-17 17:28:59.915: E/AndroidRuntime(16376): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) 12- 17 17:28:59.915: E/AndroidRuntime(16376): java.lang.reflect.Method.invoke(Method.java:521) 12-17 17:28:59.915:E/AndroidRuntime(16376): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:876) 12-17 17:28:59.915: E/AndroidRuntime(16376): com.android.internal .os.ZygoteInit.main(ZygoteInit.java:634) 12-17 17:28:59.915: E/AndroidRuntime(16376): dalvik.system.NativeStart.main(ネイティブ メソッド) 12-17 17:28:59.915: E/AndroidRuntime(16376): 原因: java.lang.NullPointerException 12-17 17:28:59.915: E/AndroidRuntime(16376): android.support.v4.app.LoaderManagerImpl.createLoader(LoaderManager.java:487) で12-17 17:28:59.915: E/AndroidRuntime(16376): android.support.v4.app.LoaderManagerImpl.createAndInstallLoader(LoaderManager.java:496) 12-17 17:28:59.915: E/AndroidRuntime(16376) : android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:550) 12-17 17:28:59.915:E/AndroidRuntime (16376): com.smartmobilelife.personal.archive.ActPlacesManagement.onCreate (ActPlacesManagement.java:131) 12-17 17:28:59.915 で: E/AndroidRuntime (16376): android.app.Instrumentation.callActivityOnCreate で(Instrumentation.java:1047) 12-17 17:28:59.915: E/AndroidRuntime(16376): android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669) 12-17 17:28:59.915: E/AndroidRuntime (16376): ... 11 件以上11以上11以上

4

1 に答える 1

0

CursorLoader を使用して、更新を受信したときにリスト アダプターのカーソルを更新することをお勧めします。

CursorLoaders はデフォルトで ContentObservers です。クエリ カーソルを返すときに ContentProvider が適切な uri を設定していること、および update/insert/delete の変更を通知していることを確認する必要があります。

CursorLoader のドキュメント: http://developer.android.com/reference/android/content/CursorLoader.html

LoaderManager.LoaderCallbacks<Cursor> mLoaderCallback = new LoaderManager.LoaderCallbacks<Cursor>() {

@Override

public Loader<Cursor> onCreateLoader(int id, Bundle args) {

    CursorLoader loader = new CursorLoader(context);

    loader.setProjection(args.getStringArray("projection"));

    loader.setSelection(args.getString("selection"));

    loader.setSelectionArgs(args.getStringArray("selectionArgs"));

    loader.setUri(Uri.parse(args.getString("uri")));



    return loader;

}



@Override

public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {

    if (cursor == null) {

       return;

    }



    YourListAdapter adapter = (YourListAdapter) getListAdapter();

    adapter.swapCursor(cursor);

}



@Override

public void onLoaderReset(Loader<Cursor> cursorLoader) {

    YourListAdapter adapter = (YourListAdapter) getListAdapter();

    adapter.swapCursor(null);

}

};



/* Calling a loader sample. */



Bundle loaderArgs = new Bundle();

loaderArgs.putString("uri", URI);

loaderArgs.putStringArray("projection", PROJECTION);



LoaderManager loaderManager = getLoaderManager();

loaderManager.initLoader(YOUR_LOADER_ID, loaderArgs, mYourLoaderCallback);
于 2012-12-17T13:29:29.307 に答える