This is keeping me sleepless…
I’m creating a slideshow kind of app. Let’s say the package name is com.myapp.slideshow
User can create a new slideshow filled with pictures previously stored in the SD card app’s private folder (something like root/Android/data/com.myapp.slideshow/files/immagini/)
Because of this, i cannot use the built in gallery through ACTION_GET_CONTENT and therefore i have created my own gallery activity class.
So to recap i have SlideshowEditor.java where user click on a button to access the IMGALLERYactivity.java where they can click pich a picture from the gallery slide object and allegedly return back to SlideshowEditor.java with the picked picture Uri.
The problem with my code is that when i run the app (i test straight on device via eclipse) i don’t seem to get the Uri back and get a nullpointer exception which stops the app.
Here is the code i’m using:
SlideshowEditor.java
// set IDs for each type of media result
private static final int PICTURE_ID = 1;
private static final int MUSIC_ID = 2;
private static final int VIDEO_ID = 3;
private static final int TAKE_PICTURE_ID = 4;
// called when an Activity launched from this Activity returns
@Override
protected final void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (resultCode == RESULT_OK) // if there was no error
{
Uri selectedUri = data.getData();
// if the Activity returns an image
if (requestCode == PICTURE_ID ||
requestCode == TAKE_PICTURE_ID || requestCode == VIDEO_ID )
{
// determine media type
MediaItem.MediaType type = (requestCode == VIDEO_ID ?
MediaItem.MediaType.VIDEO : MediaItem.MediaType.IMAGE);
// add new MediaItem to the slideshow
slideshow.addMediaItem(type, selectedUri.toString());
// refresh the ListView
slideshowEditorAdapter.notifyDataSetChanged();
} // end if
else if (requestCode == MUSIC_ID) // Activity returns music
slideshow.setMusicPath(selectedUri.toString());
} // end if
} // end method onActivityResult
// called when the user touches the "Done" Button
private OnClickListener doneButtonListener = new OnClickListener()
{
// return to the previous Activity
@Override
public void onClick(View v)
{
finish();
} // end method onClick
}; // end OnClickListener doneButtonListener
// called when the user touches the "Add Picture" Button
private OnClickListener addPictureButtonListener = new OnClickListener()
{
// launch image choosing activity
@Override
public void onClick(View v)
{
Intent intent = new Intent(SlideshowEditor.this, IMGALLERYactivity.class);
//// String imgfolder = (Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Android" + File.separator + "data" + File.separator + "com.myapp.slideshow" + File.separator + "files" + File.separator + "immagini" + File.separator).toLowerCase();
// Uri startDir = Uri.fromFile(new File("Environment.getExternalStorageDirectory().getAbsolutePath()"));
//// intent.setDataAndType(Uri.parse(imgfolder), "image/*");
///intent.setType("image/*");
///intent.Output();
////startActivity(intent);
startActivityForResult(intent, PICTURE_ID);
} // end method onClick
}; // end OnClickListener addPictureButtonListener
IMGALLERYactivity.java
public class IMGALLERYactivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.imgallery);
Gallery g = (Gallery) findViewById(R.id.gallery); g.setAdapter(new ImageAdapter(this, ReadSDCard()));
g.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View v, int position, long id) {
Toast.makeText(IMGALLERYactivity.this, "" + position, Toast.LENGTH_SHORT).show();
Intent i = new Intent(IMGALLERYactivity.this, SlideshowEditor.class);
i.putExtra("PICTURE_ID", position);
setResult(Activity.RESULT_OK, i);
finish();
// Intent resultIntent = new Intent();
// // TODO Add extras or a data URI to this intent as appropriate.
// setResult(Activity.RESULT_OK, resultIntent);
// finish();
} }); }
private List<String> ReadSDCard() { List<String> tFileList = new ArrayList<String>();
//It have to be matched with the directory in SDCard
//File folder = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Android" + File.separator + "data" + File.separator
+ "com.deepsabrina.sabrinadeep" + File.separator + "files" + File.separator + "immagini");
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Android" + File.separator + "data" + File.separator
+ "com.deepsabrina.sabrinadeep" + File.separator + "files" + File.separator + "immagini" + File.separator);
File[] files=f.listFiles();
for(int i=0; i<files.length; i++) { File file = files[i]; /*It's assumed that all file in the path are in supported type*/ tFileList.add(file.getPath()); }
return tFileList; }
public class ImageAdapter extends BaseAdapter { int mGalleryItemBackground; private Context mContext; private List<String> FileList;
public ImageAdapter(Context c, List<String> fList) {
mContext = c;
FileList = fList;
TypedArray a = mContext.obtainStyledAttributes(R.styleable.HelloGallery);
mGalleryItemBackground = a.getResourceId(
R.styleable.HelloGallery_android_galleryItemBackground,0);
a.recycle(); }
public int getCount() {
return FileList.size(); }
public Object getItem(int position) {
return position; }
public long getItemId(int position) {
return position; }
public View getView(int position, View convertView,
ViewGroup parent) {
ImageView i = new ImageView(mContext);
Bitmap bm = BitmapFactory.decodeFile(
FileList.get(position).toString());
i.setImageBitmap(bm);
i.setLayoutParams(new Gallery.LayoutParams(150, 100));
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setBackgroundResource(mGalleryItemBackground);
return i; } }
public TypedArray obtainStyledAttributes(int theme) { // TODO Auto-generated method stub return null; } }
What am i doing wrong?
Any help would be really appreciated, possibly with code corrections as i have just started familiarizing with Android although i have a medium knowledge of java.
EDIT:
Thanks Brian! I was able to get the path of the selected item based on position, setting the get item() as you suggested and then creating the var like: String pippo = parent.getItemAtPosition(position).toString(); At least i’ve moved one step forward…However i’m still not able to pass it to the SlideshowEditor.class. This is what i have put on the IMGALLERYactivity class on the onitemclicklistener:
public void onItemClick(AdapterView<?> parent,
View v, int position, long id) {
String pippo = parent.getItemAtPosition(position).toString();
Intent data = new Intent(IMGALLERYactivity.this, SlideshowEditor.class);
data.putExtra("PICTURE_ID", pippo);
setResult(RESULT_OK, data);
finish();
}
On the SlideshowEditor.class i have
protected final void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (resultCode == RESULT_OK) // if there was no error
{
Uri selectedUri = Uri.parse(data.getDataString());
//Uri selectedUri = data.getData();
// if the Activity returns an image
if (requestCode == PICTURE_ID ||
requestCode == TAKE_PICTURE_ID || requestCode == VIDEO_ID )
{
// determine media type
MediaItem.MediaType type = (requestCode == VIDEO_ID ?
MediaItem.MediaType.VIDEO : MediaItem.MediaType.IMAGE);
// add new MediaItem to the slideshow
slideshow.addMediaItem(type, selectedUri.toString());
// refresh the ListView
slideshowEditorAdapter.notifyDataSetChanged();
} // end if
else if (requestCode == MUSIC_ID) // Activity returns music
slideshow.setMusicPath(selectedUri.toString());
} // end if
} // end method onActivityResult
The whole process is started with
Intent intent = new Intent(SlideshowEditor.this, IMGALLERYactivity.class);
startActivityForResult(intent,PICTURE_ID);
I keep getting nullpointerexception. I’ve tried to use eclipse debug and my understanding is that that nullpointerexception is shot at the IMGALLERYactivity when i create the intent, but i wouldn’t bet on it because eclipse debugging seems very confusing to me…however i toggled a breakpoint at the onactivityresult on the SlideshowEditor.class and it looks like the nullpointer exception is shot before it reaches that point. I know you don’t do private consulting, but i’m banging my head on this since 3 days now and any help would really help me out, before i go completely insane lol
This is the logcat results:
02-06 19:26:40.080: E/AndroidRuntime(10661): FATAL EXCEPTION: main
02-06 19:26:40.080: E/AndroidRuntime(10661):
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=null, request=1, result=-1, data=Intent {
cmp=com.deitel.enhancedslideshow/.SlideshowEditor (has extras) }} to
activity
{com.deitel.enhancedslideshow/com.deitel.enhancedslideshow.SlideshowEditor}:
java.lang.NullPointerException: uriString 02-06 19:26:40.080:
E/AndroidRuntime(10661): at
android.app.ActivityThread.deliverResults(ActivityThread.java:2918)
02-06 19:26:40.080: E/AndroidRuntime(10661): at
android.app.ActivityThread.handleSendResult(ActivityThread.java:2970)
02-06 19:26:40.080: E/AndroidRuntime(10661): at
android.app.ActivityThread.access$2000(ActivityThread.java:132) 02-06
19:26:40.080: E/AndroidRuntime(10661): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1068)
02-06 19:26:40.080: E/AndroidRuntime(10661): at
android.os.Handler.dispatchMessage(Handler.java:99) 02-06
19:26:40.080: E/AndroidRuntime(10661): at
android.os.Looper.loop(Looper.java:150) 02-06 19:26:40.080:
E/AndroidRuntime(10661): at
android.app.ActivityThread.main(ActivityThread.java:4277) 02-06
19:26:40.080: E/AndroidRuntime(10661): at
java.lang.reflect.Method.invokeNative(Native Method) 02-06
19:26:40.080: E/AndroidRuntime(10661): at
java.lang.reflect.Method.invoke(Method.java:507) 02-06 19:26:40.080:
E/AndroidRuntime(10661): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-06 19:26:40.080: E/AndroidRuntime(10661): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 02-06
19:26:40.080: E/AndroidRuntime(10661): at
dalvik.system.NativeStart.main(Native Method) 02-06 19:26:40.080:
E/AndroidRuntime(10661): Caused by: java.lang.NullPointerException:
uriString 02-06 19:26:40.080: E/AndroidRuntime(10661): at
android.net.Uri$StringUri.(Uri.java:420) 02-06 19:26:40.080:
E/AndroidRuntime(10661): at
android.net.Uri$StringUri.(Uri.java:410) 02-06 19:26:40.080:
E/AndroidRuntime(10661): at android.net.Uri.parse(Uri.java:382) 02-06
19:26:40.080: E/AndroidRuntime(10661): at
com.deitel.enhancedslideshow.SlideshowEditor.onActivityResult(SlideshowEditor.java:87)
02-06 19:26:40.080: E/AndroidRuntime(10661): at
android.app.Activity.dispatchActivityResult(Activity.java:4108) 02-06
19:26:40.080: E/AndroidRuntime(10661): at
android.app.ActivityThread.deliverResults(ActivityThread.java:2914)
So the only thing you’re adding to your Intent is this:
But then you’re trying to get something out of the resulting Intent in your
onActivityResult()method that you never put in:The only thing you could pull out of there is this:
Which… probably wouldn’t do a lot of good. You could put the URI in as an extra.
And pull that out on the other side in
onActivityResult().