Reputation: 506
I wish to add an image from Parse.com to an ImageView in a fragment I have created using Picasso. I get a Target must not be null.
error in logcat whenever I try to open the fragment. This is occurring in .into(mProfilePicture);
in the updateProfilePic()
. Can anyone tell me why this is happening?
public class MyProfileFragment extends Fragment implements View.OnClickListener {
public static final String TAG = MyProfileFragment.class.getSimpleName();
protected Button mTakePicture;
protected Button mChoosePicture;
protected ImageView mProfilePicture;
/**
* Default constructor
*/
public MyProfileFragment() {
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current state
if (mMediaUri != null) {
savedInstanceState.putString("media_uri", mMediaUri.toString());
Log.d(TAG, "onSaveInstanceState() for mMediaUri: " + mMediaUri);
}
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mMediaUri = Uri.parse(savedInstanceState.getString("media_uri"));
Log.d(TAG, "onCreate() for mMediaUri: " + mMediaUri);
}
updateProfilePic();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_my_profile, container, false);
mProfilePicture = (ImageView) rootView.findViewById(R.id.profilePicture);
mTakePicture = (Button) rootView.findViewById(R.id.takePictureButton);
mChoosePicture = (Button) rootView.findViewById(R.id.choosePictureButton);
mTakePicture.setOnClickListener(this);
mChoosePicture.setOnClickListener(this);
return rootView;
}
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
@Override
public void onClick(View v) {
// Switch statement to select which action to take depending on button/text pressed
switch (v.getId()) {
case R.id.takePictureButton:
takeCameraPicture();
break;
case R.id.choosePictureButton:
chooseGalleryPicture();
break;
default:
System.out.println("Problem with input");
}
}
public static final int TAKE_PHOTO_REQUEST = 1889;
public static final int PICK_PHOTO_REQUEST = 1888;
// member variable to store the media type as a URI, that can be stored in multiple places
// Uri = uniform resource identifier
private Uri mMediaUri;
public void takeCameraPicture() {
// Take picture
// use an existing camera app on the phone by starting an intent
// declare intent to capture a photo using whatever camera app is available
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// after invoking the camera,
mMediaUri = getOutputMediaFileUri();
// check that a null value is not returned
if (mMediaUri == null) {
// display an error
Toast.makeText(getActivity(), R.string.error_external_storage, Toast.LENGTH_LONG).show();
} else {
// start an activity for a result so that the activity exits and returns a result back for us
// ie, the main activity will wait for the result
startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST);
}
}
public void chooseGalleryPicture() {
// Choose picture
Intent choosePhotoIntent = new Intent(Intent.ACTION_GET_CONTENT);
// need to specify which type of action we want to get - an image in this case
choosePhotoIntent.setType("image/*");
startActivityForResult(choosePhotoIntent, PICK_PHOTO_REQUEST);
}
private Uri getOutputMediaFileUri() {
// To be safe, you should check that the SD card / external storage is mounted
// using Environment.getExternalStorageState() before doing this.
// see method below...
if (isExternalStorageAvailable()) {
String appName = MyProfileFragment.this.getString(R.string.app_name);
// get the Uri
// Get the external storage directory - we want to return a file object
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appName);
// Create our subdirectory
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdir()) {
Log.e(TAG, "Failed to create directory");
return null;
}
}
// Create a file to hold the image
File mediaFile;
// get the current date and time
Date now = new Date();
// convert the date and time into a String datetimestamp
// see http://developer.android.com/guide/topics/media/camera.html#saving-media for the methods used
// need to append a timestamp to make it unique - otherwise it will overwrite the previous photo
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(now);
String path = mediaStorageDir.getPath() + File.separator;
// create a new file using the constructor that takes a name
mediaFile = new File(path + "IMG_" + timestamp + ".jpg");
Log.d(TAG, "File: " + Uri.fromFile(mediaFile));
// Return the files URI
Log.d(TAG, "Returning the files URI");
return Uri.fromFile(mediaFile);
} else {
return null;
}
}
/**
* check if external storage is available on the users device
*
* @return
*/
private boolean isExternalStorageAvailable() {
// find out what state external storage is in
String state = Environment.getExternalStorageState();
// if external storage is available, return true,
if (state.equals(Environment.MEDIA_MOUNTED)) {
return true;
} else {
return false;
}
}
private Bitmap bitmapPicture;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PICK_PHOTO_REQUEST) {
if (data == null) {
Log.d(TAG, "Data is null");
Toast.makeText(getActivity(), getString(R.string.general_error), Toast.LENGTH_LONG).show();
} else {
// the intent has data, so set the media uri
mMediaUri = data.getData();
Log.d(TAG, "Media Uri: " + mMediaUri);
}
saveImageToParse(PICK_PHOTO_REQUEST);
updateProfilePic();
} else if (requestCode == TAKE_PHOTO_REQUEST) {
bitmapPicture = (Bitmap) data.getExtras().get("data");
Log.d(TAG, "bitmapPicture picture: " + bitmapPicture);
saveImageToParse(TAKE_PHOTO_REQUEST);
}
} else if (resultCode != Activity.RESULT_CANCELED) {
Log.d(TAG, "Problem getting the picture from gallery");
Toast.makeText(getActivity(), R.string.general_error, Toast.LENGTH_LONG).show();
}
}
public void saveImageToParse(int requestCode) {
if (requestCode == PICK_PHOTO_REQUEST) {
byte[] fileBytes = FileHelper.getByteArrayFromFile(getActivity(), mMediaUri);
fileBytes = FileHelper.reduceImageForUpload(fileBytes);
String fileName = FileHelper.getFileName(getActivity(), mMediaUri, "file");
ParseFile file = new ParseFile(fileName, fileBytes);
ParseUser.getCurrentUser().put("profilePic", file);
} else {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
bitmapPicture.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
byte[] fileBytes = byteStream.toByteArray();
String fileName = FileHelper.getFileName(getActivity(), mMediaUri, "file");
ParseFile file = new ParseFile(fileName, fileBytes);
ParseUser.getCurrentUser().put("profilePic", file);
}
ParseUser.getCurrentUser().saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
Log.d(TAG, "Image saved successfully");
} else {
Log.d(TAG, "Image not saved");
}
}
});
}
public void updateProfilePic() {
ParseFile image = (ParseFile) ParseUser.getCurrentUser().getParseFile("profilePic");
// Email will be an empty String if the user didn't supply an email address
if (image == null) {
// If image file is empty, set the default avatar
Log.d(TAG, "No profile picture for: " + ParseUser.getCurrentUser().getUsername());
// holder.userImageView.setImageResource(R.mipmap.avatar_empty);
} else {
Picasso.with(getActivity())
// Load the URL
.load(image.getUrl())
// if a 404 code is returned, use the placeholder image
.placeholder(R.mipmap.avatar_empty)
// Load into user image view
.into(mProfilePicture);
}
}
}
.
09-02 14:45:23.502 26690-26690/com.khackett.runmate E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.khackett.runmate, PID: 26690
java.lang.IllegalArgumentException: Target must not be null.
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:618)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
at com.khackett.runmate.ui.MyProfileFragment.updateProfilePic(MyProfileFragment.java:297)
at com.khackett.runmate.ui.MyProfileFragment.onCreate(MyProfileFragment.java:72)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1766)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:917)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Upvotes: 0
Views: 2141
Reputation: 39846
you call updateProfilePic()
during your fragment onCreate
, and then onCreateView
that you're assigning the value to mProfilePicture
.
So all that Picasso received was:
.into(null);
just remove your updateProfilePic()
from onCreate
and put after mProfilePicture
have the correct value.
Upvotes: 1