Press "Enter" to skip to content

[일:] 2019년 07월 10일

Android에서 JSON 데이터를 송수신

Android에서 JSON 데이터를 송수신하기 위해서 HttpURLConnection을 사용하여 만든 함수 입니다.

  • serverURL : JSON 요청을 받는 서버의 URL
  • postPara : POST 방식으로 전달될 입력 데이터
  • flagEncoding : postPara 데이터의 URLEncoding 적용 여부
  • 반환 데이터 : 서버에서 전달된 JSON 데이터
public static String getJson(String serverUrl, String postPara, boolean flagEncoding) throws Exception {
         URL url = null;
         HttpURLConnection conn = null;
         PrintWriter postReq = null;
         BufferedReader postRes = null;
         StringBuilder json = null;
         String line = null;

json = new StringBuilder();
try {
    if (flagEncoding) {
        postPara = URLEncoder.encode(postPara);
    }

    url = new URL(serverUrl);
    conn = (HttpURLConnection) url.openConnection();
    conn.setDoOutput(true);
    conn.setUseCaches(false);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", "text/plain");
    conn.setRequestProperty("Content-Length", 
                                               Integer.toString(postPara.length()));
    conn.setDoInput(true);

    postReq = new PrintWriter(
                      new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
    postReq.write(postPara);
    postReq.flush();

    postRes = new BufferedReader(
                     new InputStreamReader(conn.getInputStream(), "UTF-8"));
    while ((line = postRes.readLine()) != null){
        json.append(line);
    }
    conn.disconnect();
} catch (MalformedURLException ex) {
    throw new Exception(ex.getMessage());
} catch (IOException ex) {
    throw new Exception(ex.getMessage());
} catch (Exception ex) {
    throw new Exception(ex.getMessage());
}
return json.toString(); 
}   

출처 : http://www.jopenbusiness.com/tc/oss/entry/Android에서-Json-사용하여-통신하기-1?category=15

안드로이드 개발할때 WI-FI로 연결하기 ( adb 무선 연결 )

출처 : http://kmshack.tistory.com/364


개발할때 USB안쓰고 WI-FI로 써야 겠다고 생각!

방법은 아주 간단하다.

ADB  무선 연결 / 무선 접속

일단은 을 USB에 연결 후 TCPIP 포트를 세팅한다. 

ADB명령을 통해 포트 7777로 변경한다. (숫자는 아무거나 상관 없음)

#adb tcpip 7777


그리고 이제 USB안녕! 이제 USB 선정리 해버리자!! 폰과 컴퓨터가 같은 네트워크가 연결 된 환경에서 폰의 WIFI주소(설정 – WIFI설정 – 연결된 WIFI를 통해 알수 있음)를 알아서, 아래 명령을 입력 하자.


#adb connect xxx.xxx.xxx.xxx:7777


지저분한 USB안녕?

하지만 베터리 어쩌지…


쓸때만 켜고 제니모션 에뮬레이터를 써야 겠다.

참고로 연결을 끊을때는

# adb disconnect xxx.xxx.xxx.xxx:7777

ViewPager에서 탭 구현시 옆 탭을 미리 읽는 문제..

문제라고 하기보다는 현재 보이는 탭의 옆 탭을 미리 읽어둬서 탭 슬라이드로 넘어갈때 자연스럽게 넘어가게 하는 기술이라 보겠다.
(액티비티 형태의 프로그램만 만지작 하다가 요즘 프래그먼트 형태의 프로그램을 만지작하다보니 삽질의 연속이다.)

하지만 옆 탭이 로딩하는데 통신같은 상당한 시간이 걸리거나, 심지어 프로그래스다이얼로그까지 나타나는 탭이라면 골치가 아파온다.

왜냐! 현재 탭은 이미 화면에 나타나서 잘 보이고 사용자의 입력을 기다릴 타이밍인데, 

옆 탭을 미리 로딩하면서 현재화면에 프로그래스다이얼로그가 나타난다? 켁…

(이걸 해결하기 위해 몇시간을 삽질했다… ㅜㅡ 알고보면 이렇게 간단한 것을…. )
(물론, 미리 로딩하는 걸 안하게 프로그램하는 방밥이 있을~지도 모른다…..만 안찾아봤다.. ㅡㅡ)

이제 하나하나 스텝별로 짚고 넘어가 볼까요?

상황을 하나 가정해 본다.

탭이 로딩될때 스레드로 통신을 해서 데이터를 화면에 보여주는 것이라고 하자…

현재 사용자에게 보이는 탭 화면이 자신인지는 다음과 같이 판단한다.

TabActivity는 탭을 감싸고 있는 Activity

tabIdex는 자기 자신이 TabActivity에 붙는 순번(인덱스)

탭이 표시되는 클래스의 onCreate나 onResum이나 onCreateView 등등에 아래와 같은 코드를 넣을 수 있겠죠?

if ( TabActivity.getCurrentPagerPosition() == tabIdx )
{
    // 내가 보이고 있다!!! 여기다 프로그래스다이얼로그를 뿌려주면 되것다.
}
else
{
    // 내가 보이는 중이 아니라면 미리 읽어들이는 거니깐 프로그래스다이얼로그는 표시하지 말자
}

// 필요한 스레드 생성해서 돌리기
if ( thread == null )
{
  thread = new Thread();
  thread.start();
}
// 쓰레드 동작 안하는 중
else if ( thread.isAlive() == false )
{
  // 앗싸리 새로 생성해서 다시 실행하는게 안전할라나???
  thread.start();
}
// 쓰레드가 아직 동작하는 중
else
{
   // 아무것도 안해도 되것죠? 이미 스레드가 돌고 있으니깐.
}

이렇게 해놓으면 미리 읽어들이는 중에서는 프로그래스 다이얼로그가 표시되지 않는다.

만일 사용자가 화면을 휙휙휙 넘겨서 쓰레드가 끝나기 전에 해당 화면으로 오면??? 

프로그래스 다이얼로그가 표시되어야 하는데 표시되지 않고 사용자가 뭔가를 입력할 수 있는 상황이 된다.

어랏??? 이것도 쬐끔 위험한 일이다.. 그래서 막아보자~~~

다음 코드를 넣어주면 된다.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

         if ( isVisibleToUser )
        {
            if ( thread != null )
            {
                // 스레드가 동작중이면
                if ( thread.isAlive( ) )
                {
                    // 한번도 표시된 적이 없다면
                    if ( progressDialog == null )
                    {
                        // 조회중 표시
                        progressDialog = ProgressDialog.show( TabActivity, “통신중”, “조회중…”, true, false );
                    }
                    // 표시중이지 않으면
                    else if ( progressDialog.isShowing() == false )
                    {
                        // 조회중 표시
                        progressDialog = ProgressDialog.show( TabActivity, “통신중”, “조회중…”, true, false );
                    }
                }
            }
        }   
}

마지막으로 이 프로그래스 다이얼로그는 쓰레드 종료 시점에 다음 코드로 종료해 주면 되것다.

if ( progressDialog != null )
{
     if ( progressDialog.isShowing() )
     {
          progressDialog.dismiss();
     }
}

작업환경 : 안드로이드 스튜디오 1.1.0
참고자료 : http://stackoverflow.com/questions/9323279/how-to-test-if-a-fragment-view-is-visible-to-the-user

Bitmap too large to be uploaded into a texture 에러 메시지 대처방법

내가 경험한 메시지는 정확하게 이렇게 나온다.

W/OpenGLRenderer﹕ Bitmap too large to be uploaded into a texture (5100×4212, max=4096×4096)



안드로이드에서 ImageView 에다가 좀 해상도가 나가는(?) 이미지를 올리면 이런 메시지가 나오는 경우가 있다.

실제 이미지 사이즈는 4096×4096보다 훨씬 작은데도 말이다. 
(나는 1700×1404 이었다 절반도 안되는데 막 이레… ㅡㅡ;)


황당한 것은 롤리팝(5.0)이 올라간 넥서스 5에서 퍽퍽 난다…. 죽지는 않고 이미지가 안나오고 흰 화면만 나올 뿐이다.

돌아버리는 줄알았다.. 

똑같은 apk를 프로요나 진저브레드에 설치해서 돌려보면 잘 돌아간다.

아놔… 이 시키들 뭘 바꾼겨??? 라는 생각을 했지만… 뭐… 갸들도 합리적이라 생각해서 뭔가를 바꿧겠지…



원인을 알아보자…

drawable 폴더에 있는 나의 이미지 파일은 drawable-mdpi 에 넣은거랑 동일하다. 

왜??? 거기가 1dp == 1px 이니깐… 근데… 내 안드로이드 기기가 xxhdpi(1080×1920)이라면 mdpi 꺼를 확대해서 사용한다.

몇배??? 

3배!!! ㅡㅡ;;;;

나의 경우는 1700*3 x 1404*3 = 5100 x 4212 딱 맞다~ 에러 메시지에 나온 얼토당토 않은 초고해상도가 이렇게 나온 것이었다.

췟!!! 이게 뭐다냥…


이제 해결을 해보자

우선 완전 간단하게 해결 하는 방법 : 
/drawable 에 있는 이미지 파일을 /drawable-nodpi 폴더로 이동한다. 
폴더가 없으면 /drawable 와 같은 레벨에 만들면 된다. dpi를 적용하지 않는 이미지가 저장되는 파일들이다. 
당근 xxhdpi 단말기에서도 확대를 하지 않고 그대로 쓴다.

해결은 당장 되지만 이미지의 퀄리티는 쫌 떨어져 보인다.


쬐끔 복잡하게 해결 하는 방법 : 
drawable-mdpi, hdpi, xhdpi, xxhdpi 에다가 각각의 화면 단위에 맞게 이미지를 만들어 주는 것이다.
같은 이미지를 해상도를 달리하여 저장하는 작업이기 때문에 쫌 까다롭겠지만 괸찮은 퀄리티의 이미지를 보여줄 수 있다.