Reputation: 4371
currently I'm working with the image capture using some devices. Well now I'm testing it using an Optimus G and Samsung Galaxy tab to be specific on the device. Now I already managed to capture an image, save it then preview it on an ImageView. It works just fine anyways but whenever I tried to capture an image on portrait mode then save it in landscape mode the intent then changes layout fast from landscape to portrait then landscape then goes back to my app in portrait but the app then stops working. I don't know why does this happen and I can't get the logs from the phone since I don't have the drivers to run the adb logcat. This happens most on the optimus G device anyways. Though if I capture it on landscape then save it on landscape it works just fine. really weird.
As for my code for capture here it is:
public void captureImage() {
try {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getActivity().startActivityForResult(cameraIntent, capture_image);
} catch (Exception e){
e.printStackTrace();
Toast.makeText(getActivity(),"Something went wrong",Toast.LENGTH_SHORT).show();
}
}
Okay I tried to use force portrait mode but nothing happens.
and here's on my onActivityResult:
if(requestCode == capture_image){
if(resultCode == Activity.RESULT_OK){
//Get the path of the captured image
Uri image_uri = data.getData();
String path = getPath(image_uri);
//send path to FragmentCamera
FragmentCamera.file_path = path;
//create thumbnail for display
File file = new File(FragmentCamera.file_path );
try {
Bitmap thumbnail;
thumbnail = applyOrientation(decodeSampledBitmapFromFile(file.getAbsolutePath(), 500, 250), resolveBitmapOrientation(file));
FragmentCamera.thumb_receipt.setImageBitmap(thumbnail);
} catch (IOException e) {
e.printStackTrace();
}
}
}
and here's the fixers for the image captured I added:
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { // BEST QUALITY MATCH
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight) {
inSampleSize = Math.round((float)height / (float)reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth) {
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float)width / (float)reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
private int resolveBitmapOrientation(File bitmapFile) throws IOException {
ExifInterface exif = null;
exif = new ExifInterface(bitmapFile.getAbsolutePath());
return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}
private Bitmap applyOrientation(Bitmap bitmap, int orientation) {
int rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
default:
return bitmap;
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
Hope someone can help me why does this problem happens.
UPDATES:
I got the logs now and here's the error I got:
E/WindowManager: Activity com.mark.exercise.TabMainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@42cdfff0 that was originally added here
android.view.WindowLeaked: Activity com.mark.exercise.TabMainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@42cdfff0 that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:378)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:324)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:256)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:153)
at android.view.Window$LocalWindowManager.addView(Window.java:547)
at android.app.Dialog.show(Dialog.java:282)
at com.mark.exercise.TabMainActivity$GetListTask.onPreExecute(TabMainActivity.java:372)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
at android.os.AsyncTask.execute(AsyncTask.java:534)
at com.mark.exercise.TabMainActivity.getShoppingList(TabMainActivity.java:330)
at com.mark.exercise.TabMainActivity.onCreate(TabMainActivity.java:78)
at android.app.Activity.performCreate(Activity.java:5236)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1082)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2037)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2098)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3576)
at android.app.ActivityThread.access$700(ActivityThread.java:138)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4911)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
11-13 17:55:34.228 747-747/? D/StatusBar.NetworkController: refreshViews connected={ wifi } level=5 combinedSignalIconId=0x7f02039b/com.android.systemui:drawable/stat_sys_wifi_signal_3_fully combinedActivityIconId=0x7f020393 mobileLabel=Globe wifiLabel=WiFixxxxXXXXxxxxXXXX emergencyOnly=false combinedLabel=WiFixxxxXXXXxxxxXXXX mAirplaneMode=false mDataActivity=0 mPhoneSignalIconId=0x7f020366 mDataDirectionIconId=0x0 mDataSignalIconId=0x7f020366 mDataTypeIconId=0x0 mNoSimIconId=0x0 mThirdTypeIconId=0x0 mWifiIconId=0x7f02039b mBluetoothTetherIconId=0x108054f
11-13 17:55:34.418 12444-12444/? E/CameraApp: [SoundController.java:483:onDestroy()] onDestroy-start, sound_pool release 1/2
11-13 17:55:34.428 12444-12444/? E/CameraApp: [SoundController.java:525:onDestroy()] onDestroy-end, sound_pool release 2/2
11-13 17:55:34.628 13627-13627/com.mark.exercise E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalArgumentException: View not attached to window manager
at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:685)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:381)
at android.view.WindowManagerImpl$CompatModeWrapper.removeView(WindowManagerImpl.java:164)
at android.app.Dialog.dismissDialog(Dialog.java:347)
at android.app.Dialog.dismiss(Dialog.java:330)
at com.mark.exercise.TabMainActivity$GetListTask.onPostExecute(TabMainActivity.java:379)
at com.mark.exercise.TabMainActivity$GetListTask.onPostExecute(TabMainActivity.java:337)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4911)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
11-13 17:55:34.628 536-547/? W/ActivityManager: Force finishing activity com.mark.exercise/.TabMainActivity
11-13 17:55:35.159 536-550/? W/ActivityManager: Activity pause timeout for ActivityRecord{42b81c88 com.mark.exercise/.TabMainActivity}
11-13 17:55:35.349 1298-1342/? E/ThermalDaemon: [GPU_MON] 0 percent. Current Sampling Time is 4 sec
Okay for what I see in here, the app goes back in creating the activity after the camera intent. since the part of the getList method was only fired onCreate. This is getting weird for me.
Added:
TabMainActivity.java
public class TabMainActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
ArrayList<String> ids = new ArrayList<String>();
private Map hash_values = new HashMap();
String uid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bottom_tabs);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("uid",getIntent().getStringExtra("user_id"));
editor.commit();
uid = getIntent().getStringExtra("user_id");
getShoppingList(uid);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
Bundle b = new Bundle();
b.putString("0", "Me");
mTabHost.addTab(mTabHost.newTabSpec("me").setIndicator(null,getResources().getDrawable(R.drawable.selector_me)),
FragmentMe.class, b);
b = new Bundle();
b.putString("1", "Social");
mTabHost.addTab(mTabHost.newTabSpec("social").setIndicator(null, getResources().getDrawable(R.drawable.selector_social)),
FragmentSocial.class, b);
b.putString("2", "Promo");
mTabHost.addTab(mTabHost.newTabSpec("promo").setIndicator(null,getResources().getDrawable(R.drawable.selector_promo)),
FragmentPromo.class, b);
b = new Bundle();
b.putString("3", "Camera");
mTabHost.addTab(mTabHost.newTabSpec("camera").setIndicator(null,getResources().getDrawable(R.drawable.selector_capture)),
FragmentCamera.class, b);
b.putString("4", "List");
mTabHost.addTab(mTabHost.newTabSpec("shopping_list").setIndicator(null,getResources().getDrawable(R.drawable.selector_shopping_list)),
FragmentViewPager.class, b);
}
private static final int capture_image = 1;
private static final int select_image = 2;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == capture_image){
if(resultCode == Activity.RESULT_OK){
//Get the path of the captured image
Uri image_uri = data.getData();
String path = getPath(image_uri);
//send path to FragmentCamera
FragmentCamera.file_path = path;
//create thumbnail for display
File file = new File(FragmentCamera.file_path );
try {
Bitmap thumbnail;
thumbnail = applyOrientation(decodeSampledBitmapFromFile(file.getAbsolutePath(), 500, 250), resolveBitmapOrientation(file));
FragmentCamera.thumb_receipt.setImageBitmap(thumbnail);
} catch (IOException e) {
e.printStackTrace();
}
}
}
if(requestCode == select_image){
if(resultCode == Activity.RESULT_OK){
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
//Get the path of the selected image
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String path = cursor.getString(columnIndex);
cursor.close();
//send path to FragmentCamera
FragmentCamera.file_path = path;
//create thumbnail for display
FragmentCamera.file_path = path;
//create thumbnail for display
File file = new File(FragmentCamera.file_path );
try {
Bitmap thumbnail;
thumbnail = applyOrientation(decodeSampledBitmapFromFile(file.getAbsolutePath(), 500, 250), resolveBitmapOrientation(file));
FragmentCamera.thumb_receipt.setImageBitmap(thumbnail);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public String getPath(Uri uri) {
Cursor cursor = null;
int column_index = 0;
try {
String[] projection = { MediaStore.Images.Media.DATA };
cursor = getContentResolver().query(uri, projection, null, null, null);
column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
} catch (Exception e) {
Log.d("Error", "Exception Occured", e);
}
return cursor.getString(column_index);
}
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { // BEST QUALITY MATCH
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight) {
inSampleSize = Math.round((float)height / (float)reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth) {
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float)width / (float)reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
private int resolveBitmapOrientation(File bitmapFile) throws IOException {
ExifInterface exif = null;
exif = new ExifInterface(bitmapFile.getAbsolutePath());
return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}
private Bitmap applyOrientation(Bitmap bitmap, int orientation) {
int rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
default:
return bitmap;
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
private Bitmap createThumbnail(String image_path){
Bitmap thumb=null;
Bitmap get_image = BitmapFactory.decodeFile(image_path);
int h = 500;
int w = 500;
thumb = Bitmap.createScaledBitmap(get_image,h, w, true);
return thumb;
}
public void getShoppingList(String user_id){
try{
HashMap params = new HashMap<String,String>();
params.put("uid", user_id);
params.put("url", "http://ec2-54-254-129-196.ap-southeast-1.compute.amazonaws.com/get_shoplist.php");
//pass parameters
hash_values.putAll(params);
//start async task
new GetListTask().execute(hash_values);
}catch (Exception e){
e.printStackTrace();
Toast.makeText(getBaseContext(), "Something went wrong", Toast.LENGTH_SHORT).show();
}
}
public class GetListTask extends AsyncTask<Map, Integer, Void> {
ProgressDialog progressDialog;
String json_response = null;
@Override
protected Void doInBackground(Map... maps) {
json_response = getShoppingListResponse(maps[0]);
int i = 0;
while (i <= 10) {
try {
Thread.sleep(50);
publishProgress(i);
i++;
}
catch (Exception e) {
Log.i("The progress", e.getMessage());
}
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
progressDialog.setProgress(progress[0]*10);
}
@Override
protected void onPreExecute() {
/*Do something before the async task starts*/
progressDialog = new ProgressDialog(TabMainActivity.this);
progressDialog.setMessage("Getting your shopping list");
progressDialog.setIndeterminate(false);
progressDialog.setMax(100);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.show();
//progressDialog = ProgressDialog.show(getActivity(), "Loading", "Getting the updated list, please wait a moment");
}
protected void onPostExecute(Void v) {
setJSONtoList(json_response);
progressDialog.dismiss();
}
}
private void setJSONtoList(String response){
try{
JSONArray jArray = new JSONArray(response);
JSONObject json_data=null;
for(int i=0;i<jArray.length();i++){
json_data = jArray.getJSONObject(i);
DatabasePrefs dbPref = new DatabasePrefs(getBaseContext());
dbPref.insertShoppingList(Integer.parseInt(json_data.getString("idlist")),Integer.parseInt(uid),json_data.getString("list_name"));
//TODO check
ids.add(json_data.getString("idlist"));
}
}catch(JSONException e){
Log.v("Problem", "Error parsing data " + e.toString());
}
new getListThread().execute();
}
int ctr = 0;
public class getListThread extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
try{
getListContent(ids.get(ctr));
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void v) {
ctr++;
if(ctr < ids.size()){
new getListThread().execute();
}
}
}
public void getListContent(String id){
try{
HashMap params = new HashMap<String,String>();
params.put("idlist", id);
params.put("url", "http://ec2-54-254-129-196.ap-southeast-1.compute.amazonaws.com/get_list_items.php");
//pass parameters
hash_values.putAll(params);
//start async task
new CreateNewList().execute(hash_values);
}catch (Exception e){
e.printStackTrace();
Toast.makeText(TabMainActivity.this, "Something went wrong", Toast.LENGTH_SHORT).show();
}
}
public class CreateNewList extends AsyncTask<Map, Void, Void> {
FragmentShoppingList fsl = new FragmentShoppingList();
String response;
@Override
protected Void doInBackground(Map... maps) {
//reused method
response = fsl.getShoppingListResponse(maps[0]);
return null;
}
protected void onPostExecute(Void v) {
setJSONtoListItems(response);
Log.v("The id of the list", response);
}
}
private void setJSONtoListItems(String response){
try{
JSONArray jArray = new JSONArray(response);
JSONObject json_data=null;
for(int i=0;i<jArray.length();i++){
json_data = jArray.getJSONObject(i);
String id = json_data.getString("id_list_content");
String list_id = json_data.getString("idlist");
String item_id = json_data.getString("iditem");
String item_name = json_data.getString("name");
String item_price = json_data.getString("price");
String was_price = json_data.getString("was_price");
DatabasePrefs db = new DatabasePrefs(TabMainActivity.this);
db.insertItem(Long.parseLong(id), Integer.parseInt(list_id), Integer.parseInt(item_id), item_name, item_price, was_price);
Log.v("The result",id+","+list_id+","+item_id+","+item_name+","+item_price+","+was_price);
}
}catch(JSONException e){
Log.v("Problem", "Error parsing data " + e.toString());
}
}
public String getShoppingListResponse(Map hash_values){
String response = "";
InputStream is = null;
StringBuilder string_builder = null;
String url = hash_values.get("url").toString().replace(" ", "%20"); //get the URL replacing the space with %20
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
/*This will convert the hashMap sent into individual part per key per value*/
Set set = hash_values.entrySet();
Iterator iterator = set.iterator();
/*do a loop passing all the data on a string*/
while(iterator.hasNext()) {
Map.Entry mapEntry = (Map.Entry)iterator.next();
String keyword = String.valueOf(mapEntry.getKey());
String value = String.valueOf(mapEntry.getValue());
/*this will check if the passed data is a URL, file or a simple value*/
if(!keyword.equals("url")){
if(value.matches("(.*)/(.*)")){
File file = new File(value);
Log.v("Does this exists?", String.valueOf(file.exists()));
if(file.exists()){
FileBody upload_file;
upload_file = new FileBody(file);
/*not url but file*/
mpEntity.addPart(keyword, upload_file);
}else{
/*not url and not file*/
mpEntity.addPart(keyword, new StringBody(value));
}
}else{
/*not URL and not file*/
mpEntity.addPart(keyword, new StringBody(value));
}
}
}
post.setEntity(mpEntity);
HttpResponse http_res = client.execute(post);
HttpEntity resEntity = http_res.getEntity();
is = resEntity.getContent();
} catch (Exception e) {
e.printStackTrace();
response = "";
}
/*convert JSON to string*/
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
string_builder = new StringBuilder();
String line = "0";
while ((line = reader.readLine()) != null) {
string_builder.append(line + "\n");
}
is.close();
response = string_builder.toString();
}catch(Exception e){
e.printStackTrace();
}
return response;
}
}
Upvotes: 0
Views: 1777
Reputation: 57173
Your analysis is correct. On some devices, especially with smaller RAM, camera capture activity (invoked via intent) may cause the calling activity to be destroyed. Threfore, onCreate() should be written with this scenario in mind. Note also that onActivityResult() is usually called before onResume().
It's hard to tell more becaise you have not disclosed the code for onCreate() or other relevant methods of your TabMainActivity class.
Upvotes: 2