0

I'm trying to add an onTouchListener, to an ImageView so I can get the values of a pixel that a user chooses from an image they take. Therefore, I implemented onTouchListener in my main activity and used it as the onTouchListener for ImageView imageview.

My code is as follows:

package com.andrew.omnidropper;

import java.io.File;
import java.net.URI;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class OmniDropperActivity extends Activity implements OnTouchListener {
protected static final int TAKE_PICTURE_INTENT = 0;
protected static final int SELECT_PREVIOUS_PHOTO_INTENT = 1;
/** Called when the activity is first created. */

public Button cameraButton;

public ImageView imageview;
public ImageView colordisplay;

private Bitmap bitmap;

private Uri imageUri;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    cameraButton = (Button) findViewById(R.id.camerabutton);
    imageview = (ImageView) findViewById(R.id.imageview);
    colordisplay = (ImageView) findViewById(R.id.colordisplay);

    cameraButton.setOnClickListener(clickListener);
    imageview.setOnTouchListener(this);
}
OnClickListener clickListener = new OnClickListener() {
    public void onClick(View v) {
        if(v.getId() == R.id.camerabutton){
            Intent intent = new    Intent("android.media.action.IMAGE_CAPTURE");
            File photo = new File(Environment.getExternalStorageDirectory(),  "Pic.jpg");
            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                    Uri.fromFile(photo));
            imageUri = Uri.fromFile(photo);
            startActivityForResult(intent, 0);
            setContentView(R.layout.selectcolorspot);
        }
        /*if(v.getId() == R.id.imagebutton){
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"),
                    SELECT_PREVIOUS_PHOTO_INTENT);
            setContentView(R.layout.selectcolorspot);
        }(*/
        /*if(v.getId() == R.id.scratchbutton){
            setContentView(R.layout.makenewcolor);
        }*/
    }
};
private int colorPicked;

public void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case 0:
            if (resultCode == Activity.RESULT_OK) {
                Uri selectedImage = imageUri;
                getContentResolver().notifyChange(selectedImage, null);
                imageview = (ImageView) findViewById(R.id.imageview);
                ContentResolver cr = getContentResolver();
                try {
                    bitmap = android.provider.MediaStore.Images.Media
                        .getBitmap(cr, selectedImage);

                    imageview.setImageBitmap(bitmap);
                    imageview.setScaleType(ImageView.ScaleType.FIT_XY);
                    Toast.makeText(this, "Select an point on the image and press OK",
                                   Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT)
                        .show();
                    Log.e("Camera", e.toString());
                }
            }
    }
}

public boolean onTouch(View v, MotionEvent e) {
    if(v.getId() == R.id.imageview){
        if(e.getAction() == MotionEvent.ACTION_DOWN && bitmap != null){
            colorPicked = bitmap.getPixel((int) e.getX(),(int) e.getY());
            setContentView(R.layout.iscolorok);
            colordisplay.setBackgroundColor(colorPicked);
        }
    }
    return false;
}
}

but when I try to run it, it crashes.

Here's the logcat output:

03-28 20:43:54.613: D/AndroidRuntime(4761): Shutting down VM
03-28 20:43:54.613: W/dalvikvm(4761): threadid=1: thread exiting with uncaught exception (group=0x40018560)
03-28 20:43:54.621: E/AndroidRuntime(4761): FATAL EXCEPTION: main
03-28 20:43:54.621: E/AndroidRuntime(4761): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.andrew.omnidropper/com.andrew.omnidropper.OmniDropperActivity}: java.lang.NullPointerException
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1696)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1716)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.app.ActivityThread.access$1500(ActivityThread.java:124)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:968)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.os.Looper.loop(Looper.java:123)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.app.ActivityThread.main(ActivityThread.java:3806)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at java.lang.reflect.Method.invokeNative(Native Method)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at java.lang.reflect.Method.invoke(Method.java:507)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at dalvik.system.NativeStart.main(Native Method)
03-28 20:43:54.621: E/AndroidRuntime(4761): Caused by: java.lang.NullPointerException
03-28 20:43:54.621: E/AndroidRuntime(4761):     at com.andrew.omnidropper.OmniDropperActivity.onCreate(OmniDropperActivity.java:47)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at     android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-28 20:43:54.621: E/AndroidRuntime(4761):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1660)
03-28 20:43:54.621: E/AndroidRuntime(4761):     ... 11 more
03-28 20:43:59.519: I/Process(4761): Sending signal. PID: 4761 SIG: 9

I don't think imageview is null because I declare it, so why would it throw a nullPointerException?

arowell
  • 2,271
  • 2
  • 15
  • 19
  • Check out the [API](http://developer.android.com/reference/android/app/Activity.html), public View findViewById (int id), this method could return the view if found or null otherwise. – yorkw Mar 29 '12 at 02:08
  • Have you _confirmed_ that imageview is not null? It should only take one line of code to check. Also, it doesn't look like you _declare_ imageview. It looks like it is returned by _findViewById_. – jahroy Mar 29 '12 at 02:14

1 Answers1

4

Your imageview is probably null. The findViewById method will return null if it can't find the view. Are you sure the ImageView you're trying to fetch is defined in your main layout? I would step through it with a debugger and see if imageview is null.

Mike Bockus
  • 2,079
  • 17
  • 23
  • it's not in my main layout, it's in a different layout called "iscolorok" could that be causing the problem here? – arowell Mar 29 '12 at 02:29
  • 3
    Not causing the problem...That is the problem. when you call setContentView(R.layout.main) you are telling it that you want all of the views from the main.xml to be put onto the screen. If you were to tell it setContentView(R.layout.iscolorok) in a different activity then you could use findViewById() to get a reference to that ImageView. Simply: If it is is a different layout, then it is off the screen and you cannot use findViewById() to get a reference to it to interact with. – FoamyGuy Mar 29 '12 at 02:59
  • so I should put the setOnTouchListener and findByViewId for imageview in the place where I setContentView to iscolorok, right? – arowell Mar 29 '12 at 14:26
  • Yes, that's correct. In most cases, you should not be calling setContentView multiple times in a single Activity. It usually makes more sense to launch a new Activity where content view is set to `iscolorok`. Some additional details can be found on [this question](http://stackoverflow.com/questions/4757418/pattern-one-activity-multiple-views-advantages-and-disadvantages). – Mike Bockus Mar 29 '12 at 14:36