728x90

XMPP Chat 기능 동작 테스트를 하려고 GitHub 자료를 다운로드 받아서 테스트 해보고 있다.

벌써 여러차례 로그인 실패를 겪으면서 GitHub 에 있는 자료와 동일한 환경으로 설정을 해보고자 프로젝트를 별도로 추가하는 방식으로 테스트하고 있다.


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:23.2.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:23.2.1'
    implementation 'com.android.support:recyclerview-v7:23.2.1'
    implementation 'org.igniterealtime.smack:smack-android:4.1.1'
    implementation 'org.igniterealtime.smack:smack-tcp:4.1.1'
    implementation 'org.igniterealtime.smack:smack-core:4.1.1'
    implementation 'org.igniterealtime.smack:smack-im:4.1.1'
    implementation 'org.igniterealtime.smack:smack-extensions:4.1.1'
    implementation 'org.igniterealtime.smack:smack-android-extensions:4.1.1'
    implementation 'org.igniterealtime.smack:smack-resolver-minidns:4.1.3'
    implementation 'org.igniterealtime.smack:smack-sasl-provided:4.1.1'
    implementation 'com.google.code.gson:gson:1.7.2'
    implementation 'com.google.android.gms:play-services:8.1.0'
}


<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".Login">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>


AndroidManifest.xml 에서 에러가 발생하면 위와 같이 하면 해결되더라.


그런데 문제는
implementation 'com.google.android.gms:play-services:8.1.0' 때문에 multidex 에러가 발생하는지 오류가 또다시 발생한다.

이건 시도해보려고 했지만 성공하지 못했다.



블로그 이미지

Link2Me

,
728x90

2013년 Google I/O에서 발표한 volley라는 Http 라이브러리를 이용하여 로그인 예제를 만들어봤다.

구글 자료들을 받아서 테스트 하다보니 여러가지 라이브러리로 만들어져 있어서 내가 만든 앱에 적용을 해보면서 기능을 테스트하고 적어둔다.

Volley 라이브러리를 사용하면 코드가 심플해져 사용하기 편하다는 걸 알 수 있을 것이다.


build.gradle 추가

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:recyclerview-v7:27.1.1' // ListView 개선 버전
    implementation 'com.android.support:cardview-v7:27.1.1'
    implementation 'gun0912.ted:tedpermission:2.0.0'
    implementation 'com.android.volley:volley:1.1.1'
}


API28(Android 9) 이상을 사용하는 경우에는 추가로 고려할 사항이 있다.

https 통신을 기본으로 지원하고 http 통신은 기본 지원이 아니라서 아래 색깔 표시한 한줄을 추가해줘야 한다.

AndroidManifest.xml 파일에 추가할 사항

<application
    android:allowBackup="false"
    android:icon="@drawable/icon_console"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:usesCleartextTraffic="true"> <!-- http:// 통신일 경우에도 통신 가능하도록 -->
 

앱 build.gradle 은 androidX 로 변경한다. 구글링하면 나온다.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // implementation 'com.android.support:appcompat-v7:28.0.0'
    //implementation 'com.android.support.constraint:constraint-layout:1.1.3'

    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'gun0912.ted:tedpermission:2.0.0'
    implementation 'com.android.volley:volley:1.1.1'
}


Volley를 사용하는 방법은
1) RequestQueue를 생성한다.
2) Request Object를 생성한다.
3) 생성한 Object를 RequestQueue로 넘긴다.


서버에서 받은 데이터가 텍스트인 경우에는 StringRequest 을 사용하고, JSON 데이터일 경우에는 JsonObjectRequest 를 사용하면 된다.

서버에서 데이터를 텍스트로 만들어서 보내기 때문에 StringRequest 를 사용하면 된다. 이렇게 하는 이유는 서버에서 에러가 발생했을 때 텍스트로 보내면 에러의 원인을 발견하고 서버 코드를 수정하기 쉽기 때문이다.


private void LoginVolley(final String loginID, final String loginPW) {
    // 1. RequestQueue 생성 및 초기화
    RequestQueue requestQueue = Volley.newRequestQueue(context);

    String url = Value.IPADDRESS + "/loginChk.php";

    // 2. Request Obejct인 StringRequest 생성
    StringRequest request = new StringRequest(Request.Method.POST, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.d("result", "[" + response + "]");
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d("error", "[" + error.getMessage() + "]");
                }
            }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("loginID", Value.encrypt(loginID));
            params.put("loginPW", Value.encrypt(loginPW));
            return params;
        }
    };

    // 3) 생성한 StringRequest를 RequestQueue에 추가
    requestQueue.add(request);
}



실제 사용하는 코드를 보면서 이해도를 높여보자.

코딩하면서 항상 신경써서 고려할 사항은 Log 를 보면서 문제가 서버쪽에 있는 것인지 안드로이드 코드에 문제가 있는 것인지 파악할 수 있어야 한다.


 private void LoginVolley(final String loginID, final String loginPW) {
    // 1. RequestQueue 생성 및 초기화
    RequestQueue requestQueue = Volley.newRequestQueue(context);

    String url = Value.IPADDRESS + "/loginChk.php";

    // 2. Request Obejct인 StringRequest 생성
    StringRequest request = new StringRequest(Request.Method.POST, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.d("result", "[" + response + "]"); // 서버와의 통신 결과 확인 목적
                    showJSONList(response);
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d("error", "[" + error.getMessage() + "]");
                }
            }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("loginID", Value.encrypt(loginID));
            params.put("loginPW", Value.encrypt(loginPW));
            params.put("uID", Value.encrypt(Value.getPhoneUID(context)));
            params.put("AppVersion", Value.VERSION);
            params.put("phoneVersion", Build.VERSION.RELEASE);
            params.put("phoneBrand", Build.BRAND);
            params.put("phoneModel", Build.MODEL);
            params.put("keyword", Value.encrypt(Value.URLkey()));
            return params;
        }
    };

    // 3) 생성한 StringRequest를 RequestQueue에 추가
    requestQueue.add(request);
}

private void showJSONList(String JSONdata) {
    // 서버 정보를 파싱하기 위한 변수 선언
    try {
        JSONObject jsonObj = new JSONObject(JSONdata);
        JSONArray logininfo = jsonObj.getJSONArray("result");

        JSONObject c = logininfo.getJSONObject(0);
        idx = Value.decrypt(c.getString("IDX"));
        dept1Code = Value.decrypt(c.getString("Dept1Code"));
        dept2Code = Value.decrypt(c.getString("Dept2Code"));

        System.out.println("idx : " + idx);

        if (Integer.parseInt(idx) > 0) { // 로그인 정보 일치
            pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
            SharedPreferences.Editor editor = pref.edit();

            editor.putString("id", loginID);
            editor.putString("pw", loginPW);
            editor.putString("autologin", "checked"); // 로그인되면 무조건 자동로그인 처리
            editor.putString("idx", idx); // 로그인 사용자의 idx
            editor.putString("category1", dept1Code);
            editor.putString("category2", dept2Code);
            editor.putString("uID", uID);
            editor.putString("registrationID", null);

            editor.commit();

            startActivity(new Intent(getApplication(), Main.class));
            finish(); // 현재 Activity 를 없애줌

        } else if (idx.equalsIgnoreCase("-1")) { // 등록된 단말기와 불일치
            deviceDismatch_showAlert();
        } else if (idx.equalsIgnoreCase("0")) {
            showAlert();
        } else if (idx.equalsIgnoreCase("-2")) {
            showDisAgree();
        } else if (idx.equalsIgnoreCase("-3")) {
            showDeny();
        } else {
            Toast.makeText(Login.this, "서버로부터 정보가 잘못 전송되었습니다", Toast.LENGTH_SHORT).show();
        }

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


참고 사항

ㅇ Android 로그인 폼 예제(https://link2me.tistory.com/1532)  에 이 코드를 추가해 보면 편하다.

ㅇ Anroid JSON 파헤치기 https://link2me.tistory.com/1247


이 글이 도움되었다면 000 부탁드립니다.

블로그 이미지

Link2Me

,