Ошибка захвата изображения на экране Android из-за изменения ориентации после сохранения изображения

В настоящее время я работаю с захватом изображения с использованием некоторых устройств. Что ж, теперь я тестирую его, используя вкладку Optimus G и Samsung Galaxy, чтобы быть конкретным на устройстве. Теперь мне уже удалось захватить изображение, сохранить его, а затем просмотреть его в ImageView. В любом случае, это работает просто отлично, но всякий раз, когда я пытался захватить изображение в портретном режиме, затем сохранить его в альбомном режиме, намерение затем быстро меняет компоновку с альбомного на портретное, затем альбомное, затем возвращается к моему приложению в портретном, но затем приложение перестает работать. Я не знаю, почему это происходит, и я не могу получить журналы с телефона, так как у меня нет драйверов для запуска adb logcat. Это происходит чаще всего на устройстве Optimus G в любом случае. Хотя, если я снимаю его на ландшафте, то сохраняю на ландшафте, он работает просто отлично. очень странно.

Что касается моего кода для захвата, вот он:

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();
        }
    }

Хорошо, я пытался использовать режим принудительного портрета, но ничего не происходит.

и вот на моем 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();
                }


            }
        }

и вот исправления для захваченного изображения, которое я добавил:

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);
    }

Надеюсь, кто-то может мне помочь, почему эта проблема происходит.

ОБНОВЛЕНИЕ:

Я получил журналы сейчас и вот ошибка, которую я получил:

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

Хорошо, что я вижу здесь, приложение возвращается к созданию действия после намерения камеры. поскольку часть метода getList была запущена только onCreate. Это становится странным для меня.

Добавлено:

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;
    }

}

1 ответ

Решение

Ваш анализ верен. На некоторых устройствах, особенно с меньшей оперативной памятью, захват камеры (вызывается с помощью намерения) может привести к разрушению вызывающего действия. Поэтому onCreate() должен быть написан с учетом этого сценария. Также обратите внимание, что onActivityResult() обычно вызывается перед onResume().

Трудно сказать больше, потому что вы не раскрыли код onCreate() или других соответствующих методов вашего класса TabMainActivity.

Другие вопросы по тегам