I'm working on an app that take picture by calling the Camera Intent. In the next Activity I use the URI of the image that I got and display the image. It works fine.
The problem is when I test in Sony Neo V device (ICS), the image get rotated 90 degrees (this is the screenshot). It doesn't happen when I test in HTC Desire device (Gingerbread) (this is the screenshot).
Here is my code:
Activity 1:
private final int CAMERA_REQUESTCODE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.memberform);
Button photo = (Button) findViewById(R.id.btn_photo);
photo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUESTCODE);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ( requestCode==CAMERA_REQUESTCODE ) {
if ( resultCode==RESULT_OK ) {
GlobalVar.member.setPhotoUri(data.getData());
} else if ( resultCode==RESULT_CANCELED ) {
} else {
Toast.makeText(this, "Unknown onActivityResult resultCode = " + resultCode, Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Unknown onActivityResult requestCode = " + requestCode, Toast.LENGTH_SHORT).show();
}
}
Activity 2:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.memberdetail);
ImageView photo = (ImageView) findViewById(R.id.photo);
photo.setImageURI( GlobalVar.member.getPhotoUri() );
}
I've tried to detect if ( ImageView.getWidth()>ImageView.getHeight() ) then rotate90degrees(); but it doesn't work. And I'm hoping there's a general working code (works on any device) that solve this problem because it would be better than making a conditional if.
Any help & explanation would be appreciated. General working code would be greatly appreciated.
Many thanks
There seems to be a bug with other devices as well, not sure if all Samsung devices do it, but quite a few are doing it. I can confirm on my device Samsung infuse.
You may have to query the ContentResolver to get the orientation for each image and see if it needs rotating.
Related
public class MainActivity extends Activity implements PermissionRequest.Response{
public static int CAMERA_PREVIEW_RESULT = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new CameraPreviewIntent(this)
.setExportDir(CameraPreviewIntent.Directory.DCIM, "ImgLyExample")
.setExportPrefix("example_")
.setEditorIntent(
new PhotoEditorIntent(this)
.setExportDir(PhotoEditorIntent.Directory.DCIM, "ImgLyExample")
.setExportPrefix("result_")
.destroySourceAfterSave(true)
)
.startActivityForResult(CAMERA_PREVIEW_RESULT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, android.content.Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == CAMERA_PREVIEW_RESULT) {
String path = data.getStringExtra(CameraPreviewActivity.RESULT_IMAGE_PATH);
Toast.makeText(this, "Image Save on: " + path, Toast.LENGTH_LONG).show();
}
}
Hello
I want to edit the above code so that in the result the activity displays the result image along with the file path, can someone please help with this as I am very new to android development.
The github link to this sdk is-
https://github.com/imgly/imgly-sdk-android-demo
v1 of the SDK is deprecated, please use v2 instead. Please see the documentation how to integrate the newest version.
https://github.com/imgly/imgly-sdk-android-demo
Else I'am not sure what you actually want.
Can you please explain, how your app need to perform?
I am making a activity whereby i ask the user to load image from various sources and showing the selected image on a imageview in a different activity.
I am able to show the image from the camera and gallery but from dropbox it is showing error.
For Camera and gallery i can even query the uri obtained from
intent.getData()
in the onactivityresult method and obtain the Filepath and accordingly even obtain the bitmap and resize it .
But the same is not working for Dropbox. Kindly update what code to use for Dropbox so that all options start working.
thanks
For Dropbox you will need to use their Android Chooser to choose files from the user's Dropbox account. You will need a Dropbox API key for this. Once you have grabbed the chooser library and your API key it should be fairly easy to implement;
private Button mChooserButton;
private DbxChooser mChooser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mChooser = new DbxChooser(APP_KEY);
mChooserButton = (Button) findViewById(R.id.chooser_button);
mChooserButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mChooser.forResultType(DbxChooser.ResultType.PREVIEW_LINK)
.launch(MainActivity.this, DBX_CHOOSER_REQUEST);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == DBX_CHOOSER_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
DbxChooser.Result result = new DbxChooser.Result(data);
Log.d("main", "Link to selected file: " + result.getLink());
// Handle the result
} else {
// Failed or was cancelled by the user.
}
} else if (requestCode == GALLERY) {
// If your request was from the user gallery
Log.d("main", "Link to selected file: " + data.getData());
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
I call camera to take a picture. But I cannot go back to my own original activity after taking the picture. What's the problem? Thank you.
public void addEntry(View view)
{
String EntryName=RegisterName.toString();
Toast.makeText(this, EntryName, Toast.LENGTH_LONG);
Intent addEntryintent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(getFilesDir(),EntryName);
registeryFileUri = Uri.fromFile(file);
addEntryintent.putExtra(MediaStore.EXTRA_OUTPUT, registeryFileUri);
startActivityForResult(addEntryintent,TAKE_PICTURE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE)
{
if (data != null)
{
Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG);
ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture);
Registerimage.setImageURI(registeryFileUri);
}
}
}
It took me a while to get it working and I have made several things and finally it works. I can't tell certainly which of the things I did is the solution to the problem, but they all together form the working solution.
There are multiple reasons why the camera activity does not return back. Two major ones are:
path for the new picture is invalid, or non-existing, or it can't be created
application got suspended and saved path get lost.
So here is my code solving all these problems, all together working.
First I created helper class ImageServices:
class ImageServices {
private static String getTempDirectoryPath(Context ctx) {
File cache;
// SD Card Mounted
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
cache = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Android/data/" + ctx.getPackageName() + "/cache/");
}
// Use internal storage
else {
cache = ctx.getCacheDir();
}
// Create the cache directory if it doesn't exist
if (!cache.exists()) {
cache.mkdirs();
}
return cache.getAbsolutePath();
}
public static Uri getOutputImageFileUri(Context ctx) {
// TODO: check the presence of SDCard
String tstamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File file = new File(getTempDirectoryPath(ctx), "IMG_" + tstamp + ".jpg");
return Uri.fromFile(file);
}
}
The code is partially inspired by developer.android.com and partially by CameraLauncher class of Apache Cordova project.
In my activity the event handler for button to take a picture looks like this:
private Uri imageFileUri;
private static final int MAKE_PHOTO_RESULT_CODE = 100;
private static final int PICK_PHOTO_RESULT_CODE = 101;
public void onMakePhoto(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageFileUri = ImageServices.getOutputImageFileUri(this);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
Log.i("babies", "Taking picture: requested " + imageFileUri);
startActivityForResult(intent, MAKE_PHOTO_RESULT_CODE);
}
Method onActivityResult does not really contain much, as imageFileUri already points to the existing file and necessary rendering is done in onResume method, which is called when the activity gets back into foreground:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch(requestCode) {
case MAKE_PHOTO_RESULT_CODE:
assert imageFileUri != null;
break;
case ...
...other cases...
break;
}
}
}
But this is still not sufficient, as imageFileUri gets lost as your app gets suspended. And on regular device the chances are close to 100%. So next you need to store the value of imageFileUri to instance state:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (imageFileUri == null) {
outState.putString("file-uri", "");
}
else {
outState.putString("file-uri", imageFileUri.toString());
}
};
and load it again in - easiest is directly in onCreate:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (savedInstanceState != null) {
String fileUri = savedInstanceState.getString("file-uri");
if (!fileUri.equals("")) imageFileUri = Uri.parse(fileUri);
}
}
So, again, on top of many other solutions presented on this site as well as elsewhere, there are two major differences:
smarter getTempDirectoryPath inspired by Apache Cordova
allowing imageFileUri to survive suspended application
And now - at least for me - everything works fine.
Answer
Use appContext.getExternalCacheDir() and don't forget to mention permissons.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE)
{
if(resultCode==Activity.RESULT_OK)
{ //if (data != null)
//{
Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG);
ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture);
Registerimage.setImageURI(registeryFileUri);
//}
}
else
Toast.makeText(this, "Not Registered!", Toast.LENGTH_LONG);
}
**"android.permission.CAMERA"**
Check whether the above permission is specified in your manifest or not
Note: It's better to use getExternalCacheDir() than getFilesDir() if you still dont get the
image then use that. Dont forgot to specify the permission "android.permission.WRITE_EXTERNAL_STORAGE" if you use the getExternalCacheDir().
On some devices data will unfortunately be null in onActivityResult after calling the camera activity. So you may need to save your state in your activity's variables, and them read them in onActivityResult. Be sure to save these variables in onSaveInstanceState and restore them in onCreate.
I am making a program that takes a picture and then shows it's thumbnail.
When using the emulator all goes well and the discard button deletes the photo.
But on a real device the camera intent saves the image at the imageUri variable and a second one that is named like if I had just opened up the camera and took a picture by itself.
private static final int CAMERA_PIC_REQUEST = 1337;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
//start camera
values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION,"From your Camera");
imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
image = (ImageView) findViewById(R.id.ImageView01);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
//save the image buttons
Button save = (Button) findViewById(R.id.Button01);
Button close = (Button) findViewById(R.id.Button02);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
try{
thumbnail = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
image.setImageBitmap(thumbnail);
}
catch(Exception e){
e.printStackTrace();
}
}
else{
finish();
}
}
public void myClickHandler(View view) {
switch (view.getId()) {
case R.id.Button01:
finish();
break;
case R.id.Button02:
dicard();
}
}
private void dicard(){
getContentResolver().delete(imageUri, null, null);
finish();
}
Some Android phones store the original photo in the gallery, and a thumbnail only in your location. It doesn't matter what you did with the original request. I have two different HTC phones doing it, and a slew of other brands not doing it.
I solved this another way. I ran a query of every item in the gallery and loaded the BucketIDs to an array. I do this when my app starts the camera app. When the camera app returns, I make the same query (with items recently added to save time). I compare this to my original list and find the new BucketID. Next, I compare the size of this image with the file I explicitly set as the output. If it's bigger, I copy it, replacing what I had. Then I delete the file and remove it from the gallery.
Pain in the you-know-what!
[EDIT] I had to change this around again when I discovered a phone that didn't keep unique bucket IDs... See my post in the link following this answer for more.
I am using following code to open Android Contacts
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnContacts = (Button) findViewById(R.id.btn_contacts);
txtContacts = (TextView) findViewById(R.id.txt_contacts);
btnContacts.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
txtContacts.setText("");
Intent intent = new Intent(Intent.ACTION_PICK, People.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
});
}
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (PICK_CONTACT):
if (resultCode == Activity.RESULT_OK) {
//display picked contact data.
}
}
}
Now I want to put Button at the top of this Contact activity when opened or add my own Menu in this Activity
Can any one guide me? Is this possible or not? If yes then please tell how to achieve this?
I don't believe that is possible as each Activity in Android is working on its own and by starting the Intent, you are basically giving the new Activity the focus (and control).
One way to do something like this would be to build a custom contact list activity that uses the public data providers to access the contacts and simply lists them then. Then you could add as many custom functions as you like or even add Intents for original actions (like viewing a contact's details).