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

안드로이드 카메라 문제

0 추천

 

public class MainActivity extends AppCompatActivity {

 

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

        button = (Button)findViewById(R.id.button);
        button2 = (Button)findViewById(R.id.button2);
        imageView = (ImageView)findViewById(R.id.imageView);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Camera();
            }
        });
    }


    public void Camera()
    {
        String state = Environment.getExternalStorageState();

        if(Environment.MEDIA_MOUNTED.equals(state))
        {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

            if(intent.resolveActivity(getPackageManager()) != null)
            {
                File photoFile = null;

                try
                {
                    photoFile = createImageFile();
                }
                catch(IOException e)
                {
                    Toast.makeText(this, "Camera Error", Toast.LENGTH_SHORT).show();
                }

                if(photoFile != null)
                {
                    Uri providerUri = FileProvider.getUriForFile(this, getPackageName()+".fileprovider", photoFile);
                    imageUri = providerUri;

                    intent.putExtra(MediaStore.EXTRA_OUTPUT, providerUri);

                    startActivityForResult(intent, REQUEST_CAMERA);
                }
            }
            else
            {
                Toast.makeText(this, "None createImageFile", Toast.LENGTH_SHORT).show();
            }
        }
        else
        {
            Toast.makeText(this, "저장 공간 접근 불가", Toast.LENGTH_SHORT).show();
            return;
        }


    }

    private File createImageFile() throws IOException
    {

        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        imageFileName = timeStamp + ".jpg";

        imageFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/image/"+imageFileName);


        if(!imageFile.exists())
        {
            imageFile.getParentFile().mkdirs();
            imageFile.createNewFile();
        }

        mCurrentPhotoPath = imageFile.getAbsolutePath(); <- 여기에서는 파일 경로가 잘지정되어 확인가능한데요

        return imageFile;
    }

    private void galleryAddPic()
    {
        Log.i("gelleyAddPic", "Start");

        Log.i("mCurrentPhotoPath", mCurrentPhotoPath);
        Toast.makeText(this, mCurrentPhotoPath, Toast.LENGTH_SHORT).show();

        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

        File file = new File(mCurrentPhotoPath); <-- 여기로 넘어와서 확인해보면 null 값이 들어와있어요
        contentUri = Uri.fromFile(file);
        intent.setData(contentUri);

    
        bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        imageView.setImageBitmap(bitmap);

        sendBroadcast(intent);

        Toast.makeText(this, "사진 저장 완료", Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

      switch(requestCode)
      {
          case REQUEST_CAMERA :


                 try
                 {
                     galleryAddPic();
                 }
                 catch(Exception e)
                 {
                     e.printStackTrace();
                     Toast.makeText(this, "Camera Error2", Toast.LENGTH_SHORT).show();
                 }

                 break;
    }
}

 

createImageFile 메소드를 벗어나면 mCurrentPhotoPath 변수가 null값이 되어버립니다;;

근데 더 웃긴건 위 소스로도 어쩔때는 정상적으로 실행이 되다가 갑자기 안된다는 점입니다;;

갤럭시 s4로 테스트 했고, AVD로 이용시에는 정상적으로 실행됩니다;; 도데체 왜 됬다가 안됬다가 하는 건지 이유를 모르겠습니다. 답변 부탁드려요 ㅠㅠ

알파고 (4,320 포인트) 님이 2017년 9월 4일 질문
알파고님이 2017년 9월 4일 수정

2개의 답변

+1 추천
 
채택된 답변

startActivityForResult() 로 카메라 구동시 시스템에 의해 기존앱이 정리될 수 있습니다.

시스템이 앱을 내리기 전에 호출하는 onSaveInstaceState() 에서 mCurrentPhotoPath  변수값을 저장해놓은 뒤 onCreate() 에서 인자로 넘어온 savedInstanceState가 null 이 아닐 경우 해당 값을 읽어서 mCurrentPhotoPath  에 다시 셋팅하시면 됩니다.

바램 (19,650 포인트) 님이 2017년 9월 5일 답변
알파고님이 2017년 9월 5일 채택됨
mCurrentPhotoPath가 멤버변수로 선언되었는데 그래도 해당되는 사항인가요??
그리고 될 때가 있다는건 정상적이라는 건데, 반대로 안될때도 있다는게; 이해가 안되요 왜 그런지
아 이제 해결했습니다 감사합니다.
댓글을 이제야 봤습니다.
해결되셨다니 다행이고 약간의 추가를 하자면...
시스템은 메모리가 부족할 경우 가장 앞의 앱이 아니면 정리를 할 수 있습니다.
즉,  A라는 앱이 실행도중 B라는 어플을 호출할 경우 시스템이 A라는 어플이 뒤로 들어갔으므로 메모리 상태에 따라 정리할 수도 있고, 안할 수도 있습니다.
정리가 안되면 변수의 값이 그대로 유지되지만,
정리가 될 경우에는 앱이 재시작하는 것이라 변수의 값이 초기화됩니다.
답변 정말 감사드립니다!!
+1 추천
OnActivityResult는 다른 App이나 다른 Activity를 호출한 결과를 받는 곳입니다.

MainActivity --> 카메라앱(혹은 자체 카메라 Activity) 호출 --> onActivityResult() 에서 카메라앱에서 보내준 이미지를 처리.

그렇기 때문에, 다시 돌아올 때, MainActivity의 onActivityResult()로 돌아오면,

MainActivity의 기존 데이터는 사라질 수 있습니다.

위의 소스는 애매하네요. 자체 Camera 함수를 MainActivity에 내장하고 있다면 굳이 onActivityResult를 쓸 이유가 없죠.
Will Kim (43,170 포인트) 님이 2017년 9월 5일 답변
...