"Unable to resume activity" after saving cropped image - Android - java

I want to load the image in ImageView after cropping the image and save it. But when it's resumes it gets crashed, but image is saving on selected location. I think the problem is in selectedImageUri. But I couldn't figure it out how to solve. Please someone help. Thanks in advance.
Code:
public class CatFragment extends Fragment implements OnClickListener{
private DBCreater dbCreate;
private static final int SELECT_PICTURE = 1;
private String selectedImagePath = "android.resource://com.example.abcd/" + R.drawable.pets;
private ImageView img;
//private Button imgBtn;
private Uri mCropImagedUri;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View gv = inflater.inflate(R.layout.new_pet, null);
Spinner sp = (Spinner) gv.findViewById(R.id.ETPetType);
// get reference
sp.setAdapter(new ArrayAdapter<String>(getActivity().getBaseContext(), android.R.layout.simple_spinner_dropdown_item, petType));
Button btnSubmit = (Button) gv.findViewById(R.id.ButtonNext);
btnSubmit.setOnClickListener(this);
img = (ImageView)gv.findViewById(R.id.ImageView01);
((Button) gv.findViewById(R.id.ETPetImg))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
try {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 0);
intent.putExtra("aspectY", 0);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("return-data", false);
File f = createNewFile("CROP_");
try {
f.createNewFile();
} catch (IOException ex) {
Log.e("io", ex.getMessage());
}
mCropImagedUri = Uri.fromFile(f);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
mCropImagedUri);
// start the activity - we handle returning in
// onActivityResult
startActivityForResult(intent, SELECT_PICTURE);
} catch (ActivityNotFoundException anfe) {
// display an error message
}
}
});
return gv;
}
private File createNewFile(String prefix){
if(prefix==null || "".equalsIgnoreCase(prefix)){
prefix="IMG_";
}
File newDirectory = new File(Environment.getExternalStorageDirectory()+"/test1/");
if(!newDirectory.exists()){
if(newDirectory.mkdir()){
Log.d(this.getClass().getName(), newDirectory.getAbsolutePath()+" directory created");
}
}
File file = new File(newDirectory,(prefix+System.currentTimeMillis()+".jpg"));
if(file.exists()){
//this wont be executed
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri); //To get image path
System.out.println("Image Path : " + selectedImagePath);
img.setImageURI(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
//Cursor cursor = managedQuery(uri, projection, null, null, null);
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//access the database
dbCreate = new DBCreater(getActivity());
}
#Override
public void onClick(View v) {
displayNextAlert();
}
LogCat:
7214): FATAL EXCEPTION: main
11-15 07:15:38.215: E/AndroidRuntime(27214): java.lang.RuntimeException: Unable to resume activity {com.example.abcd/com.example.abcd.MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=android:fragment:0, request=1, result=-1, data=Intent { (has extras) }} to activity {com.example.abcd/com.example.abcd.MainActivity}: java.lang.NullPointerException
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2919)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2948)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2354)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.access$700(ActivityThread.java:159)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.os.Handler.dispatchMessage(Handler.java:99)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.os.Looper.loop(Looper.java:176)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.main(ActivityThread.java:5419)
11-15 07:15:38.215: E/AndroidRuntime(27214): at java.lang.reflect.Method.invokeNative(Native Method)
11-15 07:15:38.215: E/AndroidRuntime(27214): at java.lang.reflect.Method.invoke(Method.java:525)
11-15 07:15:38.215: E/AndroidRuntime(27214): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
11-15 07:15:38.215: E/AndroidRuntime(27214): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
11-15 07:15:38.215: E/AndroidRuntime(27214): at dalvik.system.NativeStart.main(Native Method)
11-15 07:15:38.215: E/AndroidRuntime(27214): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=android:fragment:0, request=1, result=-1, data=Intent { (has extras) }} to activity {com.example.abcd/com.example.abcd.MainActivity}: java.lang.NullPointerException
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.deliverResults(ActivityThread.java:3500)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2906)
11-15 07:15:38.215: E/AndroidRuntime(27214): ... 12 more
11-15 07:15:38.215: E/AndroidRuntime(27214): Caused by: java.lang.NullPointerException
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1147)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.content.ContentResolver.query(ContentResolver.java:401)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.content.ContentResolver.query(ContentResolver.java:360)
11-15 07:15:38.215: E/AndroidRuntime(27214): at com.example.abcd.NewPetsFragment.getPath(NewPetsFragment.java:155)
11-15 07:15:38.215: E/AndroidRuntime(27214): at com.example.abcd.NewPetsFragment.onActivityResult(NewPetsFragment.java:143)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.Activity.dispatchActivityResult(Activity.java:5567)
11-15 07:15:38.215: E/AndroidRuntime(27214): at android.app.ActivityThread.deliverResults(ActivityThread.java:3496)
11-15 07:15:38.215: E/AndroidRuntime(27214): ... 13 more
Edited:
I changed OnActivityResult() like this:
if(data!=null) {
Bitmap thePic = (Bitmap) data.getExtras().get("data");
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
String filename = preferences.getString("file_name", ""); // value to retrieve
String path = Environment.getExternalStorageDirectory()+"/PetSitter/Pet Images/" + filename;
img.setImageURI(Uri.parse(path.toString()));
} else {
// In createNewFile, make sure you already saved the filename (prefix+System.currentTimeMillis()+".jpg"), for example, to sharedpreferences then get the filename and apply in path
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
String filename = preferences.getString("file_name", ""); // value to retrieve
String path = Environment.getExternalStorageDirectory()+"/PetSitter/Pet Images/" + filename;
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 1;
Bitmap bmp = BitmapFactory.decodeFile(path, bfo);
img.setImageBitmap(bmp);
}
It's seems to be working with image preview and everything. But what do thing? Is it a good practice to do? and how will be the memory usage by using like this?

In OnActivityResult():
if(data!=null) {
Bitmap thePic = (Bitmap) data.getExtras().get("data");
img.setImageBitmap(thePic);
} else {
// In createNewFile, make sure you already saved the filename (prefix+System.currentTimeMillis()+".jpg"), for example, to sharedpreferences then get the filename and apply in path
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
String filename = preferences.getString("file_name", ""); // value to retrieve
String path = Environment.getExternalStorageDirectory()+"/test1/" + filename;
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 1;
Bitmap bmp = BitmapFactory.decodeFile(path, bfo);
img.setImageBitmap(bmp);
}
In createNewFile
private File createNewFile(String prefix){
if(prefix==null || "".equalsIgnoreCase(prefix)){
prefix="IMG_";
}
File newDirectory = new File(Environment.getExternalStorageDirectory()+"/test1/");
if(!newDirectory.exists()){
if(newDirectory.mkdir()){
Log.d(this.getClass().getName(), newDirectory.getAbsolutePath()+" directory created");
}
}
// modifications applied here
long mDate = System.currentTimeMillis();
File file = new File(newDirectory,(prefix+mDate+".jpg"));
String filename = prefix+mDate+".jpg";
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("file_name", filename); // value to store
editor.commit();
if(file.exists()){
//this wont be executed
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}

Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));
And
private String getRealPathFromURI(Uri contentURI) {
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
return contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}

Try this in onActivityResult
Bitmap photo = (Bitmap) data.getExtras().get("data");
img.setImageBitmap(photo);

I changed OnActivityResult() like this:
if(data!=null) {
Bitmap thePic = (Bitmap) data.getExtras().get("data");
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
String filename = preferences.getString("file_name", ""); // value to retrieve
String path = Environment.getExternalStorageDirectory()+"/PetSitter/Pet Images/" + filename;
img.setImageURI(Uri.parse(path.toString()));
} else {
// In createNewFile, make sure you already saved the filename (prefix+System.currentTimeMillis()+".jpg"), for example, to sharedpreferences then get the filename and apply in path
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
String filename = preferences.getString("file_name", ""); // value to retrieve
String path = Environment.getExternalStorageDirectory()+"/PetSitter/Pet Images/" + filename;
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 1;
Bitmap bmp = BitmapFactory.decodeFile(path, bfo);
img.setImageBitmap(bmp);
}
It's seems to be working with image preview and everything.

Related

Get Real Path of mp3 file from Uri

I have picked audio file from Content Picker intent inside Fragment which extend PreferenceFragmentCompat
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("audio/mpeg");
startActivityForResult(intent, 1);
and Retrieved Uri from onActivityResult
#Override
public void onActivityResult(int requestCode, int resultcode, Intent data) {
if (requestCode == 1 && resultcode == Activity.RESULT_OK) {
audio = data.getData();
inputfile= (FileInputStream getActivity().getApplicationContext().getContentResolver().openInputStream(data.getData());
}
super.onActivityResult(requestCode, resultcode, data);
}
Where audio is declared public(Uri audio).
Now i wanted this audio file to be copied to a Directory in App Directory(/data/data/com.example.focusit).For this i need to get Real path of audio file from URI
public String getRealPathFromUri(Uri contentUri) {
String res = null;
String[] proj = {
MediaStore.Audio.Media.DATA
};
Cursor cursor = (Cursor) getActivity().getApplicationContext().getContentResolver().query(contentUri, proj, null, null, null);
if (cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
Now to copy audio file to my directoy i used this code
File audiofile = new File(audio.getPath());
String realpath = getRealPathFromUri(audio);
File file = new File("/data/data/com.example.focusit/Focusit_SOS/tt_temp.mp3");
if (!file.exists()) {
Toast.makeText(getContext(), "Director focus it does not existed", Toast.LENGTH_SHORT).show();
file.mkdirs();
}
try {
FileUtils.copy(new FileInputStream(audiofile), new FileOutputStream(file));enter code here
} catch (IOException e) {
e.printStackTrace();
But problem is that in function getRealPathFromUri(Uri ContentUri) cursor.movetoFirst() is returning false.Any idea how to deal with it.
Output of audio.getpath() is /external/audio/media/8099.
i tried one solution by creating Input stream directly from Uri in onActivityResult()
inputfile= (FileInputStream) getActivity().getApplicationContext().getContentResolver().openInputStream(data.getData());
but i am getting exception
2020-10-28 07:41:31.333 21292-21292/com.example.focusit E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.focusit, PID: 21292
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=Intent { dat=content://media/external/audio/media/8099 (has extras) }} to activity {com.example.focusit/com.example.focusit.SettingsActivity}: java.lang.SecurityException: com.example.focusit has no access to content://media/external/audio/media/8099
at android.app.ActivityThread.deliverResults(ActivityThread.java:4905)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4946)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2040)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7520)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.SecurityException: com.example.focusit has no access to content://media/external/audio/media/8099
at android.os.Parcel.createException(Parcel.java:2074)
at android.os.Parcel.readException(Parcel.java:2042)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:151)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:705)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1702)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1518)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1202)
at com.example.focusit.SettingsActivity$SettingsFragment.onActivityResult(SettingsActivity.java:227)
at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:170)
at android.app.Activity.dispatchActivityResult(Activity.java:8249)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4898)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4946) 
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2040) 
at android.os.Handler.dispatchMessage(Handler.java:107) 
at android.os.Looper.loop(Looper.java:224) 
at android.app.ActivityThread.main(ActivityThread.java:7520) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) `
Providing Storage access will resolve Exception
java.lang.SecurityException: com.example.focusit has no access to content:
Do not open a FileInputStream on a path you do not have.
Instead open an InputStream on the obtained uri directly.
InputStream is = getContentResolver().openInputStream(data.getData());

How to use FileProvider in Uri.parse(file://" + filex.toString()) & Java.lang.RuntimeException Error Receiving BroadCast Intent

How to use FileProvider for not getting error in android API >= 24?
I've tried FileProvider but it's still getting error...
Here is my source code
if(vid.equals("")) {
inFileName = img.substring(img.lastIndexOf('/') + 1);
File sdcard = Environment.getExternalStorageDirectory();
File filex = new File(sdcard, inDir + "/" + "IMAGE_" + inFileName);
if(filex.exists()) {
if (inDialog.isShowing())
inDialog.dismiss();
Uri uri = Uri.parse("file://" + filex.toString());
Intent i = new Intent();
i.setAction(Intent.ACTION_VIEW);
i.setDataAndType(uri, "image/*");
inContext.startActivity(i);
} else {
inTmp = Uri.parse(img);
Image_DownloadId = DownloadData(inTmp, "IMAGE_" + inFileName);
}
}
First log
android.os.FileUriExposedException: file:///storage/emulated/0/Images/IMAGE_26072028_383759662086144_8624202031520808960_n.jpg exposed beyond app through Intent.getData()
This error because of using android api >= 24 and need to use FileProvider, so I try to use it..
this line is a little bit confusing because of using toString method
Uri.parse("file://" + filex.toString())
Here is what I'm trying to do
if(vid.equals("")) {
inFileName = img.substring(img.lastIndexOf('/') + 1);
File sdcard = Environment.getExternalStorageDirectory();
File filex = new File(sdcard, inDir + "/" + "IMAGE_" + inFileName);
if(filex.exists()) {
if (inDialog.isShowing())
inDialog.dismiss();
Uri uri = FileProvider.getUriForFile(inContext, inContext.getApplicationContext().getPackageName() + ".provider", new File("file://" + filex.toString()));
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(uri, "image/*");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
inContext.startActivity(i);
} else {
inTmp = Uri.parse(img);
Image_DownloadId = DownloadData(inTmp, "IMAGE_" + inFileName);
}
The application still getting force close.
Here is the log
01-14 17:48:24.288 23382-23382/com.my.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.my.app, PID: 23382
java.lang.IllegalArgumentException: Failed to find configured root that contains /file:/storage/emulated/0/Images/IMAGE_26072028_383759662086144_8624202031520808960_n.jpg
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
at com.my.app.App$Loading$1.onClick(Saver.java:128)
at android.view.View.performClick(View.java:5619)
at android.view.View$PerformClick.run(View.java:22295)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6321)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)
Got another error in this line
String filename = cursor.getString(filenameIndex);
BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//check if the broadcast message is for our Enqueued download
long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if(referenceId == Image_DownloadId) {
DownloadManager.Query ImageDownloadQuery = new DownloadManager.Query();
//set the query filter to our previously Enqueued download
ImageDownloadQuery.setFilterById(Image_DownloadId);
//Query the download manager about downloads that have been requested.
Cursor cursor = downloadManager.query(ImageDownloadQuery);
if(cursor.moveToFirst()){
int filenameIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
String filename = cursor.getString(filenameIndex);
Uri uri = Uri.parse("file://" + filename);
Intent i = new Intent();
if(inTenTipe.equals("repost")) {
i.setAction(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_STREAM, uri);
i.setType("image/*");
}else {
i.setAction(Intent.ACTION_VIEW);
i.setDataAndType(uri, "image/*");
}
try {
if (inDialog.isShowing())
inDialog.dismiss();
inContext.startActivity(i);
} catch (android.content.ActivityNotFoundException ex) {
File file = new File(filename);
boolean deleted = file.delete();
Image_DownloadId = DownloadData(inTmp, "IMAGE_" + inFileName);
}
}
}
}
}
Log
FATAL EXCEPTION: main
Process: com.my.app, PID: 29139
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.my.app (has extras) } in com.my.app.APP$1#cc58ede
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1140)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6321)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)
Caused by: java.lang.SecurityException: COLUMN_LOCAL_FILENAME is deprecated; use ContentResolver.openFileDescriptor() instead
at android.app.DownloadManager$CursorTranslator.getString(DownloadManager.java:1791)
at com.my.app.App$1.onReceive(Saver.java:616)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1130)
at android.os.Handler.handleCallback(Handler.java:754) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:163) 
at android.app.ActivityThread.main(ActivityThread.java:6321) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

Cursor error - Retrieving image from gallery

Currently I'm trying to retrieve the location of an image in my gallery and convert it into a File so that I can upload it to the internet. But I received this error instead. The error happened when I open the gallery and on selecting the image it crash instead. I'm not so well versed in android and still consider myself a beginner. So if you decided to vote down my question please tell me the reason why so that I can learn. Thank you.
Logcat :-
05-07 08:11:45.052 8697-8697/com.example.megasap.jobforhire_android E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.megasap.jobforhire_android, PID: 8697
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/image:34 flg=0x1 }} to activity {com.example.megasap.jobforhire_android/com.example.megasap.jobforhire_android.ProfileEditActivity}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at android.database.CursorWrapper.getString(CursorWrapper.java:137)
at com.example.megasap.jobforhire_android.ProfileEditActivity.getRealPathFromURI(ProfileEditActivity.java:233)
at com.example.megasap.jobforhire_android.ProfileEditActivity.onActivityResult(ProfileEditActivity.java:191)
at android.app.Activity.dispatchActivityResult(Activity.java:6428)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) 
at android.app.ActivityThread.-wrap16(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
The code that I used to retrieved the image is down below:-
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx); // getting error here ; it returns -1
cursor.close();
}
return result;
}
You have to add column name MediaStore.Images.Media.DATA with query.
Update getRealPathFromURI() as below:
private String getRealPathFromURI(Uri contentURI) {
String result;
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(contentURI, filePathColumn, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(filePathColumn[0]);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
In you onActivityResult() method:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
// When an Image is picked
if (requestCode == YOUR_REQUEST_CODE && resultCode == RESULT_OK
&& null != data) {
// Get the Image from data
Uri selectedImage = data.getData();
// Get real path
String imageRealPath = getRealPathFromURI(selectedImage);
// Do something
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
}
Make sure you have added permission:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Here is a good tutorial. Hope this will help~
You should not try to get a file path and construct a file object from that uri to upload the file. You dont need that all. Use the uri directly to open an inputstream.
Somewhere you will now have
FileInputStream fis = new FileInputStream(path);
Replace that by
InputStream is = getContentResolver().openInputStream(data.getData());
This supports APIs below and above 19, including 19:
public String getRealPathFromURI(Uri uri) {
Cursor cursor = this.getContentResolver().query(uri, null, null, null, null);
String result;
// for API 19 and above
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
cursor.moveToFirst();
String image_id = cursor.getString(0);
image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
cursor.close();
cursor = this.getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
}
cursor.moveToFirst();
result = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return result;
}

loading last chosen image into ImageView after re-entering the app

My goal is to make last chosen image to stay in ImageView after an app was closed (destroyed) and then re-opened.
I tried to load to save bitmap in SharedPreference "(How can I store images using sharedpreference in android?), then I tried to store path to bitmap in SharedPreferences and load it using Picasso: (Picasso Load image from filesystem), and tried to load it by passing the value to BitmapFactory.decodeFile(completePath); as you can see in my code.
Anyway the output is always the same; I'm getting an NullPointerException.
I'm new to Android and programming in general so forgive my messy code.
private String picturePass;
private ImageView imageView;
private Bitmap picBitmap;
private boolean yes;
private static final int SELECT_PICTURE = 1;
private static final String SAVE_NAME = "MyFile";)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity_page);
if (savedInstanceState != null) {
savedInstanceState.get("path");
}
//loading
SharedPreferences preferences = getSharedPreferences(SAVE_NAME, MODE_PRIVATE);
//boolean to check if Image was chosen
yes = preferences.getBoolean("yes", true);
if(yes){
picturePass = preferences.getString("path", null);
String completePath = picturePass;
//just to check the content
Toast.makeText(this, completePath, Toast.LENGTH_LONG).show();
File file = new File(completePath);
if (file.exists()) {
picBitmap = BitmapFactory.decodeFile(completePath);
imageView.setImageBitmap(picBitmap);
}
}
}
//Choosing a picture from gallery
public void onClickImage(View view) {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, SELECT_PICTURE);
yes = true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SELECT_PICTURE && resultCode == RESULT_OK && null != data) {
//The only way I maneged to get the file path, that's a messy part
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
//Setting picture in imageView
if (selectedImage != null) {
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(bitmap);
picBitmap = bitmap;
//Tried to use Environment.getExternalStorageDirectory().getAbsolutePath() + imageName with no success
//File f = new File(picturePath);
//String imageName = f.getName();
//picturePass = imageName;
picturePass = picturePath;
//Saving image path
//just too check the content
Toast.makeText(this, picturePath, Toast.LENGTH_LONG).show();
SharedPreferences.Editor editor = getSharedPreferences(SAVE_NAME, MODE_PRIVATE).edit();
editor.putString("path", picturePass);
editor.putBoolean("yes", true);
editor.commit();
} catch (Exception ex) {
ex.printStackTrace();
}
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("path", picturePass);
}
}
08-29 19:05:46.263 16436-16436/com.amberapply.vitaliy.iloveyou E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.amberapply.vitaliy.iloveyou, PID: 16436
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.amberapply.vitaliy.iloveyou/com.amberapply.vitaliy.iloveyou.MainActivityPage}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5258)
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:940)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:735)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageBitmap(android.graphics.Bitmap)' on a null object reference
at com.amberapply.vitaliy.iloveyou.MainActivityPage.onCreate(MainActivityPage.java:60)
at android.app.Activity.performCreate(Activity.java:6005)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) 
at android.app.ActivityThread.access$800(ActivityThread.java:151) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5258) 
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:940) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:735) 
#Nikunj Sardhara solution should work
if you fix the npe : in onCreate there is no imageView = (ImageView) findViewById(R.id.imageView); before `imageView.setImageBitmap(picBitmap);
First of all storing an image in SharedPreferences would be a very bad idea.
You should store path of image in SharedPreferences and you can read that image when your app loads for the first time, read the SharedPreferences, get your image path, read it from storage and show it in your ImageView.
So, that was the procedure and that is simple, It does't require writing this much code.
Now you don't really need to store boolean in SharedPreferences, you can use contains() method :
https://developer.android.com/reference/android/content/SharedPreferences.html
And about NullPointerException, i would say please check logcat and if possible then copy your logcat at the time of NullPointerException and post your logcat here, that would be more helpful.
Here's how you can get logcat : https://developer.android.com/studio/debug/am-logcat.html

Application crashes when trying to take pictures/record video

I've just followed this guide: http://www.androidhive.info/2013/09/android-working-with-camera-api/
Trying to create a camera feature for my app, however when I click either take a picture or record a video (Either of the buttons), it crashes on me. I've checked through the code, but I can't seem to find the error.
CameraActivity.java:
package com.example.frederik.snapsule;
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.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.VideoView;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class CameraActivity extends AppCompatActivity {
//Activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
//Storing of content
private static final String IMAGE_DIRECTORY_NAME = "Hello Camera";
private Uri fileUri; //Content url storing
private ImageView imgPreview;
private VideoView videoPreview;
private Button btnCapturePicture, btnRecordVideo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_camera);
imgPreview = (ImageView) findViewById(R.id.imgPreview);
videoPreview = (VideoView) findViewById(R.id.videoPreview);
btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
btnRecordVideo = (Button) findViewById(R.id.btnRecordVideo);
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
captureImage();
}
});
btnRecordVideo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
recordVideo();
}
});
}
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
// code to check capture image response
} else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// video successfully recorded
// preview the recorded video
previewVideo();
} else if (resultCode == RESULT_CANCELED) {
// user cancelled recording
Toast.makeText(getApplicationContext(),
"User cancelled video recording", Toast.LENGTH_SHORT)
.show();
} else {
// failed to record video
Toast.makeText(getApplicationContext(),
"Sorry! Failed to record video", Toast.LENGTH_SHORT)
.show();
}
}
}
private void previewCapturedImage() {
try {
videoPreview.setVisibility(View.GONE);
imgPreview.setVisibility(View.VISIBLE);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
options);
imgPreview.setImageBitmap(bitmap);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
private void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
private void previewVideo() {
try {
imgPreview.setVisibility(View.GONE);
videoPreview.setVisibility(View.VISIBLE);
videoPreview.setVideoPath(fileUri.getPath());
videoPreview.start();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
fileUri = savedInstanceState.getParcelable("file_uri");
}
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type) {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " + IMAGE_DIRECTORY_NAME + " directory" );
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}
And my logcat:
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: FATAL EXCEPTION: main
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: Process: com.example.frederik.snapsule, PID: 23065
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: java.lang.NullPointerException: file
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at android.net.Uri.fromFile(Uri.java:452)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at com.example.frederik.snapsule.CameraActivity.getOutputMediaFileUri(CameraActivity.java:161)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at com.example.frederik.snapsule.CameraActivity.captureImage(CameraActivity.java:72)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at com.example.frederik.snapsule.CameraActivity.access$000(CameraActivity.java:26)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at com.example.frederik.snapsule.CameraActivity$1.onClick(CameraActivity.java:57)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at android.view.View.performClick(View.java:5198)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:21147)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
My guess is it's an issue with Uri, but I'm unsure.
Also, the preview is not showing
It is a null pointer exception at line 161.
Apparently you hand in null into Uri.fromFile().
Therefore getOutputMediaFile(int type) returns null.
That may be the case if you see "Oops! Failed create" in your log.
It may be the case if type is neither MEDIA_TYPE_IMAGE nor MEDIA_TYPE_VIDEO.
It may be the case if new File(...) returned null.
Did you try debugging that method?
Your method
File getOutputMediaFile(int type)
its returning null, you have 2 return null; statements in it.
You should make a null check before calling Uri.fromFile()
EDIT
Just change this code to get rid of the crash, but it will still fail, you need to fix the original cause.
public Uri getOutputMediaFileUri(int type) {
File f = getOutputMediaFile(type);
if(f != null)
return Uri.fromFile(f);
else{
//Show some error message
return null;
}
}
Hope this helps.

Categories