保存图像后由于方向更改导致Android显示图像捕获错误

时间:2013-11-13 09:22:09

标签: android android-camera android-imageview

目前我正在使用某些设备进行图像捕捉。那么现在我正在使用Optimus G和三星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 个答案:

答案 0 :(得分:2)

您的分析是正确的。在某些设备上,特别是RAM较小的设备,摄像头捕获活动(通过意图调用)可能会导致呼叫活动被破坏。因此,onCreate()应该记住这个场景。另请注意,onActivityResult()通常在onResume()之前调用。

很难说更多因为你没有透露onCreate()或TabMainActivity类的其他相关方法的代码。