2023.03.15 - 안드로이드 앱개발자 과정

CHA·2023년 3월 15일
0

Android



HTTP 통신 라이브러리 : Retrofit

우리는 앞서 HttpURLConnection 을 사용하여 Http 의 통신을 처리해주었습니다. 다만, try-catch 문도 써야하는 등등의 번거로움이 있었습니다. 그래서 이번 테스트에서는 이런 일들을 대신 해줄 라이브러리를 사용해보도록 하겠습니다. HttpHTTP 통신을 위한 라이브러리로는 OkHttp, Retrofit, Volley 가 있습니다. 그 중에서 오늘은 가장 많이 사용되고 안정적으로 사용이 가능한 Retrofit 을 사용해보도록 합시다.


라이브러리 추가하기

우리가 해야할 작업은 JSON 을 파싱해오는 작업입니다. 그래서 Json 을 파싱해올 때 필요한 Gson 라이브러리가 필요하며, 이번 테스트에서 사용해볼 Http 통신 라이브러리인 Retrofit, 그리고 이 두 라이브러리를 묶어줄 converter-gson 라이브러리가 필요합니다. 다음과 같이 dependencies 항목에 추가해봅시다.

dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

1. GET 방식으로 JSON 파싱해오기

Retrofit 의 사용법을 알아보기 위해 GET 방식을 활용하여 서버에 있는 JSON 문서를 파싱해오는 작업을 해봅시다. 또한 우리는 네트워크를 사용해야 하므로, 인터넷 퍼미션을 추가해줍시다. 또한 테스트를 위해 파싱해올 JSON 파일을 서버에 만들어 둡시다. JSON 파일 내용은 다음과 같습니다.

{"name":"sam","msg":"Hello World","age":10}

그리고 우리는 Retrofit 라이브러리를 사용하여 서버에서 json 파일을 읽어온 후, Item 객체로 곧바로 생성해줄 겁니다. 그래서 Item 클래스를 먼저 만들어 둡시다.

public class Item {
    String name;
    String msg;
    int age;

    public Item() {
    }

    public Item(String name, String msg, int age) {
        this.name = name;
        this.msg = msg;
        this.age = age;
    }
}

이 클래스의 멤버변수의 이름과 json 파일에 있는 식별자의 이름은 동일해야 합니다. 그래야 정상적으로 파싱해올 수 있습니다. 물론, 달라도 파싱해올 수 있게끔 설정을 할 순 있지만 현재 테스트의 의도와는 거리가 있기 때문에 이번 테스트에서는 이름을 맞춰주도록 합시다.

그럼 이제 Retrofit 을 사용할 사전 준비작업이 끝났습니다. 이제 Retrofit 을 한번 사용해봅시다. 이 라이브러리를 사용하기 위해서는 5개의 단계가 필요합니다. 하나씩 차근차근 알아봅시다.

1단계 : Retrofit 객체 생성

void clickBtn1(){
    Retrofit.Builder builder = new Retrofit.Builder();
    builder.baseUrl("http://tjdrjs0803.dothome.co.kr");
    builder.addConverterFactory(GsonConverterFactory.create());
    Retrofit retrofit = builder.build();
}
  • Retrofit.Builder builder = new Retrofit.Builder();
    Retrofit의 기능을 사용하기 위해서는 빌더의 기능이 필요하므로, 빌더 객체를 하나 생성합니다.

  • builder.baseUrl("http://tjdrjs0803.dothome.co.kr");
    빌더 객체에게 우리가 사용할 서버의 기본 주소까지만 줍시다. 추후에 Call 객체를 만들때, 세부적인 폴더명과 파일명을 전달할 수 있습니다.

  • builder.addConverterFactory(GsonConverterFactory.create());
    우리는 json 파일을 서버로 전송해야 하므로, Gson 라이브러리를 사용해야 합니다. 그리고 그러한 과정을 네트워크를 이용하여 해주어야 하며, 그 과정을 도와주는 라이브러리가 Retrofit 입니다. 그래서 이 두 라이브러리를 연결하기 위한 컨버터 객체가 필요하며, 빌더에게 컨버터 객체를 생성할 수 있는 Factory 를 요청할 수 있습니다. 파라미터로는 어떠한 종류의 Factory 를 만들지에 대한 정보를 전달해주어야 합니다. 우리는 Gson 을 이용할것이므로, GsonConverterFactory.create() 을 전달하였습니다.

  • Retrofit retrofit = builder.build();
    이제 빌더에게 Retrofit 객체를 생성해달라고 요청합시다.

2단계 : 인터페이스를 설계

public interface RetrofitService {
    @GET("Retrofit/board.json")
    Call<Item> getBoardJson(); 
}

Retrofit 이 내부적으로 어떠한 기능을 할지를 미리 설계해두어야 합니다. 그래서 설계도를 만들어주어야 하는데, interface 로 만들어주면 됩니다. 원하는 GET,POST 등의 동작을 어노테이션으로 지정해줄 수 있으며, 여기에 어떤 폴더의 어떤 파일을 가져올지 명시할 수 있습니다.

또한 추상메서드를 만들때에는 Call<Item> 인터페이스를 리턴타입으로 설정해주어야 합니다. 이러면, MainActivity 에서 메서드를 호출하여 받아올 때, Call<Item> 타입으로 받아올 수 있으며, 이 객체를 이용하여 서버에서 Json 이 잘 파싱되어 돌아왔는지 확인할 수 있습니다.

3단계 : RetrofitService 인터페이스 객체 생성

void clickBtn1(){

... 중략

    RetrofitService retrofitService = retrofit.create(RetrofitService.class);
}

인터페이스는 직접적으로 new 를 이용하여 객체를 생성할 수 없기 때문에, Retrofit 객체에게 객체생성을 요청해주어야 합니다. 내부적으로 Retrofit 객체는 인터페이스의 추상 메소드들의 구현을 하게 되어있습니다. 그래서 Retrofit 객체의 create() 메서드의 파라미터로 인터페이스의 클래스 정보를 넘겨주어야 합니다.

4단계 : Call 객체 리턴받기

앞서 만든 서비스 객체의 추상 메소드를 호출하여 실제 서버작업을 수행하는 Call 객체를 리턴받아옵시다.

void clickBtn1(){

... 중략 
    Call<Item> call = retrofitService.getBoardJson();
}

만들어진 RetrofitService 의 객체를 이용하여, Call<Item> 의 객체를 받아올 수 있습니다.

5단계 : 네트워크 작업 수행

4단계에서 리턴된 Call 객체에게 네트워크 작업을 요청합시다. Call 객체는 네트워크 작업을 비동기로 처리합니다.

void clickBtn1(){

... 중략
    call.enqueue(new Callback<Item>() {
        @Override
        public void onResponse(Call<Item> call, Response<Item> response) {

        }

        @Override
        public void onFailure(Call<Item> call, Throwable t) {

        }
    });
}

2. GET 방식으로 JSON 파싱해오기 By Path

1번에서는 GET 방식으로 JSON 을 파싱해올 때, 우리가 정한 폴더와 파일 이름을 명세서에 명시해두고 파싱해왔습니다. 이번 테스트에서는 명세서에 따로 명시하지 않고 메서드 호출시 파라미터로 어떤 파일을 파싱해올지를 결정해봅시다.

----------------- RetrofitService.java


public interface RetrofitService {

... 중략
    @GET("{aaa}/{bbb}")
    Call<Item> getBoardJsonByPath(@Path("aaa") String path,@Path("bbb") String file);
}

@GET 어노테이션의 파라미터로 변수를 주고, getBoardJsonByPath() 메소드의 파라미터에 @Path 어노테이션을 활용합시다. @Path 를 활용하면 각 변수의 식별자를 줄 수 있습니다.

----------------- MainActivity.java


void clickBtn2(){

    Retrofit.Builder builder = new Retrofit.Builder();
    builder.baseUrl("http://tjdrjs0803.dothome.co.kr");
    builder.addConverterFactory(GsonConverterFactory.create());
    Retrofit retrofit = builder.build();

    RetrofitService retrofitService = retrofit.create(RetrofitService.class);

    Call<Item> call = retrofitService.getBoardJsonByPath("Retrofit","board.json");

    call.enqueue(new Callback<Item>() {
        @Override
        public void onResponse(Call<Item> call, Response<Item> response) {
            Item item = response.body();
            binding.tv.setText(item.name +" " + item.msg + " " + item.age);
        }

        @Override
        public void onFailure(Call<Item> call, Throwable t) {
            binding.tv.setText("failure : " + t.getMessage());
        }
    });
}

3. GET 방식으로 서버에 값 전달하기

값을 전달하기 이전에 Retrofit 객체를 생성하는 방법을 좀 바꿔봅시다. RetrofitHelper 클래스를 하나를 만들고, 다음과 같이 Retrofit 객체를 만드는 기능을 가진 static 메소드 하나를 만들어둡시다.

public class RetrofitHelper {

    public static Retrofit getRetrofitInstance(){
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl("http://tjdrjs0803.dothome.co.kr");
        builder.addConverterFactory(GsonConverterFactory.create());
        return builder.build();
    }
}

이렇게 만들어두면 추후에 코드의 재활용이 가능할것이고 가독성 또한 좋아지게 됩니다. 그리고 Retrofit 사용을 위한 단계들을 거쳐 GET 방식으로 서버에 값을 전달해봅시다.

----------------- MainActivity.java


void clickBtn3(){
    String name = "홍길동";
    String message = "안녕하세요";
    int age = 20;

    Retrofit retrofit = RetrofitHelper.getRetrofitInstance();

    RetrofitService retrofitService = retrofit.create(RetrofitService.class);

    Call<Item> call = retrofitService.getMethodTest(name,message,age);
    call.enqueue(new Callback<Item>() {
        @Override
        public void onResponse(Call<Item> call, Response<Item> response) {
            Item item = response.body();
            binding.tv.setText(item.name + " " + item.msg + " " + item.age);
        }

        @Override
        public void onFailure(Call<Item> call, Throwable t) {
            binding.tv.setText("Failure : " + t.getMessage());
        }
    });

}

원래 같으면 EditText 등의 사용자 입력을 데이터로 해서 보내줘야 하지만, 테스트 목적이므로 단순 데이터로 사용했습니다. Retrofit 객체를 만들고 Retrofit 객체를 이용하여 RetrofitService 인터페이스의 객체를 생성해주었습니다.

그리고 인터페이스의 추상메서드를 이용하여 Call 객체를 만들어주어야 하므로, 인터페이스를 먼저 구축해줍시다.

----------------- RetrofitService.java


 @GET("Retrofit/getTest.php")
 Call<Item> getMethodTest(@Query("name") String name, @Query("msg") String message, @Query("age") int age);

@GET 어노테이션을 이용하여 데이터를 Retrofit 폴더의 getTest.php 파일에 전달하겠다고 선언해주었습니다. 또한 Call<Item> 을 리턴값으로 갖는 getMethodTest() 추상메서드를 만들어 주었습니다. 파라미터로는 name, message, age 를 전달하며, 각각의 파라미터에 @Query 어노테이션을 이용하여 식별자를 부여했습니다. 이래야 나중에 php 파일에서 받을 때 알맞게 받아올 수 있습니다.

인터페이스를 설계해두었으므로, Call 객체를 생성할 수 있게 됩니다. 만들어진 Call 객체를 이용하면 서버로 부터의 응답을 처리할 수 있습니다.

아래는 php 코드 입니다.

<?php
    header('Content-Type:application/json; charset=utf-8');

    $name = $_GET['name'];
    $message = $_GET['msg'];
    $age = $_GET['age'];

    $arr = array();

    $arr['name'] = $name;
    $arr['msg'] = $message;
    $arr['age'] = $age;

    echo json_encode($arr);
?>

4. GET 방식과 Map collection 을 이용하여 값 전달하기

----------------- MainActivity.java


void clickBtn4(){

    HashMap<String,String> datas = new HashMap<>();
    datas.put("name","robin");
    datas.put("msg","nice to meet you");

    Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
    RetrofitService retrofitService = retrofit.create(RetrofitService.class);
    Call<Item> call = retrofitService.getMethodTest2(datas);

    call.enqueue(new Callback<Item>() {
        @Override
        public void onResponse(Call<Item> call, Response<Item> response) {
            Item item = response.body();
            binding.tv.setText(item.name + " , "+item.msg);
        }

        @Override
        public void onFailure(Call<Item> call, Throwable t) {

        }
    });
}

데이터를 보내는 방식만 일반 String 변수에서 Map Collection 으로 달라졌을 뿐입니다. 다만, 앞선 테스트에서는 @Query 어노테이션을 이용하여 php 에서 식별자를 구분할 수 있도록 식별자를 지정해주었으나, Map Collection 을 사용하여 이미 식별자가 존재하기 때문에 어노테이션을 활용한 식별자 지정은 필요치 않습니다. 대신 Map Collection 을 사용할 때에는@QueryMap 어노테이션을 지정해주면 됩니다. 그리 어렵지 않으니 읽어보고 넘어갑시다.

----------------- RetrofitService.java


public interface RetrofitService {
... 중략
    @GET("Retrofit/getTest.php")
    Call<Item> getMethodTest2(@QueryMap Map<String,String> datas);
}

5. GET 방식으로 ArrayList 으로 받아오기

Json 배열로 이루어진 데이터를 받아올 때에는 ArrayList 로 받아올 수 있습니다. 앞선 코드들과 크게 다르지 않기 때문에 보고 넘어갑시다.

----------------- MainActivity.java


void clickBtn5(){
    Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
    RetrofitService retrofitService = retrofit.create(RetrofitService.class);
    Call<ArrayList<Item>> call = retrofitService.getJsonBoardArr();
    call.enqueue(new Callback<ArrayList<Item>>() {
        @Override
        public void onResponse(Call<ArrayList<Item>> call, Response<ArrayList<Item>> response) {
            ArrayList<Item> items = response.body();
            binding.tv.setText(items.size() + "");
        }

        @Override
        public void onFailure(Call<ArrayList<Item>> call, Throwable t) {

        }
    });
}
----------------- RetrofitService.java


@GET("Retrofit/boardArr.json")
Call<ArrayList<Item>> getJsonBoardArr();

아래는 php 코드 입니다.

[
    {"name":"robin", "msg":"Hello", "age":25},
    {"name":"sam", "msg":"Hello2", "age":45},
    {"name":"hong", "msg":"Hello3", "age":12}
]

6. GET 방식으로 String 으로 받아오기

Gson 을 사용하면, Json 데이터 형식으로 된 데이터들을 손쉽게 분류할 수 있습니다. 만일, Json 데이터를 String 으로 받아보고 싶다면, Gson 을 사용할 이유가 없어집니다. 그래서 우리가 빌더에게 Factory 객체를 만들어달라 요청했을 때 파라미터로 전달해주었던 GsonConverterFactory 대신 ScalarConverterFactory 를 전달해주어야 합니다.

추가로 이 ScalarConverterFactory 도 라이브러리를 추가해주어야 합니다.

----------------- MainActivity.java


void clickBtn6(){

    Retrofit.Builder builder = new Retrofit.Builder();
    builder.baseUrl("http://tjdrjs0803.dothome.co.kr");
    builder.addConverterFactory(ScalarsConverterFactory.create());
    Retrofit retrofit = builder.build();

    RetrofitService retrofitService = retrofit.create(RetrofitService.class);
    Call<String> call = retrofitService.getJsonString();
    call.enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            String s = response.body();
            binding.tv.setText(s);
        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {

        }
    });
}
----------------- RetrofitService.java


    @GET("Retrofit/board.json")
    Call<String> getJsonString();

7. POST 방식으로 객체 전송

이제 GET 방식으로 데이터 파싱과 전송은 해보았으니, POST 방식을 활용하여 Retrofit 을 사용해봅시다.

----------------- MainActivity.java


void clickBtn7(){
    Item item = new Item("kim","Good Afternoon",20);

    Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
    RetrofitService retrofitService = retrofit.create(RetrofitService.class);
    Call<Item> call = retrofitService.postMethodTest(item);

    call.enqueue(new Callback<Item>() {
        @Override
        public void onResponse(Call<Item> call, Response<Item> response) {
            Item i = response.body();
            binding.tv.setText(i.name + " " + i.msg + " " + i.age);
        }

        @Override
        public void onFailure(Call<Item> call, Throwable t) {

        }
    });
}

인터페이스의 설계부분만 확인해봅시다. 우리는 POST 방식을 활용해야 하므로, @POST 어노테이션을 이용해주었습니다. 또한 객체를 서버로 보낼 때는 @Body 를 이용해주어야 합니다. 추가적으로 php 에서 데이터를 받을 때에는 식별자가 필요했습니다. 이번 테스트에서는 그 식별자의 역할을 객체의 멤버변수가 대신하므로, 따로 식별자 지정이 필요치 않습니다.

----------------- RetrofitService.java


@POST("Retrofit/postTest.php")
Call<Item> postMethodTest(@Body Item item ); 

아래는 php 코드 입니다. php 파일에서 객체를 POST 방식으로 받아올 때에는&_POST 에 곧바로 저장되지 않으며, 임시 저장 공간인 php://input 에 저장됩니다. 그래서 file_get_contents 를 이용하여 데이터를 끄집어 내준후, json_decode()&_POST 에 다시 저장해준 후에 사용해야 합니다.

<?php
    header('Content-Type:application/json; charset=utf-8');
    
    $data = file_get_contents("php://input");
    $_POST = json_decode($data,true);
    
    $name= $_POST['name'];
    $message= $_POST['msg'];
    $age= $_POST['age'];

    $arr = array();
    $arr['name'] = $name;
    $arr['msg'] = $message;
    $arr['age'] = $age;
    
    echo json_encode($arr);
?>

8. POST 방식으로 단일 데이터 전송하기

----------------- MainActivity.java


void clickBtn8(){
    String name = "ROSA";
    String message = "Have a good day";
    int age = 25;

    Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
    RetrofitService retrofitService = retrofit.create(RetrofitService.class);
    Call<Item> call = retrofitService.postMethodTest2(name,message,age);

    call.enqueue(new Callback<Item>() {
        @Override
        public void onResponse(Call<Item> call, Response<Item> response) {
            Item item = response.body();
            binding.tv.setText(item.name + ", " + item.msg + ", " + item.age);
        }

        @Override
        public void onFailure(Call<Item> call, Throwable t) {

        }
    });
}

앞선 GET 을 사용한 테스트에서 @Query 어노테이션을 이용하여 단일 데이터들의 식별자를 구분해주었다면, POST 방식에서는 @Field 어노테이션을 이용하여 식별자를 구분해주어야 합니다. 단, @Field 어노테이션을 사용하기 위해서는 @FormUrlEncoded 어노테이션을 필수로 함께 사용해주어야 합니다.

----------------- RetrofitService.java


@FormUrlEncoded
@POST("Retrofit/postTest2.php")
Call<Item> postMethodTest2( @Field("name") String name, @Field("msg") String message, @Field("age") int age);

아래는 php 코드 입니다.

<?php
    header('Content-Type:application/json; charset=utf-8');
   
    $name= $_POST['name'];
    $message= $_POST['msg'];
    $age= $_POST['age'];

    $arr = array();
    $arr['name'] = $name;
    $arr['msg'] = $message;
    $arr['age'] = $age;
    
    echo json_encode($arr);
?>

HTTP 통신 라이브러리 : 이미지 업로드


라이브러리 추가

이미지를 서버에 업로드 하기 위해, 우리는 몇가지의 라이브러리를 추가시켜줘야 합니다. Gson , converter-gson, converter-scalars, glide, retrofit 라이브러리를 추가시켜 줍시다.

dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
    implementation 'com.github.bumptech.glide:glide:4.15.1'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

화면 구성

이미지 선택 버튼을 누르면, 사진 선택 Bottomsheet 로 부터 사진을 선택해올 수 있습니다. 사진이 선택되면, ImageView 에 선택된 사진이 띄워지며, 업로드 이미지 버튼을 누르면 선택된 사진을 서버에 업로드 할 예정입니다.

<LinearLayout ... 중략 >

    <Button
        android:id="@+id/btn_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/teal_700"
        android:text="이미지 선택"/>

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="300dp"/>
    <Button
        android:id="@+id/btn_upload"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:backgroundTint="#4A4A4A"
        android:text="업로드 이미지"/>
</LinearLayout>

사진 선택 기능 구현

예전에 한번 살펴보았던 사진 앱 내부 사진의 선택 기능 입니다. 그리 어렵지 않으니 넘어갑시다.

void clickSelect(){
    Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
    launcher.launch(intent);
}

ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),result -> {
    if(result.getResultCode() == RESULT_CANCELED) return;

    Uri uri = result.getData().getData();
    Glide.with(this).load(uri).into(binding.iv);
});


이제 우리는 이미지 업로드를 해주어야 합니다. 이미지 업로드와 관련한 코드들은 다음 포스팅에서 다시 다뤄야합니다. 일단은 코드 정도만 살짝 보고 넘어갑시다.

Uri -> 실제 파일 주소

우리의 최종 목적은 선택한 사진을 서버로 업로드 하는것입니다. 그러기 위해서는 Http 통신을 해주는 Retrofit 을 이용해주어야 하는데요, 안타깝게도, 우리가 Retrofit 으로 서버에 파일을 전송하기 위해서는 파일의 Uri, 즉 , 파일의 콘텐츠 주소가 아닌 파일의 실제 주소가 필요합니다. 그러기 위해서 우리는 앞서 구했던 파일의 Uri 를 파일의 실제 주소로 변환해주어야 합니다.

ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),result -> {
    if(result.getResultCode() == RESULT_CANCELED) return;

    Uri uri = result.getData().getData();
    Glide.with(this).load(uri).into(binding.iv);

    imgPath = getFilePathFromUri(uri);
});
String getFilePathFromUri(Uri uri){
    String[] projection = new String[]{MediaStore.Images.Media.DATA};
    CursorLoader loader = new CursorLoader(this,uri,projection,null,null,null);
    Cursor cursor = loader.loadInBackground();
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

이미지 업로드

void clickUpload(){
    Retrofit.Builder builder = new Retrofit.Builder();
    builder.baseUrl("http://tjdrjs0803.dothome.co.kr");
    builder.addConverterFactory(ScalarsConverterFactory.create());
    Retrofit retrofit = builder.build();

    RetrofitService retrofitService = retrofit.create(RetrofitService.class);

    File file = new File(imgPath);
    RequestBody body = RequestBody.create(MediaType.parse("image/*"),file);
    MultipartBody.Part part = MultipartBody.Part.createFormData("img",file.getName(),body);

    Call<String> call = retrofitService.uploadImage(part);
    call.enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            String s = response.body();
            new AlertDialog.Builder(MainActivity.this).setMessage(s).create().show();
        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {

        }
    });
}
profile
Developer

0개의 댓글