I am working on an Android app where part of the functionality is that the user can select an image from their device, associate it with a specific item from a list, and use it in the app. My intention was to store the image itself in internal memory and the path to the image in a SQLite database with the rest of the stored information for the item.
I have been able to get the user to select and image and upload it, but the image is sometimes rotated depending on how the picture was taken. I've tried looking at the Exif data, but the orientation is always zero. I've tried using a cursor for the MediaStore.Images.Media.DATA
information, but also to no avail. The current state of the relevant code is as follows:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
mDbHelper = new EntryDbHelper(this);
Intent intent = getIntent();
pId = intent.getIntExtra(PhrasesActivity.T_KEY, -1);
mImageView = (ImageView) findViewById(R.id.details_img);
mImageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//Making an intent to Pick an image, looking for an Internal URI
Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
//Setting the content to images
pickImageIntent.setType("image/*");
if(pickImageIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(pickImageIntent, REQUEST_IMAGE_GET);
}
return true;
}
});
setText();
setImage();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
Bitmap image = null;
Uri imageUri = data.getData();
try {
image = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
mImageView.setImageBitmap(image);
String path = storeImage(image);
SQLiteDatabase db = mDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(PhraseEntry.COLUMN_URI, path.toString());
String selection = PhraseEntry._ID + " = ?";
String[] selectionArgs = {Integer.toString(pId)};
int count = db.update(PhraseEntry.TABLE_NAME, values, selection, selectionArgs);
if(count == 1) {
Toast.makeText(this, "Image Updated Successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Image Updated UNSUCCESSFULLY", Toast.LENGTH_SHORT).show();
}
}
}
private void setImage() {
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = {
PhraseEntry.COLUMN_URI
};
String selection = PhraseEntry._ID + " = ?";
String[] selectionArgs = {Integer.toString(pId)};
Cursor cursor = db.query(PhraseEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, null);
String imagePath = "";
while(cursor.moveToNext()) {
imagePath = cursor.getString(
cursor.getColumnIndexOrThrow(PhraseEntry.COLUMN_URI)
);
}
if(!imagePath.isEmpty()) {
try {
File f = new File(imagePath, "phrase_" + Integer.toString(pId));
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
mImageView.setImageBitmap(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
else {
mImageView.setImageResource(R.drawable.sample);
}
cursor.close();
}
Here is the relevant layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.bladefrisch.discoveringtalk.DetailsActivity">
<ImageView
android:id="@+id/details_img"
style="@style/DetailImage"
android:contentDescription="Sample"
android:src="@drawable/sample" />
<TextView
android:id="@+id/details_text"
style="@style/DetailText"
tools:text="Hello, how are you?" />
</LinearLayout>
This allows the user to select an image, upload it to the image view (sometimes rotated), store the image, and retrieve the image after shutting down the app. The rotation is the only major issue, and the fixes I have tried are not reflected here. I have follow too many answers here to cite, but they fall into three major categories: checking Exif tags and rotating the Bitmap with a matrix, using a cursor to get the image information and rotating, and using Glide. All three failed, and I am at a loss for what to do next. Any suggestions?
The complete code can be found here.
UPDATE
As requested, I've added the Exif checking code to no avail. As mentioned before, the orientation is always zero, so I get a null bitmap based on the code in the link.
I do not know what saveImage()
does. Given that it takes in a Bitmap
and returns a "path", I assume that it is saving that Bitmap
to a file. If so, that will certainly not work, as a Bitmap
does not have EXIF data.
Use the support library's edition of ExifInterface
to read in the EXIF tags from the original content. Use getContentResolver().openInputStream(imageUri)
to get an InputStream
, passing that to the ExifInterface
constructor.