0

Hello when the app is running everything works fine, but when i try to click save i get an error. At first it had and error with the external storage permission. I fixed that but now I'm getting the error below.

Can someone look at my code and see if you can see what I'm missing?

It says NullPointerException but the line that it is pointing to has no null points in the code.

Code:

package com.androidbook.pettracker3;

import android.app.LoaderManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.FilterQueryProvider;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.RadioGroup.LayoutParams;
import android.widget.SimpleCursorAdapter;

import com.androidbook.pettracker3.PetTrackerDatabase.PetType;
import com.androidbook.pettracker3.PetTrackerDatabase.Pets;

public class PetTrackerEntryActivity extends PetTrackerActivity implements
    LoaderManager.LoaderCallbacks<Cursor> {
private static final int GALLERY_CURSOR_LOADER_ID = 0x1001;
private static final String GALLERY_CURSOR_URI_ARG =     "GALLERY_CURSOR_URI_ARG";
protected Cursor mCursorAutoComplete;
protected Cursor mThumbnailImagesCursor;

private Gallery imagePickerGallery;
private ImageUriAdapter mGalleryAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // use this to note how the setImageURI method is bad
    /*StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll().penaltyFlashScreen().penaltyLog().build());

 */
    setContentView(R.layout.petentry);

    // Fill our Gallery from pictures available on the SD Card
    setGalleryAdapter();

    // Fill AutoComplete word list from database
    fillAutoComplete();

    imagePickerGallery = (Gallery) findViewById(R.id.GalleryOfPics);

    // Handle Save Button
    final Button savePet = (Button) findViewById(R.id.ButtonSave);
    savePet.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            final EditText petName = (EditText) findViewById(R.id.EditTextName);
            final EditText petType = (EditText) findViewById(R.id.EditTextSpecies);
            long imageId = PetRecord.INVALID_PET_IMAGE_ID;

            ImageView selectedImageView = (ImageView) imagePickerGallery
                    .getSelectedView();

            Uri imageUri = (Uri) selectedImageView.getTag();
            String imageUriString = imageUri.toString();

            String strPetType = petType.getText().toString().toLowerCase();
            String strPetName = petName.getText().toString();
            PetRecord newRecord = new PetRecord(strPetName, strPetType,
                    imageUriString, imageId, PetRecord.INVALID_PET_ID);
            addPetRecord(newRecord);

            // reset form
            petName.setText(null);
            petType.setText(null);
        }
    });

    // Handle Go to List button
    final Button gotoList = (Button) findViewById(R.id.ButtonShowPets);
    gotoList.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            // Go to other activity that displays pet list
            Intent intent = new Intent(PetTrackerEntryActivity.this,
                    PetTrackerListActivity.class);
            startActivity(intent);
        }
    });
}

//
private void setGalleryAdapter() {

    // The base URI for SD Card content
    Uri thumbnailUri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI;

    mGalleryAdapter = new ImageUriAdapter(this, null, false, thumbnailUri);

    // Assign the adapter to our Gallery to display the images
    final Gallery pictureGal = (Gallery) findViewById(R.id.GalleryOfPics);
    pictureGal.setAdapter(mGalleryAdapter);

    // use a loader to get the cursor and assign it to this adapter
    Bundle args = new Bundle();
    args.putString(GALLERY_CURSOR_URI_ARG, thumbnailUri.toString());
    getLoaderManager().initLoader(GALLERY_CURSOR_LOADER_ID, args, this);
}

private void fillAutoComplete() {
    mCursorAutoComplete = mDB.query(PetType.PETTYPE_TABLE_NAME,
            new String[] { PetType.PET_TYPE_NAME, PetType._ID }, null,
            null, null, null, PetType.DEFAULT_SORT_ORDER);

    startManagingCursor(mCursorAutoComplete);

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            android.R.layout.simple_dropdown_item_1line,
            mCursorAutoComplete, new String[] { PetType.PET_TYPE_NAME },
            new int[] { android.R.id.text1 });

    // I just want the text splatted into the edittext, not the textview
    // object
    // so I implemented a CursorToStringConverter and a FilterQueryProvider
    // CursorToStringConverter - controls what "value" is returned when an
    // AutoText option is chosen
    // in this case, the text itself, not the id to the text
    // FilterQueryProvider - interface to get control over the filtering
    // process, which we implement a custom matching function
    adapter.setCursorToStringConverter(new MyCursorToStringConverter());
    adapter.setFilterQueryProvider(new MyFilterQueryProvider());

    AutoCompleteTextView text = (AutoCompleteTextView) findViewById(R.id.EditTextSpecies);
    text.setAdapter(adapter);

}

// This controls what column to place in the edittext when selected. The
// default textview.tostring, not helpful
class MyCursorToStringConverter implements
        SimpleCursorAdapter.CursorToStringConverter {

    public CharSequence convertToString(Cursor cursor) {
        return cursor.getString(cursor
                .getColumnIndex(PetType.PET_TYPE_NAME));
    }
}

// Our custom filter finds all substring matches, not just the beginning of
// the string, just for kicks
// There's a bit of a workaround here, since this function does not handle
// Cursor refreshing appropriately
class MyFilterQueryProvider implements FilterQueryProvider {

    public Cursor runQuery(CharSequence constraint) {

        if ((constraint != null) && (mCursorAutoComplete != null)) {
            String strWhere = PetType.PET_TYPE_NAME + " LIKE ?";

            stopManagingCursor(mCursorAutoComplete);
            mCursorAutoComplete = mDB
                    .query(PetType.PETTYPE_TABLE_NAME, new String[] {
                            PetType.PET_TYPE_NAME, PetType._ID }, strWhere,
                            new String[] { "%" + constraint.toString()
                                    + "%" }, null, null,
                            PetType.DEFAULT_SORT_ORDER);
            startManagingCursor(mCursorAutoComplete);
        }

        return mCursorAutoComplete;
    }
}

// Add appropriate records to the database (Pet and Pet_Type)
private void addPetRecord(PetRecord newRecord) {

    // Save new records, since we're saving multiple records, let's do a
    // transaction so it's all or nothing
    mDB.beginTransaction();
    try {

        // check if species type exists already
        long rowPetTypeId = 0;

        // SQL Query -> "select * from table_pettype where
        // PetType.pettype_name='string'
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        queryBuilder.setTables(PetType.PETTYPE_TABLE_NAME);
        queryBuilder.appendWhere(PetType.PET_TYPE_NAME + "='"
                + newRecord.getPetType() + "'");

        // run the query since it's all ready to go
        Cursor c = queryBuilder.query(mDB, null, null, null, null, null,
                null);

        if (c.getCount() == 0) {
            // add the new type to our list
            ContentValues typeRecordToAdd = new ContentValues();
            typeRecordToAdd.put(PetType.PET_TYPE_NAME,
                    newRecord.getPetType());
            rowPetTypeId = mDB.insert(PetType.PETTYPE_TABLE_NAME,
                    PetType.PET_TYPE_NAME, typeRecordToAdd);

        } else {
            // Type already exists, grab the row id to refer to below
            c.moveToFirst();
            rowPetTypeId = c.getLong(c.getColumnIndex(PetType._ID));
        }

        c.close();

        // Always insert new pet records, even if the names clash
        ContentValues petRecordToAdd = new ContentValues();
        petRecordToAdd.put(Pets.PET_NAME, newRecord.getPetName());
        petRecordToAdd.put(Pets.PET_TYPE_ID, rowPetTypeId);
        petRecordToAdd.put(Pets.PET_IMAGE_URI,
                newRecord.getPetImageUriPath());
        petRecordToAdd.put(Pets.PET_IMAGE_ID, newRecord.getPetImageId());
        mDB.insert(Pets.PETS_TABLE_NAME, Pets.PET_NAME, petRecordToAdd);

        mDB.setTransactionSuccessful();
    } finally {
        mDB.endTransaction();
    }
}

public class ImageUriAdapter extends CursorAdapter {

    private int colIndexMediaId;
    private final Uri baseUri;
    private final int mGalleryItemBackground;

    public ImageUriAdapter(Context context, Cursor c, boolean autoRequery,
            Uri baseUri) {
        super(context, c, autoRequery);
        if (c != null) {
            colIndexMediaId = c
                    .getColumnIndex(MediaStore.Images.Thumbnails._ID);
        }
        this.baseUri = baseUri;

        TypedArray a = obtainStyledAttributes(R.styleable.default_gallery);
        mGalleryItemBackground = a.getResourceId(
        R.styleable.default_gallery_android_galleryItemBackground, 0);
        a.recycle();
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        long id = cursor.getLong(colIndexMediaId);

        // TODO: this should be done on a background thread; it blocks
        Uri imageUri = Uri.withAppendedPath(baseUri, String.valueOf(id));
        ((ImageView) view).setImageURI(imageUri);
        view.setTag(imageUri);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        ImageView imageView = new ImageView(context);
        long id = cursor.getLong(colIndexMediaId);

        // TODO: this should be done on a background thread; it blocks
        Uri imageUri = Uri.withAppendedPath(baseUri, String.valueOf(id));
        imageView.setImageURI(imageUri);

        // Constrain the images so they all look the same size/ratio
        imageView.setLayoutParams(new Gallery.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        imageView.setTag(imageUri);

        imageView.setBackgroundResource(mGalleryItemBackground);

        return imageView;
    }

    @Override
    public Cursor swapCursor(Cursor newCursor) {
        if (newCursor != null) {
            colIndexMediaId = newCursor
                    .getColumnIndex(MediaStore.Images.Thumbnails._ID);
        }
        return super.swapCursor(newCursor);
    }
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    switch (id) {
    case GALLERY_CURSOR_LOADER_ID:
        // An array specifying which columns to return.
        String[] projection = new String[] { MediaStore.Images.Thumbnails._ID };

        // The base URI for SD Card content
        Uri thumbnailUri = Uri
                .parse(args.getString(GALLERY_CURSOR_URI_ARG));

        // thumbnails of all external images in the media store
        // Best way to retrieve a cursor; performs operation on a background
        // thread
        CursorLoader loader = new CursorLoader(this, thumbnailUri,
                projection, null, null,
                MediaStore.Images.Thumbnails.DEFAULT_SORT_ORDER
                        //+ " limit 50"
                        );
        return loader;
    }

    return null;

}

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
    switch (cursorLoader.getId()) {
    case GALLERY_CURSOR_LOADER_ID:
        mGalleryAdapter.swapCursor(cursor);
        break;
    }

}

@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
    switch (cursorLoader.getId()) {
    case GALLERY_CURSOR_LOADER_ID:
        mGalleryAdapter.swapCursor(null);
        break;
    }
}

Error message

D/dalvikvm: Not late-enabling CheckJNI (already on)
04-07 15:25:41.172 2212-2212/? E/Trace: error opening trace file: No such     file or directory (2)
04-07 15:25:41.172 2212-2212/com.androidbook.pettracker3 W/ActivityThread:     Application com.androidbook.pettracker3 is waiting for the debugger on port    8100...
04-07 15:25:41.182 2212-2212/com.androidbook.pettracker3 I/System.out: Sending WAIT chunk
04-07 15:25:41.842 2212-2219/com.androidbook.pettracker3 I/dalvikvm: Debugger is active
04-07 15:25:42.012 2212-2212/com.androidbook.pettracker3 I/System.out: Debugger has connected
04-07 15:25:42.012 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:42.212 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:42.422 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:42.632 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:42.842 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:43.052 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:43.262 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:43.472 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:43.682 2212-2212/com.androidbook.pettracker3 I/System.out: waiting for debugger to settle...
04-07 15:25:43.892 2212-2212/com.androidbook.pettracker3 I/System.out: debugger has settled (1352)
04-07 15:25:43.922 2212-2217/com.androidbook.pettracker3 D/dalvikvm: GC_CONCURRENT freed 131K, 7% free 2675K/2864K, paused 7ms+0ms, total 9ms
04-07 15:25:43.942 2212-2217/com.androidbook.pettracker3 D/dalvikvm: GC_CONCURRENT freed 117K, 9% free 2958K/3216K, paused 3ms+0ms, total 5ms
04-07 15:25:43.972 2212-2217/com.androidbook.pettracker3 D/dalvikvm:  GC_CONCURRENT freed 129K, 8% free 3228K/3480K, paused 9ms+1ms, total 12ms
04-07 15:25:44.041 2212-2212/com.androidbook.pettracker3 D/libEGL: loaded /system/lib/egl/libEGL_emulation.so
04-07 15:25:44.041 2212-2212/com.androidbook.pettracker3 D/libEGL: loaded /system/lib/egl/libGLESv1_CM_emulation.so
04-07 15:25:44.041 2212-2212/com.androidbook.pettracker3 D/libEGL: loaded /system/lib/egl/libGLESv2_emulation.so
04-07 15:25:44.092 2212-2212/com.androidbook.pettracker3 W/EGL_emulation: eglSurfaceAttrib not implemented
04-07 15:25:44.092 2212-2212/com.androidbook.pettracker3 D/OpenGLRenderer: Enabling debug mode 0
04-07 15:26:22.622 2212-2212/com.androidbook.pettracker3 D/AndroidRuntime: Shutting down VM
04-07 15:26:22.622 2212-2212/com.androidbook.pettracker3 W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xb2d17908)
04-07 15:26:22.622 2212-2212/com.androidbook.pettracker3 E/AndroidRuntime:
   FATAL EXCEPTION: main                                                          java.lang.NullPointerException
   at  com.androidbook.pettracker3.PetTrackerEntryActivity$1.onClick(PetTrackerEntryAct ivity.java:70)
   at android.view.View.performClick(View.java:4204)
   at android.view.View$PerformClick.run(View.java:17355)
   at android.os.Handler.handleCallback(Handler.java:725)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:5041)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
   at dalvik.system.NativeStart.main(Native Method)
   04-07 15:26:27.422 2212-2212/? I/Process: Sending signal. PID: 2212 SIG: 9

petentry.xml

   <?xml version="1.0" encoding="utf-8"?>
   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical" >
   <TextView
      style="@android:style/TextAppearance.Large"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/enter_data"
      android:textColor="#0f0" />
   <TableLayout
      android:id="@+id/TableLayout01"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:shrinkColumns="*"
      android:stretchColumns="1" >
      <TableRow
        android:id="@+id/TableRow01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Pet Name:" >
        </TextView>
        <EditText
            android:id="@+id/EditTextName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="textCapWords" >
        </EditText>
      </TableRow>
      <TableRow
        android:id="@+id/TableRow02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Pet Species:" >
        </TextView>
        <AutoCompleteTextView
            android:id="@+id/EditTextSpecies"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </AutoCompleteTextView>
      </TableRow>
      <TableRow
        android:id="@+id/TableRow03"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Choose Pet Picture:" >
        </TextView>
    </TableRow>
    <TableRow
        android:id="@+id/TableRow04"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <Gallery
            android:id="@+id/GalleryOfPics"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_span="2" >
        </Gallery>
    </TableRow>
  </TableLayout>
   <Button
    android:id="@+id/ButtonSave"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/save" >
  </Button>
  <Button
    android:id="@+id/ButtonShowPets"
    style="@android:style/TextAppearance.Large"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Show All Pets"
    android:textColor="#0f0" >
  </Button>
</LinearLayout>
  • One of your buttons is null. Check that `petentry.xml` contains the all the id's that you are trying to find – OneCricketeer Apr 07 '16 at 16:04
  • added petentry.xml code. – DarthMactis Apr 07 '16 at 16:52
  • My bad, not one of the buttons. `selectedImageView` is null. Just read the error. It says it's on line 70. – OneCricketeer Apr 07 '16 at 16:55
  • I did check it but there is no null notation in that method. I'm just leaning and i don't understand how that can be null. Ty for the help so far by the way. – DarthMactis Apr 07 '16 at 17:03
  • `getSelectedView()` will return null if nothing is selected. Says it in the Android documentation. – OneCricketeer Apr 07 '16 at 17:06
  • Ok let me see if i go this the line the error is 'Uri imageUri = (Uri) selectedImageView.getTag();'. So to change it from null you need to put something in the .getTag brackets, right? – DarthMactis Apr 07 '16 at 20:28
  • `getTag()` takes no paramaters. Your error points to that line because `getTag()` cannot be called on the `selectedImageView` variable because it is null, thus the error. It is null because the `getSelectedView()` method that you called on your Gallery variable returned null for the reason I mentioned above – OneCricketeer Apr 07 '16 at 20:32
  • kk let me fiddle around with it ty very much!!! – DarthMactis Apr 07 '16 at 20:34
  • Ok i think i may have an idea. I think the problem is the fact that is't trying to use android.widget.gallery but is deprecated, this code was written with old API's. i think i need to change the code to use viewPager but have know idea how to do that. – DarthMactis Apr 07 '16 at 21:37

0 Answers0