728x90

웹서버 상에 이미지를 다운로드하여 안드로이드 어플에서 사진정보를 보여주기 위한 기능을 테스트 중이다.


먼저 웹서버에 이미지 파일이 존재하는지 유무를 체크하는 기능부터 테스트를 했다.


protected void showList() {
    try {
        JSONObject jsonObj = new JSONObject(searchJSON);
        peoples = jsonObj.getJSONArray(TAG_RESULTS);

        personDataItem.clear(); // 서버에서 가져온 데이터 초기화
        for(int i=0;i<peoples.length();i++){
            JSONObject c = peoples.getJSONObject(i);
            final String uid = c.getString(TAG_UID);
            String name = c.getString(TAG_NAME);
            String mobileNO = c.getString(TAG_MobileNO);
            String officeNO = c.getString(TAG_OfficeNO);
            Drawable myIcon = getResources().getDrawable(R.mipmap.ic_launcher);

            final String photoURL = Value.IPADDRESS + "/photos/" + uid + ".jpg";
            System.out.println("Server Photo URL ===" + photoURL);
            AsyncTask.execute(new Runnable() {
                @Override
                public void run() {
                    if(isExists(photoURL) == true){
                        System.out.println("Server Photo Image ===" + uid);
                    }
                }
            });

            // 서버에서 가져온 데이터 저장
            listViewAdapter.addItem(myIcon,uid,name,mobileNO,officeNO);
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // 갱신된 데이터 내역을 어댑터에 알려줌
                listViewAdapter.notifyDataSetChanged();
            }
        });

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

 private static boolean isExists(String URLName) {
    // 서버에 파일의 존재 유무 파악
    try {
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
        con.setRequestMethod("HEAD");
        if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
            return true;
        }
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return false;
}


for 문 내에서 순차적으로 결과가 나올 것 같지만 AsyncTask.execute(new Runnable() 에서 처리는 나중에 처리됨을 확인할 수 있다.


사진 이미지가 있는 경우와 없는 경우 결과가 false 로 처리됨을 확인할 수 있다.


코드 구현시 결과가 순차적으로 실행되지 않는다는 점이 중요한 이슈가 될 수도 있다.

순서대로 처리되어야 할 로직인 경우에는 구현 로직을 고민해봐야 한다.


이제 서버에서 파일을 안드로이드폰으로 다운로드하는 함수를 만들어야 한다.

protected void showList() {
    try {
        JSONObject jsonObj = new JSONObject(searchJSON);
        peoples = jsonObj.getJSONArray(TAG_RESULTS);

        personDataItem.clear(); // 서버에서 가져온 데이터 초기화
        for(int i=0;i<peoples.length();i++){
            JSONObject c = peoples.getJSONObject(i);
            final String uid = c.getString(TAG_UID);
            final String name = c.getString(TAG_NAME);
            final String mobileNO = c.getString(TAG_MobileNO);
            final String officeNO = c.getString(TAG_OfficeNO);
            // 이미지 사이즈가 커서 생기는 문제??
            final Bitmap myIcon = PHPComm.autoresize_decodeResource(getResources(), R.mipmap.photo_base, 160);

            final String photoURL = Value.IPADDRESS + "/photos/" + uid + ".jpg";
            System.out.println("Server Photo URL ===" + photoURL);
            AsyncTask.execute(new Runnable() {
                @Override
                public void run() {
                    if(isExists(photoURL) == true){
                        Bitmap rBmp = loadWebImage(photoURL);
                        System.out.println("Server Photo Image ==="+ uid +" | "+ rBmp);
                        System.out.println("Photo Image height ==="+ rBmp.getHeight());
                        int width = (int)(rBmp.getWidth() * 160.0 / rBmp.getHeight());
                        rBmp = Bitmap.createScaledBitmap(rBmp, width, 160,true);

                        // 서버에서 가져온 데이터 저장
                        listViewAdapter.addItem(rBmp,uid,name,mobileNO,officeNO);
                    } else {
                        // 서버에 사진 이미지가 없으면 기본 이미지를 포함한 정보 저장
                        listViewAdapter.addItem(myIcon,uid,name,mobileNO,officeNO);
                    }
                }
            });

            // 서버에서 가져온 데이터 저장
            //listViewAdapter.addItem(myIcon,uid,name,mobileNO,officeNO);
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // 갱신된 데이터 내역을 어댑터에 알려줌
                listViewAdapter.notifyDataSetChanged();
            }
        });

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

private static boolean isExists(String URLName) {
    // 서버에 파일의 존재 유무 파악
    try {
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
        con.setRequestMethod("HEAD");
        if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
            return true;
        }
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return false;
}

Bitmap mBmp = null;
// 서버에서 전달 받은 데이터를 Bitmap 이미지에 저장
public Bitmap loadWebImage(String URLName) {
    try {
        // 스트림 데이터를 Bitmap 에 저장
        InputStream is = new URL(URLName).openStream();
        mBmp = BitmapFactory.decodeStream(is);
        is.close();
    } catch(Exception e) {
        Log.d("tag", "Image Stream error.");
        return null;
    }
    return mBmp;
}

 public class PHPComm extends Activity {

    // serverURL : JSON 요청을 받는 서버의 URL
    // postParams : POST 방식으로 전달될 입력 데이터
    // 반환 데이터 : 서버에서 전달된 JSON 데이터
    public static String getJson(String serverUrl, String postParams) throws Exception {

        BufferedReader bufferedReader = null;  
        try {  
            URL url = new URL(serverUrl);  
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 세션 쿠키 전달
            String cookieString = CookieManager.getInstance().getCookie(Value.IPADDRESS);
            
            StringBuilder sb = new StringBuilder();  

            if(conn != null){ // 연결되었으면
                //add request header
                conn.setRequestMethod("POST");
                conn.setRequestProperty("USER-AGENT", "Mozilla/5.0");
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
                if (cookieString != null) {
                   conn.setRequestProperty("Cookie", cookieString);
                   Log.e("PHP_getCookie", cookieString);
                 }
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(10000);
                conn.setUseCaches(false);
                conn.setDefaultUseCaches(false);
                conn.setDoOutput(true); // POST 로 데이터를 넘겨주겠다는 옵션
                conn.setDoInput(true);

                // Send post request
                DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
                wr.writeBytes(postParams);
                wr.flush();
                wr.close();

                int responseCode = conn.getResponseCode();
                System.out.println("GET Response Code : " + responseCode);        
                if(responseCode == HttpURLConnection.HTTP_OK){ // 연결 코드가 리턴되면
                    bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    String json;
                    while((json = bufferedReader.readLine())!= null){
                        sb.append(json + "\n");
                    }      
                }
                bufferedReader.close();
            }
            System.out.println("PHP Comm Out : " + sb.toString());
            return sb.toString().trim();  

        } catch(Exception e){  
            return new String("Exception: " + e.getMessage());
        }
    }

    public static Bitmap autoresize_decodeResource(Resources res, int resId, int reqHeight) {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInAutoSize(options, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

    public static int calculateInAutoSize(BitmapFactory.Options options, int reqHeight) {
        // 원본 이미지의 높이와 너비
        final int height = options.outHeight;
        final int width = options.outWidth;

        float ratio = width / height;
        int reqWidth = Math.round((float) ratio * width);

        int inSampleSize = 1;
        if (height > reqHeight) {
            final int halfHeight = height / 2;
            while ((halfHeight / inSampleSize) > reqHeight) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }
}


현재까지 테스트에 사용되었던 파일을 첨부한다.

이미지 테스트를 하면서 Bitmap 가져오기를 하면서 PersonData.java 파일 내용도 수정되었다.


json_demo_getImage.zip



이미지 사이즈를 줄이는 것까지는 성공했는데, 문제는 매번 접속할 때마다 새롭게 이미지 파일을 받아오는 문제점을 해결해야 한다.

http://theeye.pe.kr/archives/1309

http://www.androidbegin.com/tutorial/android-json-parse-images-and-texts-tutorial/

에 좋은 내용의 예제가 있다. 이것을 이용하여 코드를 다시 수정하고 테스트를 해봐야겠다.


블로그 이미지

Link2Me

,