0

I am making small inventory app where user will enter info about some product then,using a camera he will be able to take an image an store it.i am using SQLite for storing data.My app is worked just fine until i wanted to use camera for storing images Then in my CursorAdapter i'am having Attempt to get length of null array.

This is learning projects,I have never before used Cursor Adapter with images importing.I tried to figure out from posts on SO but failed.

   imeDelaTextView.setText(imeDela);
   modeliAutomobilaTextView.setText(modeliAutomobila);
   cenaTextView.setText(String.valueOf(cenaDela));
   preostalaKolicinaTextView.setText(String.valueOf(preostalaKolicina));
   bitmap = BitmapFactory.decodeByteArray(slikaDela, 0, slikaDela.length);//error in this line
   slikaDelaImageView.setImageBitmap(bitmap);   

my cursor adapter:

public class DeloviCursorAdapet extends CursorAdapter {
        Bitmap bitmap;
       public DeloviCursorAdapet(Context context, Cursor cursor) {
        super(context, cursor, 0);
        }
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
        //LayoutInflater uzima input moj layout xml fajl odnosno, activity_main i pravi View objekat
        return LayoutInflater.from(context).inflate(R.layout.list_view, viewGroup, false);
    }
    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        TextView imeDelaTextView = view.findViewById(R.id.ime_dela);
        TextView modeliAutomobilaTextView = view.findViewById(R.id.modeli_kola);
        TextView cenaTextView = view.findViewById(R.id.cena);
        TextView preostalaKolicinaTextView = view.findViewById(R.id.kolicina);
        ImageView slikaDelaImageView = view.findViewById(R.id.slika);

        int imeDelaColumnIndex = cursor.getColumnIndex(DeoContract.DeoEntry.NAZIV_DELA);
        int modeliAutomobilaColumnIndex = cursor.getColumnIndex(DeoContract.DeoEntry.MODELI_AUTOMOBILA);
        int cenaColumnIndex = cursor.getColumnIndex(DeoContract.DeoEntry.CENA_DELA);
        int preostalaKolicinaColumnIndex = cursor.getColumnIndex(DeoContract.DeoEntry.PREOSTALA_KOLICINA);
        int slikaColumnIndex = cursor.getColumnIndex(DeoContract.DeoEntry.SLIKA_DELA);

        String imeDela = cursor.getString(imeDelaColumnIndex);
        String modeliAutomobila = cursor.getString(modeliAutomobilaColumnIndex);
        int cenaDela = cursor.getInt(cenaColumnIndex);
        int preostalaKolicina = cursor.getInt(preostalaKolicinaColumnIndex);
        byte[] slikaDela = cursor.getBlob(slikaColumnIndex);

        imeDelaTextView.setText(imeDela);
        modeliAutomobilaTextView.setText(modeliAutomobila);
        cenaTextView.setText(String.valueOf(cenaDela));
        preostalaKolicinaTextView.setText(String.valueOf(preostalaKolicina));
        bitmap = BitmapFactory.decodeByteArray(slikaDela, 0, slikaDela.length);//error in this line
        slikaDelaImageView.setImageBitmap(bitmap);   

    }
}

manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.korisnik.katalogdelova">
<uses-feature android:name="android.hardware.camera" />

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".Edit"
        android:label="Izmeni deo"
        android:parentActivityName=".MainActivity" />
    <!-- Parent activity meta-data to support 4.0 and lower -->
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />

    <!--    identifikuje ContentPtovider na uredjaju
           ime klase provajder,odnsno gde se nalazi
           da li je ovaj provajder deljiv sa ostalim aplikacija ovde nije i zato je false-->
    <provider
        android:name=".data.DeloviProvider"
        android:authorities="com.example.korisnik.katalogdelova"
        android:exported="false"/>

MikeT
  • 51,415
  • 16
  • 49
  • 68
gojic
  • 363
  • 7
  • 20
  • You should edit your question and add the stack-trace for the error, if unsure how to then see [Debug your app](https://developer.android.com/studio/debug). – MikeT Jun 20 '19 at 19:59

1 Answers1

0

It is highly unlikely that the Cursor is null, if it were you would have encountered an error prior to the error you have indicated.

  • Any of the SQLiteDatabase methods (query or rawQuery) will not return a Cursor that is null, if no data has been extracted then the Cursor would be empty and I believe that there would be no view to bind in that case.

Storing images in a database is not recommended, they are basically bloat, the recommended way is to save the image as a file and to store the image's path in the database (or part of the path that can be used to retrieve the image from the file).

With Android there is a restriction of 2MB for a CursorWindow (a buffer for the rows in the Cursor). Although an image larger than 2MB (or even close to 2MB) can be saved in the database, such an image cannot be retrieved as it cannot fit into the CursorWindow. Normally this results in an exception.

  • The size that could fit depends upon other columns as a complete row has to fit in the CursorWindow, so there is no definitive size

Even at 1MB you would likely only be able to retrieve 1 row at a time.

As said trying to save images rather then paths will likely lead you from problem to problem.

This answer includes an example of storing an image of up to 100KB in the database but otherwise storing the image as a file and storing the path in the database.

  • The 100k demarkation was based upon 35% Faster Than The Filesystem (i.e. it may be that storing smaller images in the database can be more efficient than retrieving the image via a path)

This question and answer shows a means to save large images (by splitting the images into chunks) but note that this method is not recommended.

I'd suggest that any picture taken with a camera would likely be too large so you probably want to always store the image as a file and store the path in the database. As such the first link is probably the most useful.

MikeT
  • 51,415
  • 16
  • 49
  • 68