마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

사진 exif 정보가 불러와지질 않습니다..

0 추천

 try {

            ExifInterface exif = new ExifInterface(filename);

            showExif(exif);

        } catch (IOException e) {

            e.printStackTrace();

            Toast.makeText(this, "Error!", Toast.LENGTH_LONG).show();

        }

제가 구현하려고 하는게 사진의 exif 정보중에 gps정보를 받아서 그걸 구글맵에다가 띄워주는걸 목표로 하고있는데 현재 사진을 클릭하면 exif정보가 떠야하는데 실행시키면 계속 저부분에서 에러가 출력됩니다...

녹두장군님 블로그 보고 따라했는데 되질않아서..질문드립니다

또 질문이 하나 더 있는데 저 경로를 핸드폰 갤러리에 있는 사진으로 하려는데 어떻게 바꾸어야하죠??

출처: http://mainia.tistory.com/1179 [녹두장군 - 상상을 현실로]

 

 

하 너무어렵다 (120 포인트) 님이 2017년 6월 14일 질문

1개의 답변

0 추천
더 자세한 코드와 콜 스택이 없어서 에러를 알 수가 없네요..

예외 콜 스택을 올려주셔야 이걸 보시고, 에러 진단과 해결책을 드릴 수 있습니다.

혹시 모르니, https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html 이것도 참고해 보세요..
mcsong (44,040 포인트) 님이 2017년 6월 15일 답변
package dongyang.ac.exiftest3;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.IOException;

public class MainActivity extends Activity {


    private static final int ID_JPGDIALOG = 0;
    private String exifAttribute;
    private Dialog dlg;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView txtImgName = (TextView) findViewById(R.id.jpgname);
        ImageView jpgView = (ImageView) findViewById(R.id.jpgview);
        jpgView.setOnClickListener(popupDlgOnClickListener);

        Intent intent = getIntent();
        if (intent != null) {
            String path = intent.getStringExtra("totalpath");
            txtImgName.setText(path);

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            Bitmap bm = BitmapFactory.decodeFile(path, options);
            jpgView.setImageBitmap(bm);

            try {
                ExifInterface exif = new ExifInterface(path);
                exifAttribute = getExif(exif);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    View.OnClickListener popupDlgOnClickListener = new View.OnClickListener() {
        public void onClick(View v) {
            createdDialog(ID_JPGDIALOG).show(); // Instead of showDialog(0);
        }
    };

    protected Dialog createdDialog(int id) {
        dlg = null;
        TextView content;

        switch (id) {
            case ID_JPGDIALOG:

                Context mContext = this;
                dlg = new Dialog(mContext);

                dlg.setContentView(R.layout.dialog_select_image_view);
                content = (TextView) dlg.findViewById(R.id.dlgImageName);
                content.setText(exifAttribute);

                Button okDialogButton = (Button) dlg.findViewById(R.id.btnOk);
                okDialogButton.setOnClickListener(okDialogButtonOnClickListener);

                break;
            default:
                break;
        }
        return dlg;
    }

    private Button.OnClickListener okDialogButtonOnClickListener =
            new Button.OnClickListener() {
                public void onClick(View v) {
                    dlg.dismiss();
                }
            };

    private String getExif(ExifInterface exif) {
        String myAttribute = "";
        myAttribute += getTagString(ExifInterface.TAG_DATETIME, exif);
        myAttribute += getTagString(ExifInterface.TAG_FLASH, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LATITUDE, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LATITUDE_REF, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LONGITUDE, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LONGITUDE_REF, exif);
        myAttribute += getTagString(ExifInterface.TAG_IMAGE_LENGTH, exif);
        myAttribute += getTagString(ExifInterface.TAG_IMAGE_WIDTH, exif);
        myAttribute += getTagString(ExifInterface.TAG_MAKE, exif);
        myAttribute += getTagString(ExifInterface.TAG_MODEL, exif);
        myAttribute += getTagString(ExifInterface.TAG_ORIENTATION, exif);
        myAttribute += getTagString(ExifInterface.TAG_WHITE_BALANCE, exif);
        return myAttribute;
    }

    private String getTagString(String tag, ExifInterface exif) {
        return (tag + " : " + exif.getAttribute(tag) + "\n");
    }
}

그럼 혹시 이 코드에선 어떤문제떄문에 중단됐다는게 뜨는거죠?? 컴파일 시킬떄 오류는 하나도없습니다... 다만 어플을 실행할때 중단됨이 떠서 저절로 꺼져요..
지금 올려드린 코드는 파일브라우저를 통해 들어가 사진을 클릭하면 얼럿다이얼로그로 exif정보가 뜨는구조입니다..ㅠ
안드로이드 스튜디오에 Android Monitor에 에러 콜 스택을 보여줄 겁니다. 그걸 첨부해 주세요. ^^
06-15 11:14:24.762 5553-5553/? E/Zygote: v2
06-15 11:14:24.762 5553-5553/? I/libpersona: KNOX_SDCARD checking this for 10246
06-15 11:14:24.762 5553-5553/? I/libpersona: KNOX_SDCARD not a persona
06-15 11:14:24.763 5553-5553/? E/Zygote: accessInfo : 0
06-15 11:14:24.763 5553-5553/? W/SELinux: SELinux selinux_android_compute_policy_index : Policy Index[2],  Con:u:r:zygote:s0 RAM:SEPF_SECMOBILE_7.0_0005, [-1 -1 -1 -1 0 1]
06-15 11:14:24.764 5553-5553/? I/SELinux: SELinux: seapp_context_lookup: seinfo=untrusted, level=s0:c512,c768, pkgname=dongyang.ac.exiftest3
06-15 11:14:24.766 5553-5553/? I/art: Late-enabling -Xcheck:jni
06-15 11:14:24.792 5553-5553/? D/TimaKeyStoreProvider: TimaSignature is unavailable
06-15 11:14:24.793 5553-5553/? D/ActivityThread: Added TimaKeyStore provider
06-15 11:14:24.907 5553-5553/dongyang.ac.exiftest3 W/System: ClassLoader referenced unknown path: /data/app/dongyang.ac.exiftest3-1/lib/arm64
06-15 11:14:24.915 5553-5553/dongyang.ac.exiftest3 D/ContextRelationMgrBrdg: loadKlass() : caller=com.samsung.android.bridge.multiscreen.common.ContextRelationManagerBridge.<clinit>:28 android.app.LoadedApk.makeApplication:840
06-15 11:14:24.922 5553-5553/dongyang.ac.exiftest3 I/InstantRun: starting instant run server: is main process
06-15 11:14:24.960 5553-5553/dongyang.ac.exiftest3 D/AndroidRuntime: Shutting down VM
06-15 11:14:24.961 5553-5553/dongyang.ac.exiftest3 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                     Process: dongyang.ac.exiftest3, PID: 5553
                                                                     java.lang.RuntimeException: Unable to start activity ComponentInfo{dongyang.ac.exiftest3/dongyang.ac.exiftest3.MainActivity}: java.lang.IllegalArgumentException: filename cannot be null
                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2917)
                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2978)
                                                                         at android.app.ActivityThread.-wrap14(ActivityThread.java)
                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1628)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                         at android.os.Looper.loop(Looper.java:154)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6646)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
                                                                      Caused by: java.lang.IllegalArgumentException: filename cannot be null
                                                                         at android.media.ExifInterface.<init>(ExifInterface.java:1099)
                                                                         at dongyang.ac.exiftest3.MainActivity.onCreate(MainActivity.java:45)
                                                                         at android.app.Activity.performCreate(Activity.java:6912)
                                                                         at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2870)
                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2978) 
                                                                         at android.app.ActivityThread.-wrap14(ActivityThread.java) 
                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1628) 
                                                                         at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                         at android.os.Looper.loop(Looper.java:154) 
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6646) 
                                                                         at java.lang.reflect.Method.invoke(Native Method) 
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 



이미지캡처로 보여드리면 편하겠는데 이미지가 댓글로안올라가지네요..ㅠㅠ 이렇게 오류가 뜹니다!
콜스택은 filename 변수가 null이라서 발생한다고 하는데.. 첨부한 코드는 filename이라는 변수가 없네요.. ^^;;
아 정말감사합니다!!!근데 혹시 하나만 더물어봐도 되나요??ㅠㅠ 지금 현재 파일탐색기를 만들어서 넣었는데  핸드폰이랑 연동해서 하는중입니다..원래 제생각에는 핸드폰의 경로들이 떠야하는데 뜨질않네요../storage/emulated/0/DCIM/Camera 이곳에 사진이 저장되어야 하는거아닌가요??? 근데 emulated 부분이 들어가지지않습니다 파일이없는건지 ..권한이없는건지 manifest 에다가                 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
                <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
이 두개를 넣었는데 권한이 없을리는없고..왜 안되는거죠??
퍼미션 관리 방법이 바꿔어서 권한 요청을 하고, 사용자가 권한을 승인하는 구조입니다. 아이폰과 똑같습니다. 아래 링크를 참고하시면 이해하기 쉽습니다.
https://news.realm.io/kr/news/android-marshmellow-permission/

이게 귀찮으신 경우에는 설정 > 앱 > 퍼미션에서 퍼미션을 주면 위 과정은 생략해도 됩니다.

그리고, 이미지등의 파일은 콘텐트 프로바이더를 사용해서 처리하는게 일반적인 방법입니다.
아래에서 확인하실 수 있습니다.

https://developer.android.com/guide/topics/providers/content-provider-basics.html?hl=ko

파일 탐색기를 만드신다고 하시니.. 제가 만든 탐색기도 함 써봐 주세요.. ^^ 별점 주시면 더욱 감사하겠습니다. ^^

https://play.google.com/store/apps/details?id=net.sjava.file
하..제가 학생인데 이렇게 까지 도와드리고 정말감사합니다..ㅠ 근데 제가 잘몰라서 이해가 가질않습니다..우선 제가 구현할 목표는 원래 버튼을누르면 갤러리에서 사진을 가져와 그 안에있는 exif정보들로 gps정보를 받아 구글맵에 띄워주는걸 목표로 하고있습니다...혹시 이부분에대해 좀 쉽게 설명해줄수있나요??? 아니면 잘 설명되어있는곳이 있을까요?? 소스를 보고이해해야하는데 제가 직접 소스를 만들려니 너무 어렵습니다..ㅠ도움 부탁드릴게요..
버튼 눌러서 이미지 가져오는 것은 아래를 참고하시면 됩니다.
https://stackoverflow.com/questions/2507898/how-to-pick-an-image-from-gallery-sd-card-for-my-app

이미지 위치를 가져오면, exif 정보를 읽고..
말씀하신데로 좌표 위치로 구글 맵에 marker로 이 이미지를 띄워주면 될 듯 합니다.
와 덕분에 정말 많은 도움됐습니다!!!!!
package dongyang.ac.picture;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.FileNotFoundException;
import java.io.IOException;

public class MainActivity extends Activity {
    TextView mView;
    final int REQ_CODE_SELECT_IMAGE=100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mView = (TextView) findViewById(R.id.textview);
        Button picture = (Button) findViewById(R.id.Btn_Find);
        picture.setOnClickListener(new View.OnClickListener(){


            public void onClick(View v){  // 클릭하면 ACTION_PICK 연결로 기본 갤러리를 불러옵니다.

                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType(android.provider.MediaStore.Images.Media.CONTENT_TYPE);
                intent.setData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQ_CODE_SELECT_IMAGE);
            }
        });
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Toast.makeText(getBaseContext(), "resultCode : "+resultCode,Toast.LENGTH_SHORT).show();

        if(requestCode == REQ_CODE_SELECT_IMAGE)
        {
            if(resultCode==Activity.RESULT_OK)
            {
                try {
                    //Uri에서 이미지 이름을 얻어온다.
                    String name_Str = getImageNameToUri(data.getData());


                    String filename = Environment.getExternalStorageDirectory()
                            .getPath() + name_Str;
                    try {
                        ExifInterface exif = new ExifInterface(filename);
                        getExif(exif);
                    } catch (IOException e) {
                        e.printStackTrace();
                        Toast.makeText(this, "Error!", Toast.LENGTH_LONG).show();
                    }


                    //이미지 데이터를 비트맵으로 받아온다.
                    Bitmap image_bitmap     = MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData());
                    ImageView image = (ImageView)findViewById(R.id.SelectedImage);

                    //배치해놓은 ImageView에 set
                    image.setImageBitmap(image_bitmap);

                    Toast.makeText(getBaseContext(), "name_Str : "+name_Str , Toast.LENGTH_SHORT).show();

                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

    public String getImageNameToUri(Uri data)
    {
        String[] proj = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(data, proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String imgPath = cursor.getString(column_index);
        String imgName = imgPath.substring(imgPath.lastIndexOf("/")+1);
        return imgName;
    }
    private void getExif(ExifInterface exif) {

        String myAttribute = "[Exif information] \n\n";

        myAttribute += getTagString(ExifInterface.TAG_DATETIME, exif);
        myAttribute += getTagString(ExifInterface.TAG_FLASH, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LATITUDE, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LATITUDE_REF, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LONGITUDE, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LONGITUDE_REF, exif);
        myAttribute += getTagString(ExifInterface.TAG_IMAGE_LENGTH, exif);
        myAttribute += getTagString(ExifInterface.TAG_IMAGE_WIDTH, exif);
        myAttribute += getTagString(ExifInterface.TAG_MAKE, exif);
        myAttribute += getTagString(ExifInterface.TAG_MODEL, exif);
        myAttribute += getTagString(ExifInterface.TAG_ORIENTATION, exif);
        myAttribute += getTagString(ExifInterface.TAG_WHITE_BALANCE, exif);

        mView.setText(myAttribute);

    }

    private String getTagString(String tag, ExifInterface exif) {
        return (tag + " : " + exif.getAttribute(tag) + "\n");
    }

}
현재 여기서 exif정보를 받아와 textview 로 띄어주려고하는데 경로가 오류인지 error라는 토스트가 자꾸뜨네요 경로를 어떻게 바꿔줘야하죠..?
현재 코드짠건 버튼 > 갤러리 > 사진선택 > 메인xml에 imageView 넣어줌
여기까지 진행된건데 여기서 받아온 사진의 exif정보를 메인의 textView로띄어주려고 하는중입니다!!
디버깅하는 방법부터 알아보시는게 빠를겁니다.
어떤부분에서 에러가 나서 Exception 으로 빠지는지 단계별로 확인이 가능하니까요.
사진에 좌표정보가 무조건 있다고 판단해서는 안되며, getExif 처리중 에러가 나는 것 같은데, 소스보단 에러 로그를 보면 어느 부분에서 에러가 나는지를 정확히 집어줍니다. 확인해보세요.
답변 감사드립니다!!
http://mainia.tistory.com/1218
현재 여기있는 코드를 진행중인데
맨밑에 적혀있는 코드 이부분을 어디다가 넣어야 할지 몰라서 계속 오류가납니다..
GeoDegree geoDegree = new GeoDegree(exif);
geoPoint = (TextView) dlg.findViewById(R.id.dlgGeoPoint);
geoPoint.setText(geoDegree.toString());

현재코드는 이렇게 되어있고 이렇게 넣으면 (exif)에 선언되지않았다고 오류가뜹니다
package dongyang.ac.exifview;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.IOException;

public class SelectImageView extends Activity {
    private static final int ID_JPGDIALOG = 0;
    private String exifAttribute;
    private Dialog dlg;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_image_view);
        TextView txtImgName = (TextView) findViewById(R.id.jpgname);
        ImageView jpgView = (ImageView) findViewById(R.id.jpgview);
        jpgView.setOnClickListener(popupDlgOnClickListener);

        Intent intent = getIntent();
        if (intent != null) {
            String path = intent.getStringExtra("totalpath");
            txtImgName.setText(path);

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            Bitmap bm = BitmapFactory.decodeFile(path, options);
            jpgView.setImageBitmap(bm);

            try {
                ExifInterface exif = new ExifInterface(path);
                exifAttribute = getExif(exif);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    View.OnClickListener popupDlgOnClickListener = new View.OnClickListener() {
        public void onClick(View v) {
            createdDialog(ID_JPGDIALOG).show(); // Instead of showDialog(0);
        }
    };

    protected Dialog createdDialog(int id) {
        dlg = null;
        TextView content;
        TextView geoPoint;



        switch (id) {
            case ID_JPGDIALOG:

                Context mContext = this;
                dlg = new Dialog(mContext);
                dlg.setContentView(R.layout.dialog_select_image_view);
                ----------------------------------------------
GeoDegree geoDegree = new GeoDegree(exif);
----------------------------------------
                content = (TextView) dlg.findViewById(R.id.dlgImageName);
                content.setText(exifAttribute);
                ----------------------------------------------------------
geoPoint = (TextView) dlg.findViewById(R.id.dlgGeoPoint);
                geoPoint.setText(geoDegree.toString());
----------------------------------------------------------------------
                Button okDialogButton = (Button) dlg.findViewById(R.id.btnOk);
                okDialogButton.setOnClickListener(okDialogButtonOnClickListener);

                break;
            default:
                break;
        }
        return dlg;
    }

    private Button.OnClickListener okDialogButtonOnClickListener =
            new Button.OnClickListener() {
                public void onClick(View v) {
                    dlg.dismiss();
                }
            };

    private String getExif(ExifInterface exif) {
        String myAttribute = "";
        myAttribute += getTagString(ExifInterface.TAG_DATETIME, exif);
        myAttribute += getTagString(ExifInterface.TAG_FLASH, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LATITUDE, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LATITUDE_REF, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LONGITUDE, exif);
        myAttribute += getTagString(ExifInterface.TAG_GPS_LONGITUDE_REF, exif);
        myAttribute += getTagString(ExifInterface.TAG_IMAGE_LENGTH, exif);
        myAttribute += getTagString(ExifInterface.TAG_IMAGE_WIDTH, exif);
        myAttribute += getTagString(ExifInterface.TAG_MAKE, exif);
        myAttribute += getTagString(ExifInterface.TAG_MODEL, exif);
        myAttribute += getTagString(ExifInterface.TAG_ORIENTATION, exif);
        myAttribute += getTagString(ExifInterface.TAG_WHITE_BALANCE, exif);
        return myAttribute;
    }

    private String getTagString(String tag, ExifInterface exif) {
        return (tag + " : " + exif.getAttribute(tag) + "\n");
    }
}
...