1. 준비물

이미지 갤러리를 열 수 있게 버튼을 만들어서 가져오겠습니다.


        mGetImageFromGalleryButton = (ImageView) view.findViewById(R.id.btn_getgallery);
 
cs


여기에 setOnClickListener를 달아줍니다.


        mGetImageFromGalleryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            }
        });
cs


onClick() 안에 원하는 것을 채워주겠습니다.


2. 권한 획득 후 실행


                if(ActivityCompat.checkSelfPermission(getActivity(),
                        Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
                {
                    requestPermissions(
                            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                            2000);
                }
                else {
                    startGallery();
                }
cs


이렇게 하면 권한 획득을 구현하게 됩니다. 권한이 있으면 자동으로 startGallery() 함수를 호출합니다.

지금까지 구현한 코드의 마지막에 써줘야 할 것이 있습니다.


        return view;
cs


이렇게 마무리 해주지 않으면 코드가 정상적으로 작동하지 않습니다.

갤러리를 열 때 필요한 코드가 또 있습니다.


    private void startGallery() {
        Intent cameraIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        cameraIntent.setType("image/*");
        if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            startActivityForResult(cameraIntent, 1000);
        }
    }
cs


이 부분의 코드가 있어야 Intent를 이용해서 열 수 있습니다. Intent 는 새 화면이라고 생각하시면 됩니다.


1. 준비물

기본적인 구조는 다음과 같습니다.


            @Override
            public void onClick(View view) {
                if (returnUri != null) {
                    if (!mEditTextdialogOpenField.getText().toString().equals("")) {
                    }
                    else {
                        Snackbar.make(getView(), "You have to say any words", Snackbar.LENGTH_LONG).show();
                    }
                }
                else {
                    Snackbar.make(getView(), "You have to get any image from gallery", Snackbar.LENGTH_LONG).show();
                }
            }
cs


if 구문에 Snackbar를 등록한 형태입니다. 이제 이 안을 채울 것입니다. Dialog로부터 입력받은 텍스트가 존재하면 실행되는 구문입니다. 그렇지 않다면 Snackbar로 에러를 표시합니다.


2. 내용물


    
                        Bitmap bitmap = null;
                        try {
                            bitmap = getBitmapFromUri(returnUri);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
cs


이 것으로 비트맵을 가져옵니다. uri를 통해 비트맵을 열 수 있습니다. 비트맵은 그림파일이라고 생각하시면 됩니다.


                        File imageFile = null;
                        try {
                            imageFile = createFileFromBitmap(bitmap);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
cs


여기는 파일을 가져오는 부분을 구현했습니다. 이 파일을 이제 비동기통신으로 연결하겠습니다.

가져온 텍스트를 Retrofit에 실어주는 부분입니다. okHttpClient를 사용할 때엔 builder를 호출해서 생성해야 합니다. 그리고 interceptor()를 builder에서 호출하여 현재 activity의 view.getContext() 속성을 넣어줍니다.


                        String givenText = mEditTextdialogOpenField.getText().toString();
                        OkHttpClient client = new OkHttpClient();
                        OkHttpClient.Builder builder = new OkHttpClient.Builder();
                        builder.interceptors().add(new AddCookiesInterceptor(view.getContext()));
                        client = builder.build();
                        Retrofit retrofit = new Retrofit.Builder()
                                .client(client)
                                .addConverterFactory(GsonConverterFactory.create())
                                .baseUrl(Constants.BASE_URL)
                                .build();
cs


okHttpClient의 구현 방법에 주의하시기 바랍니다.

사전에 만들어 놓은 api 서비스가 있습니다. 이 api 서비스를 이용해서 사진을 다루겠습니다.


                        PostApiService postApiService = retrofit.create(PostApiService.class);
                        RequestBody requestFile =
                                RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
                        MultipartBody.Part body =
                                MultipartBody.Part.createFormData("image", makeImageFileName(), requestFile);
 
cs


좌표는 int혹은 string으로 다뤄질 수 있습니다. 이번엔 String 변수에 담겠습니다. 사용하실 때 편한 방법으로 값을 저장해두면 불러오거나 다시 저장할 때 유용합니다.


                        ReferSharedPreference preferenceCoordinates = new ReferSharedPreference(getContext());
                        final String lat = preferenceCoordinates.getValue("Lat", "13");
                        final String lon = preferenceCoordinates.getValue("Lon", "15");
                        String pointString = "{ \"longitude\": \""+lon+"\",     \"latitude\": \""+lat+"\" } ";
 
cs


Request할 Body 부분을 구현합니다. http통신이므로 request가 존재합니다.


                        RequestBody coordinatePoint =
                                RequestBody.create(
                                        MediaType.parse("multipart/form-data"), pointString);
                        RequestBody textToPost =
                                RequestBody.create(
                                        MediaType.parse("multipart/form-data"), givenText);
 
cs


이제 Retrofit를 이용해서 Call을 구현하면 됩니다. call은 서버에 요청하는 과정입니다.


                        Call<ResponseBody> call = postApiService.uploadFile(body, coordinatePoint, textToPost);
                        call.enqueue(new Callback<ResponseBody>() {
                            @Override
                            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                                Snackbar.make(getView(), "Success, posted at \n" + lat + "  , " + lon , Snackbar.LENGTH_LONG).show();
 
                            }
                            @Override
                            public void onFailure(Call<ResponseBody> call, Throwable t) {
                            }
                        });
cs


그 다음 ImageView를 정리합니다.


                        mImageview.setImageBitmap(null);
                        returnUri = null;
                        mEditTextdialogOpenField.setText("");
cs


이러면 전송 후 이미지뷰가 깨끗해집니다. 이미지가 계속 남아있으면 다음 요청시에 에러가 발생할 수 있기 때문입니다.

1. 준비물

Glide, 서비스할 API와 Model들을 가져옵니다.


import com.bumptech.glide.Glide;
import com.example.keepair.myapplication.apiservice.LoginApiService;
import com.example.keepair.myapplication.apiservice.PostApiService;
import com.example.keepair.myapplication.helper.Constants;
import com.example.keepair.myapplication.loginhelper.AddCookiesInterceptor;
import com.example.keepair.myapplication.loginhelper.ReferSharedPreference;
import com.example.keepair.myapplication.model.Point;
import com.example.keepair.myapplication.model.PostData;
cs


버터나이프를 쓸 것입니다. 버터나이프는 뷰를 가져올 때 편리한 도구입니다.

그리고 okhttp3를 써서 json 데이터를 다루기 편하게 할 것입니다.


import butterknife.Bind;
import butterknife.OnClick;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okio.BufferedSink;
cs


Retrofit를 이용해서 비동기통신을 구현할 것입니다. 

Retrofit : http://square.github.io/retrofit/

Retrofit 한글 번역 : http://devflow.github.io/retrofit-kr/


import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.POST;
cs


2. 레이아웃

레이아웃을 가져옵니다.


    ImageView mGetImageFromGalleryButton;
 
    ImageView mImageview;
    TextView mEditTextdialogOpenField;
    Uri returnUri;
cs


여러가지 View는 inflater를 이용해서 가져옵니다. 앞으로도 view를 가져올 땐 inflater의 inflate 함수를 이용할 것입니다.


        View view = inflater.inflate(R.layout.fragment_green, container, false);
        customImageview = (ImageView) view.findViewById(R.id.iv_beforesendpost);
        customEditTextdialogOpenField = (TextView) view.findViewById(R.id.tv_textToPost);
        setRetainInstance(true);
 
        mEditTextdialogOpenField.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openDialog();
            }
        });
cs


가져온 뷰에 각기 onClickListener를 달아줍니다. 레이아웃상의 버튼을 클릭하면 일정한 동작이 구현되게 할 수 있습니다.


        view.findViewById(R.id.btn_post).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            }
        }
cs


이렇게 하게 되면 기본적인 세팅이 완성됩니다.

Activity는 java android 프로그래밍에서 핵심이 되는 부분입니다. 이 부분에서 여러가지 프로그래밍적인 설정을 할 수 있습니다. 레이아웃과의 연동을 위해 우선은 (ImageView), (TextView) 등을 가져온 부분을 주의깊게 봐주시기 바랍니다.


다음 포스트에서 계속하겠습니다.

+ Recent posts