[GESCHLOSSEN] Random ListItem ausgeben funktioniert nicht mehr

Status
Für weitere Antworten geschlossen.
S

Sabey

Neues Mitglied
0
Hallo zusammen,

ich arbeite gerade an einer App die Rezepte mit einem Bild, dem Namen und der Kategorie in einem ListView anzeigen soll.
Wenn ich mein Handy schüttel wird durch einen Sensor ein Dialog ausgelöst und anschließend ein Zufallsrezept ausgegeben. Dies funktioniert auch anfangs.
Wenn ich allerdings alle Einträge die ich bisher gemacht haben lösche und in die leere Liste neue Daten einfüge, wird mir kein Rezept mehr ausgeben.
Es wird angezeigt, dass die Cursor moveToFirst() Methode nicht mehr klappt.
Könnt ihr mir helfen wo mein Fehler liegt? Momentan fange ich das mit einem if Statement in meiner openObject Methode ab. Dann wird mir aber wie oben gesagt, kein Rezept mehr geöffnet. Ohne das Statement stürzt die App ab.

Hier mein Code:
Code:
    private ListViewAdapter adapter;
    private ArrayList<ListItem> itemList;
    private ListView list;
    private DatabaseAdapter receptDB;
    private SensorManager sensorMgr;
    private long mLastShakeTime;
    private SensorEventListener listener = this;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);
        setupListView();
        setupDatabase();
        setupButton();
        setupSensor();
        addObject();


    }

    private void setupDatabase() {
        receptDB = new DatabaseAdapter(this);
        receptDB.open();
        refreshListView();
    }

    private void setupButton() {
        Button addItemButton = (Button) findViewById(R.id.addItemButton);
        addItemButton.setOnClickListener(new View.OnClickListener() {

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

    private void addButtonClicked() {
        sensorMgr.unregisterListener(listener);
        Intent newItemIntent = new Intent(List_Page.this, Add_Object.class);
        startActivity(newItemIntent);
        finish();
    }

    private void setupListView() {
        itemList = new ArrayList<ListItem>();
        adapter = new ListViewAdapter(List_Page.this, itemList);
        list = (ListView) findViewById(R.id.listItem);
        list.setOnItemLongClickListener(longClickListener);
        list.setOnItemClickListener(clickListener);
        list.setAdapter(adapter);

    }

    private void setupSensor(){
        sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
        Sensor accelerometer = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (accelerometer != null) {
            sensorMgr.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    public void onBackPressed() {}

    private void addObject(){
        Intent intent = getIntent();
        if (intent.hasExtra(Constants.KEY_RECEPT_NAME)) {
            String name = intent.getExtras().getString(Constants.KEY_RECEPT_NAME);
            String kategory = intent.getExtras().getString(Constants.KEY_KATEGORY);
            String ingredients = intent.getExtras().getString(Constants.KEY_INGREDIENTS);
            String directions = intent.getExtras().getString(Constants.KEY_DIRECTIONS);
            byte[] imageBytes = intent.getByteArrayExtra(Constants.KEY_IMAGE);
            ListItem newObject = new ListItem(name,kategory,ingredients,directions, imageBytes);
            receptDB.insertReceptItem(newObject);
            refreshListView();
        }
    }

   //View updaten
    //hier immer auch bild rausnehmen, wenn kein photo dann das was bereits gesetzt ist?
    private void refreshListView() {
        Cursor cursor = receptDB.getAllRows();
        String[] fromFieldNames = new String[] {DatabaseAdapter.KEY_NAME, DatabaseAdapter.KEY_KATEGORY};
        int[] toViewIDs = new int[] {R.id.receptName, R.id.kategory};
        SimpleCursorAdapter myCursorAdapter;
        myCursorAdapter = new SimpleCursorAdapter(getBaseContext(), R.layout.activity_list_item, cursor, fromFieldNames, toViewIDs, 0);
        ListView myList = (ListView) findViewById(R.id.listItem);
        myList.setAdapter(myCursorAdapter);
    }

    //zuvor fragen!!
    private void removeTaskAtPosition(long id) {
        receptDB.deleteItem(id);
        refreshListView();
    }

    // convert from bitmap to byte array
    public static byte[] getBytes(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 0, stream);
        return stream.toByteArray();
    }

    // convert from byte array to bitmap
    public static Bitmap getImage(byte[] image) {
        return BitmapFactory.decodeByteArray(image, 0, image.length);
    }

    private void alertDialogDelete(long id){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        sensorMgr.unregisterListener(listener);
        final long _id = id;
        builder.setMessage("Bist du dir sicher, dass du dieses Rezept löschen willst?");
        builder.setPositiveButton("JA", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                removeTaskAtPosition(_id);
                dialog.dismiss();
            }
        });
        builder.setNegativeButton("NEIN", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        AlertDialog alert = builder.create();
        setupSensor();
        alert.show();
    }

//ondestroy stürzt schüttelsensor ab

    //schummeln we
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (receptDB.getAllRows().getCount() != 0) {
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                long curTime = System.currentTimeMillis();
                if ((curTime - mLastShakeTime) > MIN_TIME_BETWEEN_SHAKES_MILLISECS) {

                    float x = event.values[0];
                    float y = event.values[1];
                    float z = event.values[2];

                    double acceleration = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) +
                            Math.pow(z, 2)) - SensorManager.GRAVITY_EARTH;

                    if (acceleration > SHAKE_THRESHOLD) {
                        alertDialogRandomRecept(curTime);
                    }
                }
            }
        }
    }

    private void alertDialogRandomRecept(final long curTime) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Willst du ein zufälliges Rezept angezeigt bekommen?");
        sensorMgr.unregisterListener(listener);
        builder.setPositiveButton("JA", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mLastShakeTime = curTime;
                randomRecept();
                dialog.dismiss();
            }
        });
        builder.setNegativeButton("NEIN", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });


        AlertDialog alert = builder.create();
        alert.show();
    }

    //wenn nur eins drin stürzt ab
    private void randomRecept() {
        Random random = new Random();
        long randomLong = (long) random.nextInt(receptDB.getAllRows().getCount()) + 1;
        openObject(randomLong);
    }

    private void openObject(long id) {
        sensorMgr.unregisterListener(listener);
        Intent openObject = new Intent(List_Page.this, Open_Object.class);
        Cursor itemToOpen = receptDB.getRow(id);
        if( itemToOpen != null && itemToOpen.moveToFirst() ) {
            openObject.putExtra(Constants.KEY_RECEPT_NAME, itemToOpen.getString(1));
            openObject.putExtra(Constants.KEY_KATEGORY, itemToOpen.getString(2));
            openObject.putExtra(Constants.KEY_INGREDIENTS, itemToOpen.getString(3));
            openObject.putExtra(Constants.KEY_DIRECTIONS, itemToOpen.getString(4));
            openObject.putExtra(Constants.KEY_IMAGE, itemToOpen.getBlob(1));
            startActivity(openObject);
            finish();
        }
        itemToOpen.close();
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    private AdapterView.OnItemLongClickListener longClickListener = new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                                       int position, long id) {
            alertDialogDelete(id);
            return true;
        }
    };

    private AdapterView.OnItemClickListener clickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            openObject(l);
        }
    };
}
 
Hallo Sabey,

Ich habe Deinen Code ein wenig überflogen.

Was mich ein wenig wundert :
a) Warum nimmst du dir nicht einen CustomAdapter und regelst dein ContentArray ausserhalb ?
b) Dein getImage wird dich ganz schnell zum nächsten Absturz bringen , weil du keine Speichermanagement hast.
Hierzu müsstest du schon LRUCache anwenden . oder z.b. mit Glide arbeiten

Und dann können wir natürlich nur schlecht rästeln , mit welchem Exception deine App abstürtzt.
Dazu wäre es gut, den LogCat zu haben
 
Zuletzt bearbeitet:
Hallo Stefan,

leider bin ich noch ein Anfänger in der Programmierung, weshalb ich noch nicht so viele Tricks drauf hab.
Ich werden mich mal bezüglich eines Costum Adapters informieren, danke für den Tipp.

Und das Logcat zum Absturz:
08-13 18:11:34.259 13229-13229/de.ur.mi.android.excercises.starter E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.ur.mi.android.excercises.starter, PID: 13229
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at de.ur.mi.android.excercises.starter.List_Page.openObject(List_Page.java:242)
at de.ur.mi.android.excercises.starter.List_Page.randomRecept(List_Page.java:234)
at de.ur.mi.android.excercises.starter.List_Page.access$300(List_Page.java:41)
at de.ur.mi.android.excercises.starter.List_Page$4.onClick(List_Page.java:214)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6274)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Ich verstehe nur nicht wieso die OutOfBounce Exception nur kommt wenn ich erst alle Einträge lösche und dann Neue erstelle.

LG
Sabey
 
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0

Da ist schon der Übeltäter, deine Array ist in dem Moment 0 - also kein Inhalt und greiffst drauf zu.

P.S Tip : Du solltest auch deine DB in eine Klasse auslagern und dann bei bedarf deinen Content daraus entnehmen
 
Aber wieso ist er null, wenn ich neue Einträge hinzugefügt habe?
Bevor ich alle Einträge gelöscht habe, hat das immer funktioniert, dass neue Einträge in den Array übergeben wurde.

Und ich habe doch meine Datenbank in einer eigenen Klasse DatabaseAdapter, wobei hier der Name evtl. nicht so gut gewählt ist.
 
Status
Für weitere Antworten geschlossen.

Ähnliche Themen

D
Antworten
23
Aufrufe
2.312
Data2006
D
SaniMatthias
Antworten
19
Aufrufe
858
swa00
swa00
5
Antworten
0
Aufrufe
1.104
586920
5
Zurück
Oben Unten