검색결과 리스트
글
저장된 사진및 파일이 보이지 않을 때 미디어스캐닝(Media Scanning) 방법 [Kitkat 이후의 버전에서 적용방법]
Socket을 활용하여 안드로이드 프로그래밍을 하는 분들이라면 누구나 한 번 즈음은 난관에 부딪치는 경우가 하나 있습니다. 그 중 하나가 분명 소켓 통신을 통해 받은 이미지나 동영상 파일을 저장하였는데 갤러리를 통해 확인해 보려 하면 보이지 않는 경우이지요! 희한하게도 안드로이드 기기의 전원을 끈 후 다시 확인해보면 안보이던 사진이 버젓이 보인다는 사실!
갤러리에 내가 다운로드 받은 파일이 누락되어 있다면 상당히 당황스러울 것이다.
실제로 안드로이드 기기는 파일을 바로 저장한 상태로는 이를 기기가 바로 인식을 하지 못합니다. 그렇다면 기껏 다운로드 받은 파일을 보기 위해서 안드로이드 기기를 리셋 하는 방법밖에 없는 걸까요?
안드로이드 기기를 쓰다가 위와 같이 미디어스캐닝(Media scanning)이 진행중인 것을 종종 보실 수 있습니다. 이것이 바로 종적을 감추어버린 파일들의 위치를 다시 찾는 기능을 하는 녀석입니다. 종종 개발자들이 애플리케이션을 개발하던 도중 다운로드가 완료된 후 미디어스캐닝을 해주지 않게 될 경우 파일을 볼 수 없는 상황이 벌어지는 것입니다.
이번 포스팅에서는 소스코드를 통하여 미디어스캐닝을 수행하는 방법에 대해 알아볼 것입니다. 또한 본 포스팅은 Kitkat에서부터 변경된 미디어 저장 방식을 반영한 방법에 대해 다루어 보도록 할 것입니다.
아래의 소스코드는 카메라로부터 촬영된 사진 데이터를 저장하는 과정을 나타낸 소스코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | private Camera.PictureCallback picb = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); long time = System.currentTimeMillis(); SimpleDateFormat day = new SimpleDateFormat("yyyymmddhhmmssSSS"); String output = day.format(new Date(time)); String folder = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/FrameworkTest"; String file = folder + File.separator + output + ".jpg"; File FolderPath = new File(folder); if (!FolderPath.exists()) { FolderPath.mkdirs(); Log.d("MKDIR", folder); } try { FileOutputStream out = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 50, out); out.close(); sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+file))); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } camera.startPreview(); } }; | cs |
위 소스코드의 내용대로 byte[] 형식으로 들어온 사진 데이터가 FileOutputStream 클래스를 통해 저장되는 과정을 나타내고 있습니다. 이를 위해 위의 소스코드 몇 줄을 확인해 보도록 하겠습니다.
String folder = Environment.getExternalStorageDirectory().getAbsolutePath();
저장할 파일의 폴더명을 설정해 줍니다. 위의 소스코드를 통해 안드로이드 기기의 외부저장소의 최상단에서의 절대주소를 얻을 수 있습니다.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+file)));
FileOutputStream을 통해 저장된 파일 하나를 나타내기 위해 해당 파일에 대해 Media Scanning을 수행합니다. Uri.parse() 의 인자값으로 해당 파일의 절대주소를 입력하며, Intent의 첫번째 인자인 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE에 주의하시면 해당 소스코드를 사용하는 데에 큰 문제는 없을 것입니다. 위와 같이 설정된 Intent 클래스를 sendBroadcast() 매서드를 통해 전달하면 저장된 파일에 대한 Media Scanning이 정상적으로 동작되에 갤러리를 통해 해당 파일을 확인하실 수 있을 것입니다.
'안드로이드 > 애플리케이션 제작' 카테고리의 다른 글
같은 공유기에 접속중인 안드로이드 기기 탐색 및 통신하기 (0) | 2015.10.16 |
---|---|
Error: The SDK Build Tools revision is too low for project (0) | 2015.10.10 |
byte[] 바이트 배열을 socket을 통해 쉽게 전송하는 방법 (0) | 2015.10.03 |
Handler와 Message를 활용하여 콜백함수 구현하기 (0) | 2015.08.24 |
안드로이드 기기 간에 Wifi Socket 통신하기 (14) | 2015.02.08 |
설정
트랙백
댓글
글
byte[] 바이트 배열을 socket을 통해 쉽게 전송하는 방법
C/C++을 통해 파일을 socket 통신으로 전송하는 경우 데이터를 char 배열을 통해 buffer의 크기를 고려하면서 전송을 해야 하기 때문에 프로그램을 설계할 때 상당히 많은 부분을 고려해야 되어 골치가 아프지요. 그러한 면에서 보았을 때 Java에서 제공하는 Socket 통신 기능들이 상당히 편해서 프로그래머들에게도 상당히 큰 부담을 줄여주는 점이 맘에 들곤 합니다. 이번 포스팅에서는 C/C++에서는 다루는 것이 다소 번거로운 byte 배열을 손쉽게 전송하는 방법에 대해 알아보도록 하겠습니다.
안드로이드 프로그래밍을 하다 보면 이미지나 파일을 Socket을 통해 전송해야 되는 경우들이 많습니다. 만약 수신측이 C/C++로 짜여져 있으면 정해진 buffer로 나누어서 전송을 해야 하기 때문에 파일을 byte[] 배열 형식으로 변환한 후 socket에 실어서 전송해야 합니다. 프로그램을 설계할 때 도중에 자료가 누락되는 경우 원본의 손실 또한 발생하기 때문에 신중하게 프로그래밍을 해야 합니다.
안드로이드 카메라의 경우 takePicture() 함수에 callback 함수를 통해 카메라에 찍힌 이미지를 아래와 같은 방식으로 byte[] 배열로 제공합니다. 프로그래머는 이를 통해 파일로 저장하거나 화면에 띄우는 등의 작업을 수행하게 됩니다.
1 2 3 4 5 6 7 8 9 10 11 | private Camera.PictureCallback picb_remote = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub .... camera.startPreview(); } }; | cs |
위의 이미지 형식의 데이터인 byte[] 배열을 Java 기반의 서버와 socket을 통해 어떤 방식으로 통신을 하면 가장 간편할까요? Java에서는 직렬화 된 Object 혹은 byte[] 배열을 손쉽게 전송할 수 있는 ObjectOutputStream과 ObjectInputStream을 제공합니다. 이를 사용하는 방식에 대해 좀 더 자세히 알아보겠습니다. 소스코드에서 각 중요한 내용을 주석을 통해 설명하였습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | private Camera.PictureCallback picb_remote = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub try { //IP주소와 포트번호를 입력하여 Socket 통신을 시작합니다. Socket sock = new Socket("127.0.0.1", 8200); //Socket으로부터 outputStream을 얻습니다. OutputStream os = sock.getOutputStream(); //등록한 OutputStream을 ObjectOutputStream 방식으로 사용합니다. ObjectOutputStream oos = new ObjectOutputStream(os); //byte[] 파일을 object 방식으로 통째로 전송합니다. oos.writeObject(data); oos.close(); os.close(); sock.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } camera.startPreview(); } }; | cs |
위의 소스코드에서 보이는 바와 같이 생성된 byte[] 배열을 그대로 writeObject() 매서드의 인자값에 등록을 하면 Java에서는 이를 그대로 Server 쪽으로 전송해줍니다. 아래는 byte[]를 수신하는 Server 측의 소스코드입니다. 중요한 부분은 주석으로 설명합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int port = 8200; //Server측에서 사용할 포트번호를 설정한 후 Socket 서버를 개방합니다. ServerSocket sock = new ServerSocket(port); //Client로부터 소켓 신호를 기다립니다. Socket socket = sock.accept(); //Socket로부터 InputStream을 등록합니다. InputStream is = socket.getInputStream(); //등록한 InputStream을 ObjectInputStream방식으로 사용합니다. final ObjectInputStream ois = new ObjectInputStream(is); //전송된 byte[] 데이터를 수신합니다. byte[] data = (byte[])ois.readObject(); System.out.println("data size : " + data.length); ois.close(); is.close(); socket.close(); sock.close(); | cs |
위와 같은 방식으로 Socket 프로그램을 설계하시면 byte[] 배열 방식으로 되어있는 데이터 값을 Java 상에서 손쉽게 전송할 수 있습니다.
'안드로이드 > 애플리케이션 제작' 카테고리의 다른 글
Error: The SDK Build Tools revision is too low for project (0) | 2015.10.10 |
---|---|
저장된 사진및 파일이 보이지 않을 때 미디어스캐닝(Media Scanning) 방법 [Kitkat 이후의 버전에서 적용방법] (0) | 2015.10.04 |
Handler와 Message를 활용하여 콜백함수 구현하기 (0) | 2015.08.24 |
안드로이드 기기 간에 Wifi Socket 통신하기 (14) | 2015.02.08 |
USB를 연결한 후 Logcat이 바로 보이지 않을 때 해결방법 (0) | 2015.02.07 |
설정
트랙백
댓글
글
IP v4 주소 0.0.0.0의 의미
IP주소는 여러분들이 흔히 아시듯이 인터넷에 접속하기 위해 사용되는 자신의 기기에 할당되는 일종의 주소와 같은 역할을 합니다. 이 중 몇몇 IP주소의 경우 특수 용도로 쓰입니다.
가장 대표적인 것이 0.0.0.0과 255.255.255.255입니다. 255.255.255.255는 한정된 범위 내에 접속된 모든 기기에 패킷을 보내는 용도로 사용됩니다. 그렇다면 0.0.0.0은 어떤 용도로 사용되는 것일까요?
IP주소 0.0.0.0은 IPv4 패킷을 전송하고자 하는 컴퓨터가 자신의 IP주소를 모르는 경우 통신을 하기 위해 사용됩니다. 보통 자신의 IP주소를 모르는 컴퓨터는 부트스트랩(컴퓨터의 전원을 킬 때나 재부팅할 때)이 진행되는 도중에 위 주소를 사용합니다.
이 신호를 보낸 컴퓨터는 자신의 주소를 알기 위해 이 주소를 발신지 주소로 설정하고 목적지 주소로 255.255.255.255로 설정한 IP 패킷을 DHCP서버로 전송합니다. DHCP서버는 신호를 받은 후 해당 PC에 IP 주소를 알려주며 PC는 해당 주소를 자신의 IP 주소로 사용합니다.
보다 더 자세한 내용을 알고 싶으신 분은 아래 링크를 참조해 주시길 바랍니다.
'공대생의 팁' 카테고리의 다른 글
우분투 커널 업데이트 후 VirtualBox가 제대로 동작되지 않을 때 해결방법(버전 5.08 이후) (0) | 2015.11.05 |
---|---|
[컴퓨터비전]이미지 변환시 DoF(Degrees of Freedom)에 대한 고찰 (0) | 2015.10.13 |
PHLASHNT.SYS 드라이버를 로드할 수 없습니다. 오류 코드: 1275 (1) | 2015.09.07 |
Intel Management Engine BIOS Extention 설정시 암호 변경이 안될 때 해결방법 (1) | 2015.08.19 |
Ubuntu에서 특정 Unicode가 안보일 때 (0) | 2015.07.22 |