[Android] 스레드에서 ProgressDialog 사용

ProgressDialog가 사용되는 경우는 대부분 시간이 많이 소요되는 연산을 스레드에서 실행할때 사용자에게 대기하도록 하는 용도입니다. 그러나 이 글의 제목에서 언급된 스레드는 ProgressDialog를 생성하고 표시(Show)하는 코드가 스레드에 위치하는 경우를 의미합니다.

블랙포인트라는 모바일 GIS 엔진에서 지도를 처음 그리기 시작할때 발생하는 이벤트와 지도가 모두 다 그려질때 발생하는 이벤트의 리스너는 각각 OnBeforeMapDrawEventListener와 OnUpdateMapCompletedEventListener입니다. 이 이벤트 리스너가 호출되는 위치가 바로 그리기 스레드(Rendering Thread)이므로 Handler를 사용하여 ProgressDialog를 생성하고 표시해줘야 합니다.

private static ProgressDialog progressDialog = null;

@Override
public void onBeforeMapDraw(BeforeMapDrawEvent event) {
    Message msg = new Message();
    msg.what = 0;
    msg.obj = event;
    handler.sendMessage(msg);
}
	
@Override
public void onUpdateMapCompleted(UpdateMapCompletedEvent event) {
    handler.sendEmptyMessage(1);
}
	
private static Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        if(msg.what == 0) {
            BeforeMapDrawEvent event = (BeforeMapDrawEvent)msg.obj;
            if(event.isCalledUpdateMethod()) {
                if(MainActivity.progressDialog == null)  {
                    MainActivity.progressDialog = ProgressDialog.show(
                        event.getMap().getContext(), "", 
                        Html.fromHtml(
                            "Please wait for map drawing ..."));
                    Window dlgWin = MainActivity.progressDialog.getWindow()
                    dlgWin.setGravity(Gravity.BOTTOM);
                }
            }				
        } else if(msg.what == 1) {
            if(MainActivity.progressDialog != null) { 
                MainActivity.progressDialog.hide();
                MainActivity.progressDialog = null;
            }				
        }
    }
};

스레드로부터 안전한 ProgressDialog를 표시하는 중요한 코드는 16번 코드부터입니다. 아래는 위의 코드가 적용되어 실제 실행되는 화면입니다.

사용자 삽입 이미지

안드로이드에서 CAD, PDF 등의 파일 보기

안드로이드 디바이스에 저장된 CAD나 PDF 등과 같은 파일을 볼 수 있는 손쉽고 강력하며 안정적인 방법은 각각 파일을 볼 수 있는 책임성이 뛰어난 앱을 활용하는 것이라 할 수 있습니다. 예를 들어서 CAD 파일을 볼 수 있는 앱은 CAD 파일을 개발한 AutoDesk사의 AutoCAD 360이나 AutoDwg사의 DWGSee가 있으며 PDF 파일을 볼 수 있는 앱은 PDF 파일을 개발한 Adobe사의 Adobe Reader가 있습니다.

개발사가 업무용 프로그램을 개발하면서 경험하게 되는 요구사항은 고객이 가지고 있는 데이터 파일을 볼 수 있게 해달라는 것인데, GIS 분야에서는 DWG나 DXF와 같은 CAD 파일과 일반 문서인 PDF 파일이 바로 이러한 요구사항에 해당되는 데이터 파일이라고 할 수 있겠습니다.

이러한 데이터 파일을 별도의 앱과 연동하여 볼 수 있는 샘플 프로그램을 만들어 정리해 봅니다. 화면상에 2개의 버튼을 배치하고 첫번째 버튼을 터치하면 CAD 파일을 보고 두번째 버튼을 터치하면 PDF 파일을 볼 수 있도록 하겠습니다. 아래는 이러한 버튼의 배치 화면입니다.

사용자 삽입 이미지

첫번째 버튼인 CAD File View의 터치 이벤트에서 호출되는 함수입니다.

Intent intent = new Intent(Intent.ACTION_DEFAULT);
File file = new File("/sdcard/mapdata/dwg/samples.dwg");
if(file.exists()) {
    Uri uri = Uri.fromFile(file);
    intent.setData(uri);
    startActivity(intent);
}

이 버튼을 터치하면 아래의 화면 예처럼 지정된 파일을 볼 수 있습니다.

사용자 삽입 이미지

다음은 두번째 버튼인 PDF File View의 터치 이벤트에서 호출되는 함수입니다.

intent = new Intent(Intent.ACTION_DEFAULT);
File file = new File("/sdcard/e10842.pdf");
if(file.exists()) {
    Uri uri = Uri.fromFile(file);
    intent.setData(uri);
    startActivity(intent);
}

이 버튼을 터치하면 아래의 화면 예처럼 지정된 파일을 볼 수 있습니다.

사용자 삽입 이미지

안드로이드에서 이러한 프로그램들의(정확히는 Activity 간의) 연동은 매우 자연스러우며 매우 빠르게 실행됩니다. 그리고 다시 원래의 프로그램으로 자연스럽고 신속하게 복귀되어 마치 하나의 프로그램처럼 연동됩니다.

비록 간단한 내용이지만 고객의 요구사항에 대해서 빠르고 정확하게 수용할 수 있다는 점에서 정리해 봅니다. 그러나 이 방식의 단점은 특정한 데이터 파일을 볼 수 있는 앱을 별도로 설치해줘야 한다는 점입니다. 위의 코드들을 위해 제가 설치한 프로그램은 DWGSee와 Adobe Reader였습니다.

Java에서 POST 방식으로 GeoService-X에 SQL 쿼리 요청

GeoService-Xr 공간서버에 직접 Java 언어로 SELECT 구문과 쿼리를 요청하는 코드 Keeping ..

try {
    URL url = new URL("http://X.X.X.X:8078/Xr?sql|oracle|0");
    HttpURLConnection httpConn = (HttpURLConnection)url.openConnection();
    httpConn.setUseCaches(false);
    httpConn.setDoOutput(true);
    httpConn.setRequestMethod("POST");
    OutputStream outputStream = httpConn.getOutputStream();
    String sql 
        = "SELECT IDN, CDE, MNG FROM TBLNAME WHERE IDN=2437";
    byte[] bytesSql = sql.getBytes();
    ByteBuffer bb = ByteBuffer.allocate(bytesSql.length + 1 + 4);
			
    bb.order(ByteOrder.BIG_ENDIAN);
    bb.putInt(bytesSql.length + 1);
    bb.put(bytesSql);
    bb.put((byte)0);
    bb.flip();
			
    byte[] bytes = bb.array();
    outputStream.write(bytes);
    outputStream.close();
			
    int responseCode = httpConn.getResponseCode();
    if(responseCode == HttpURLConnection.HTTP_OK) {
        BufferedReader reader 
            = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
        System.out.println("Server's response: ");
        while(true) {
            String response = reader.readLine();
            if(response == null) break;
            System.out.println("\t" + response);
        }
    } else {
        System.out.println("Server returned non-Ok code: " + responseCode);
    }
} catch (Exception e) {
    e.printStackTrace();
}