Reputation: 7
I am trying to pass my image with intent in Xamarin Android with C#. In the first activity, I am using BitmapFactory.DecodeFile(uri_path);
for decode my image path into bitmap file. I also set that bitmap picture with imgView.SetImageBitmap(BitMap);
then, I pass that URI path in my button click which is the button will reference the picture to the next activity using intent.PutExtra("path", mCurrentPhotoPath);
. In the next activity, I want to get the passing path value from the first activity.
string path = intent.GetStringExtra("path");
if (path != null)
{
Bitmap bitmap = BitmapFactory.DecodeFile(path);
m_imageView.SetImageBitmap(bitmap);
}
else
{
Toast.MakeText(this, "Your picture empty!", ToastLength.Long).Show();
}
But, I get an error with a null exception error. The path return null and the program is crashing. Please help me! I feel stuck after few hours. Any help? Here's my full code :
first activity - my onActivityResult
private Button btnContinue, btnCapture;
private ImageView imgView;
public Bitmap BitMap;
private Android.Net.Uri filePath;
private const int c_TAKE_IMAGE_REQUSET = 72;
private ProgressBar progressBar;
public String mCurrentPhotoPath = null;
public override void OnActivityResult(int requestCode, int resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == c_TAKE_IMAGE_REQUSET &&
resultCode == (int)Result.Ok &&
data != null)
{
filePath = data.Data;
//String mCurrentPhotoPath = null;
try
{
mCurrentPhotoPath = GetRealPathFromURI(filePath);
}
catch (Exception ex)
{
// Failed for some reason.
}
try
{
BitMap = (Bitmap)data.Extras.Get("data");
imgView.SetImageBitmap(BitMap);
BitMap = BitmapFactory.DecodeFile(mCurrentPhotoPath);
System.Diagnostics.Debug.WriteLine("Image path == " + mCurrentPhotoPath);
}
catch (System.IO.IOException ex)
{
System.Console.WriteLine(ex);
}
var bitmap = BitmapFactory.DecodeFile(mCurrentPhotoPath); // decode the path into bitmap
imgView.SetImageBitmap(bitmap);
}
}
private string GetRealPathFromURI(Android.Net.Uri uri)
{
string doc_id = "";
using (var c1 = this.View.Context.ContentResolver.Query(uri, null, null, null, null))
{
c1.MoveToFirst();
string document_id = c1.GetString(0);
doc_id = document_id.Substring(document_id.LastIndexOf(":") + 1);
}
string path = null;
// The projection contains the columns we want to return in our query.
string selection = Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " =? ";
using (var cursor = this.View.Context.ContentResolver.Query(Android.Provider.MediaStore.Images.Media.ExternalContentUri, null, selection, new string[] { doc_id }, null))
{
if (cursor == null) return path;
var columnIndex = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data);
cursor.MoveToFirst();
path = cursor.GetString(columnIndex);
}
return path;
}
}
second activity - onCreate protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Upload);
string path = intent.GetStringExtra("path");
if (path != null)
{
Bitmap bitmap = BitmapFactory.DecodeFile(path);
m_imageView.SetImageBitmap(bitmap);
}
else
{
Toast.MakeText(this, "Your picture empty!", ToastLength.Long).Show();
}
m_upload.Click += M_upload_Click;
}
EDIT: I Put my put string extra in my button. The button is Button Continue which is a reference to the next activity
private void btnContinue_Click(object sender, EventArgs e)
{
Busy();
Intent intent = new Intent(Activity, typeof(UploadActivity));
intent.PutExtra("path", mCurrentPhotoPath);
StartActivity(intent);
}
Upvotes: 0
Views: 745
Reputation: 15031
I think this only happens after you've taken a picture,because filePath = data.Data;
return null
,if you choose a picture from photos,it will return its uri
.
So you could try to use other methods,you could passing the byte[]
data of the bitmap after you take a picture :
public override void OnActivityResult(int requestCode, int resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == c_TAKE_IMAGE_REQUSET &&
resultCode == (int)Result.Ok &&
data != null)
{
try
{
mBitMap = (Bitmap)data.Extras.Get("data");
imgView.SetImageBitmap(mBitMap);
using (var stream = new MemoryStream())
{
mBitMap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
bitmapData = stream.ToArray();
}
}
catch (System.IO.IOException ex)
{
System.Console.WriteLine(ex);
}
}
}
then you could pass the bitmapData
:
Intent intent = new Intent(Activity, typeof(UploadActivity));
intent.PutExtra("img", bitmapData);
StartActivity(intent);
show it in new activity :
byte[] bitmapbyte = Intent.GetByteArrayExtra("img");
Bitmap bitmap = BitmapFactory.DecodeByteArray(bitmapbyte, 0, bitmapbyte.Length);
m_imageView.SetImageBitmap(bitmap);
Update:
if you want to use file path,you could do like this:
private Java.IO.File outputImage;
private Android.Net.Uri photoUri; // the camera takes a photo and returns the image path
//Create a file object to store the image after the photo is taken, which is also the photo path after the photo is taken successfully
Java.IO.File outputImage = new Java.IO.File(xxx,xxx);
//determine the current Android version
if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
{
photoUri = FileProvider.GetUriForFile(this, "xxxxx", outputImage);
}
else
{
photoUri = Android.Net.Uri.FromFile(outputImage);
}
Intent intent = new Intent(MediaStore.ActionImageCapture);
intent.PutExtra(MediaStore.ExtraOutput, photoUri);
StartActivityForResult(intent, TAKE_IMAGE_REQUSET);
then you could use photoUri
.
And on some devices you could use below method to save the picture and get the path.
filePath = Android.Net.Uri.Parse(MediaStore.Images.Media.InsertImage(Activity.ContentResolver, mBitMap, null, null));
Note:
FileProvider is used in Android 7.0 and above.
Upvotes: 0