한 걸음 두 걸음

android - node.js 간단하게 데이터 통신하기 //Volley활용 본문

FrontEnd/Android

android - node.js 간단하게 데이터 통신하기 //Volley활용

언제나 변함없이 2019. 5. 24. 13:25
반응형

안드로이드 모바일 앱에서 node.js로 만든 서버로 데이터를 날리고,

서버에서 모바일로 보낸 데이터를 받아와 사용해보도록 하겠습니다.

mongoDB(NoSQL)까지 활용하는 것은 다음 포스팅으로 작성하고

이 포스팅에서는 간단히 데이터만 하나의 모듈(라우터사용없이)안에서 보내는 것까지 작성할 예정입니다.


android studio프로젝트의 gradle app module단계에

implementation 'com.android.volley:volley:1.1.0'
    implementation 'com.google.code.gson:gson:2.3.1'

를 추가해줍니다.

이제 implementation을 활용해야한다는 점 항상 유념해주세요~

참고로 volley1.0.0은 더 이상 지원하지 않습니다.

기존에 LoginPage에서 하드코딩으로 id = a 이고 pw = b이면 로그인이 가능하도록 간단히 만들어 두었었는데,

모바일에서 입력한 ID와 PW를 서버로 보내고, 서버에서 받아 ID와 PW가 일치하는지 확인한 후, 일치할 경우 승인 플래그 데이터를 전달하도록 만들겠습니다.


1. 모바일에서 서버로 ID / PW 전달하기.

서버구성(간단) - node.js

/*jslint devel: true */ 
/* eslint-disable no-console */ 
/*eslint no-undef: "error"*/ 
/*eslint-env node*/
//IP주소가 변화하면 안드로이드 앱 내에 있는 url 주소도 바꿔주어야 정상 동작하기시작함!


var express = require('express');
var http = require('http');
var bodyParser= require('body-parser');
var app = express();

app.set('port',process.env.PORT || 3000);
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

//첫 번째 미들웨어
app.use(function(req, res, next) {

    console.log('첫 번째 미들웨어 호출 됨');
    var approve ={'approve_id':'NO','approve_pw':'NO'};


    var paramId = req.body.id;
    var paramPassword = req.body.password;
    console.log('id : '+paramId+'  pw : '+paramPassword);

    //아이디 일치여부 flag json 데이터입니다.
    if(paramId == 'test01') approve.approve_id = 'OK';
    if(paramPassword == '123') approve.approve_pw = 'OK';

    res.send(approve);

});

var server = http.createServer(app).listen(app.get('port'),function(){
   console.log("익스프레스로 웹 서버를 실행함 : "+ app.get('port')); 
});

위는 미들웨어 하나로 만든 node.js 서버입니다. 이는 제 컴퓨터로 돌리고있는 중입니다.
이제 모바일로 가서

edittext를 3개와 버튼 하나를 만들었습니다. (아래의 textView는 디버깅용이라 신경 안쓰셔도 됩니다.)

맨 위에 자신의 컴퓨터의 port주소:3000로 해줍니다. (저는 3000번 포트를 쓰겠다고 서버 만들 때 지정해두었기때문에)

자신의 컴퓨터 주소는 cmd창에서 ipconfig로 확인하실 수 있습니다.

WiFi를 쓰고 있어서 위의 IPv4주소를 읽어왔습니다.

현재 제 ip주소는 172.19.83.10이네요. 이런 경우, http://172.19.83.10:3000 으로 입력하시면 됩니다.

그리고 아래 두 edittext는 ID와 PW를 입력하는 창이라고 제가 임시로 지정한 칸입니다.

이제 데이터를 전달하고 받을 해당 Activity로 이동하겠습니다.

아래의 코드는 서버로 데이터를 보내고 데이터를 받는 android studio의 Acitivity코드입니다.

public void request(){
        //url 요청주소 넣는 editText를 받아 url만들기
        String url = editText.getText().toString();

        //JSON형식으로 데이터 통신을 진행합니다!
        JSONObject testjson = new JSONObject();
        try {
            //입력해둔 edittext의 id와 pw값을 받아와 put해줍니다 : 데이터를 json형식으로 바꿔 넣어주었습니다.
            testjson.put("id", id.getText().toString());
            testjson.put("password", pw.getText().toString());
            String jsonString = testjson.toString(); //완성된 json 포맷

            //이제 전송해볼까요? 
            final RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
            final JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url,testjson, new Response.Listener<JSONObject>() {

            //데이터 전달을 끝내고 이제 그 응답을 받을 차례입니다.
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        println("데이터전송 성공");

                        //받은 json형식의 응답을 받아 
                        JSONObject jsonObject = new JSONObject(response.toString());

                        //key값에 따라 value값을 쪼개 받아옵니다.
                        String resultId = jsonObject.getString("approve_id");
                        String resultPassword = jsonObject.getString("approve_pw");

                        //만약 그 값이 같다면 로그인에 성공한 것입니다.
                        if(resultId.equals("OK") & resultPassword.equals("OK")){

                            //이 곳에 성공 시 화면이동을 하는 등의 코드를 입력하시면 됩니다.
                        }else{
                            //로그인에 실패했을 경우 실행할 코드를 입력하시면 됩니다.
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //서버로 데이터 전달 및 응답 받기에 실패한 경우 아래 코드가 실행됩니다.
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                    //Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_SHORT).show();
                }
            });
            jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
            requestQueue.add(jsonObjectRequest);
            //
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

이렇게 서버와 데이터를 주고받아보았습니다.

최대한 간단하게 구성했는데,
다음 포스팅에서는 라우터를 활용하여 더 구체적으로 서버와의 통신을 진행해보도록 하겠습니다.


임시저장 node 확정코드

/*jslint devel: true */ 
/* eslint-disable no-console */ 
/*eslint no-undef: "error"*/ 
/*eslint-env node*/
//172.19.83.109
//IP주소가 변화하면 안드로이드 앱 내에 있는 url 주소도 바꿔주어야 정상 동작하기시작함!


var express = require('express');
var http = require('http');
var bodyParser= require('body-parser');
var app = express();

app.set('port',process.env.PORT || 3000);
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
var router = express.Router();

//첫 번째 미들웨어
app.use(function(req, res, next) {

    console.log('첫 번째 미들웨어 호출 됨');
    var approve ={'approve_id':'NO','approve_pw':'NO'};


    var paramId = req.body.id;
    var paramPassword = req.body.password;
    console.log('id : '+paramId+'  pw : '+paramPassword);

    //아이디 일치여부 flag json 데이터입니다.
    if(paramId == 'test01') approve.approve_id = 'OK';
    if(paramPassword == '123') approve.approve_pw = 'OK';

    res.send(approve);

});

var server = http.createServer(app).listen(app.get('port'),function(){
   console.log("익스프레스로 웹 서버를 실행함 : "+ app.get('port')); 
});

안드로이드 LoginActivity.java확정코드

public class LoginActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener{

    SignInButton Google_Login;
    private static final int RC_SIGN_IN = 1000;
    private FirebaseAuth mAuth;
    private GoogleApiClient mGoogleApiClient;

    EditText editTextID;
    EditText editTextPW;
    Button buttonLogin;

    String ID;
    String PW;
    //Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        init();

        buttonLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ID = editTextID.getText().toString();
                PW = editTextPW.getText().toString();
                requestLogin(ID, PW);

            }
        });

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, this)
                .addApi(Auth.GOOGLE_SIGN_IN_API,gso)
                .build();

        mAuth = FirebaseAuth.getInstance();

        Google_Login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
                startActivityForResult(signInIntent,RC_SIGN_IN);
            }
        });
    }

    public void init(){
        editTextID = (EditText)findViewById(R.id.editTextID);
        editTextPW = (EditText)findViewById(R.id.editTextPW);
        buttonLogin = (Button)findViewById(R.id.activity_login_login_button);
        Google_Login = (SignInButton)findViewById(R.id.Google_Login);
        //mContext = getApplicationContext();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess()) {
                //구글 로그인 성공해서 파베에 인증
                GoogleSignInAccount account = result.getSignInAccount();
                firebaseAuthWithGoogle(account);
            }
            else{
                //구글 로그인 실패
            }
        }
    }
    private void firebaseAuthWithGoogle(GoogleSignInAccount acct){
        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(),null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if(!task.isSuccessful()){
                            Toast.makeText(LoginActivity.this, "인증 실패", Toast.LENGTH_SHORT).show();

                        }else{
                            Toast.makeText(LoginActivity.this, "구글 로그인 인증 성공", Toast.LENGTH_SHORT).show();
                            Intent intent = new Intent(getApplicationContext(), EnrollActivity.class);
                            startActivity(intent);
                            finish();
                        }
                    }
                });
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    public void requestLogin(String ID, String PW){
        String url = "http://172.19.83.10:3000";

        //JSON형식으로 데이터 통신을 진행합니다!
        JSONObject testjson = new JSONObject();
        try {
            //입력해둔 edittext의 id와 pw값을 받아와 put해줍니다 : 데이터를 json형식으로 바꿔 넣어주었습니다.
            testjson.put("id", ID);
            testjson.put("password", PW);
            String jsonString = testjson.toString(); //완성된 json 포맷

            //이제 전송해볼까요?
            final RequestQueue requestQueue = Volley.newRequestQueue(LoginActivity.this);
            final JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url,testjson, new Response.Listener<JSONObject>() {

                //데이터 전달을 끝내고 이제 그 응답을 받을 차례입니다.
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        //받은 json형식의 응답을 받아
                        JSONObject jsonObject = new JSONObject(response.toString());

                        //key값에 따라 value값을 쪼개 받아옵니다.
                        String resultId = jsonObject.getString("approve_id");
                        String resultPassword = jsonObject.getString("approve_pw");

                        if(resultId.equals("OK") & resultPassword.equals("OK")){
                            Toast.makeText(getApplicationContext(),"로그인 성공",Toast.LENGTH_SHORT).show();
                            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                            startActivity(intent);
                            finish();
                        }else{
                            easyToast("로그인 실패");
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //서버로 데이터 전달 및 응답 받기에 실패한 경우 아래 코드가 실행됩니다.
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                }
            });
            jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
            requestQueue.add(jsonObjectRequest);

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

    void easyToast(String str){
        Toast.makeText(getApplicationContext(),str,Toast.LENGTH_SHORT).show();
    }
}

이건

앞에서 사용한 건 jsonObjectResponse인데 아래는 StringResponse임. 그런데 이건 실행이 잘 되는지 확인은 안해봤음.
다만 지우기 전 기록용으로 남겨놓고 감. 데이터를 받는 역할만 기술되어있음 일단.

String urlTest = editText.getText().toString();
        StringRequest request = new StringRequest(
                Request.Method.POST,
                urlTest,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //응답이 오면 자동으로 호출되는 함수
                        println(response);//직접만든 출력함수
                        try
                        {
                            JSONObject jsonObject = new JSONObject(response.toString());
                            String resultId = jsonObject.getString("approve_id");
                            String resultPassword = jsonObject.getString("approve_pw");
                            check1.setText(resultId+"\n"+resultPassword);

                            if(resultId.equals("OK") & resultPassword.equals("OK")){
                                check2.setText("로그인 되었습니다.");
                            }else{
                                check2.setText("로그인 실패하였습니다.");
                            }
                        }
                        catch (JSONException e)
                        {
                            e.printStackTrace();
                        }

                    }
                },
                new Response.ErrorListener(){

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //에러가 발생하면 자동으로 호출되는 함수
                        println("에러발생함");
                    }
                }


        );

        request.setShouldCache(false);
        Volley.newRequestQueue(this).add(request);
반응형