안드로이드 소켓 통신 (client 부분 : 데이터 송신, 수신)

프로그래밍/ANDROID|2021. 2. 3. 14:24
반응형

네트워크 작업은 스레드를 통해서만 동작 합니다.

thread 를 구성한 후 그 안에 try, catch 를 이용해 작성합니다.

 

        Thread t = new Thread(new Thread() {

            public void run() {

                StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

                StrictMode.setThreadPolicy(policy);
                StringBuffer sb = new StringBuffer();

                try {

                    InetAddress address = InetAddress.getByName("192.168.10.2"); // 서버 IP

                    Socket s = new Socket();
                    s.connect(new InetSocketAddress(address, 8888), 1000); // 서버 포트와 timeout

                    // 데이터 송신
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(s.getOutputStream())), true);
                    out.println("Send msg"); // 전송 메세지

                    // 데이터 수신
                    BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));

                    String str = null;
                    while((str = reader.readLine()) != null){
                        sb.append(str);
                    }
                    System.out.println("수신 내용 : " + sb.toString()); // 데이터를 String 형으로 출력
                    reader.close();

 

                } catch (UnknownHostException e) {

                    // nothing

                } catch (IOException e) {

                    // nothing

                } catch (Exception e) {

                    // nothing

                }

            }

        });

        t.start();

 

 

thread 안에서 toast 를 이용하여 결과를 간단히 출력하고 싶은 경우 아래 포스팅을 참고합니다.

https://sysdocu.tistory.com/1608

 

 

 

반응형

댓글()

안드로이드 Date 날짜 비교하기

프로그래밍/ANDROID|2021. 2. 2. 12:35
반응형

 

아래와 같은 형식으로 사용합니다.

Date date1, date2;

String last_checktime = "2021-02-01 10:20:30";

String checktime = "2021-02-01 10:20:35";

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 형식은 String 과 맞추면 yyyy-MM-dd 형식도 상관없음


try {

    date1 = dateFormat.parse(last_checktime);

    date2 = dateFormat.parse(checktime);

    int compare = date1.compareTo(date2);

    if (compare < 0) { 

        // date2 가 date1 보다 큰 경우 처리할 부분

    }

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

 

반응형

댓글()

스레드 (thread) 가 종료되기까지 기다리기

프로그래밍/ANDROID|2021. 1. 26. 16:33
반응형

thread 를 사용하면 작업을 백그라운드로 돌려 호출되는 페이지의 처리속도를 높일 수 있는 장점이 있습니다.

하지만 불가피하게 소스를 순차적으로 처리해야 할 경우에는 아래와 같이 thread 를 기다렸다가 완료되면 계속 진행하도록 할 수 있습니다.


Thread t = new Thread(new Runnable() {

    @Override

    public void run() {

        // 처리할 내용

    }

});

t.start(); // thread 시작


try { 

    t.join();  // thread 종료를 기다렸다가 진행

} catch (InterruptedException e) { 

    e.printStackTrace(); 



반응형

댓글()

스레드 (thread) 안에서 toast 사용하기

프로그래밍/ANDROID|2021. 1. 26. 14:22
반응형

우선 class 내에 아래 내용을 작성 합니다.


    public void postToastMessage(final String message) {

        Handler handler = new Handler(Looper.getMainLooper());

        handler.post(new Runnable() {

            @Override

            public void run() {

                Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();

            }

        });

    }



그다음 스레드 (thread) 안에서 아래와 같은 코드로 사용하면 됩니다.

postToastMessage("test"); // 'test' 라는 문자가 toast 로 출력



[출처] https://stackoverflow.com/questions/3134683/how-do-you-display-a-toast-from-a-background-thread-on-android



반응형

댓글()

안드로이드 스레드 (thread) 예제 - http 응답 코드 확인하기

프로그래밍/ANDROID|2021. 1. 25. 16:35
반응형

사이트 접속 코드가 들어가면 순차 처리 도중 화면이 잠깐 멈추는 것 같은경우가 발생하여

가 되지 않고, 작업을 백그라운드로 처리하여 화면 멈춤 현상이 없어지게 됩니다.

다만 화면과 동기화 되는 toast 작업 등은 처리되지 않는것 같아, preferences 에 처리값 입력 되는 것이 감지될때 꺼내오는 식으로 처리해야 할 것 같습니다.

(toast 결과를 보려면 다시 호출)



        // pref 준비

        final SharedPreferences pref = getDefaultSharedPreferences(this);

        final SharedPreferences.Editor edit = pref.edit();


        int bb = pref.getInt("test", 0);

        Toast.makeText(getBaseContext(), "결과 코드 : " + bb, Toast.LENGTH_SHORT).show();


        // thread 내용

        t = new Thread(new Thread(){

            private int aa; // 스레드 내에서 정의된 변수는 사용시 모두 앞에 this. 를 붙여줘야 함

            private URL url;

            private HttpURLConnection connection = null;

            @Override

            public void run() {

                try {

                    this.url = new URL("http://sysdocu.tistory.com");

                    this.connection = (HttpURLConnection) this.url.openConnection();

                    this.aa = this.connection.getResponseCode(); // http 응답 코드 넣기

                } catch (IOException e) {

                    e.printStackTrace();

                    this.aa = 999; // 접속 불가시 임의의 값

                }

                edit.putInt("test", this.aa); // preferences 에 값 저장

                edit.commit();

            }

        });


        t.start();



작업이 끝나면 자연스레 종료되지만, 수동으로 종료하고자 할 경우 아래 코드를 사용합니다.


t.interrupt();




반응형

댓글()

Failed to install the following Android SDK packages as some licences have not been accepted. 에러 해결

프로그래밍/ANDROID|2021. 1. 25. 14:39
반응형

안드로이드 스튜디오를 새로 설치한 후 기존의 프로젝트를 불러올 경우 빌드시 아래와 같은 에러 메세지가 출력될 때가 있습니다.



[에러]

Failed to install the following Android SDK packages as some licences have not been accepted.



[해결]

안드로이드 스튜디오 메뉴 File > Settings > 출력창에서 Appearance & Behavior > System Settings > Android SDK 에서


[SDK Platforms] 탭에서 필요한 버전의 플랫폼 설치하고

[SDK Tools] 탭에서 Google Play licensing Library 를 설치해 줍니다.



그리고 빌드하면 정상 처리되는 것을 볼 수 있습니다.


반응형

댓글()

안드로이드 Sound Play 사운드 재생

프로그래밍/ANDROID|2021. 1. 21. 09:08
반응형

안드로이드 사운드 재생 방법입니다.

1. SoundPool
2. MediaPlayer

차이점이라면

SoundPool  알림사운드,게임효과등 짧은 사운드클립에 적합하고
MediaPlayer  노래와 같이 더  사운드파일을 재생할 때 적합합니다.

 

1. SoundPool 로 재생하는 방법

우선 res > raw 폴더에 sound file 을 넣습니다. (모두 소문자로! 대쉬(-)는 언더바(_)로 바꾸고)

raw 폴더가 없다면 res 에서 우클릭 -> new -> Directory 클릭 해서 raw 폴더를 만듭니다.

그럼 이제 sound play 를 위한 class를 하나 생성합니다.

MySoundPlayer.java

package ai.vdotdo.hellobryan_test;

import android.content.Context;
import android.media.AudioAttributes;
import android.media.SoundPool;

import java.util.HashMap;

public class MySoundPlayer {
	public static final int DING_DONG = R.raw.sound_dingdong;
	public static final int SUCCESS = R.raw.success;

	private static SoundPool soundPool;
	private static HashMap<Integer, Integer> soundPoolMap;

	// sound media initialize
	public static void initSounds(Context context) {
		AudioAttributes attributes = new AudioAttributes.Builder()
				.setUsage(AudioAttributes.USAGE_GAME)
				.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
				.build();
		soundPool = new SoundPool.Builder()
				.setAudioAttributes(attributes)
				.build();

		soundPoolMap = new HashMap(2);
		soundPoolMap.put(DING_DONG, soundPool.load(context, DING_DONG, 1));
		soundPoolMap.put(SUCCESS, soundPool.load(context, SUCCESS, 2));
	}

	public static void play(int raw_id){
		if( soundPoolMap.containsKey(raw_id) ) {
			soundPool.play(soundPoolMap.get(raw_id), 1, 1, 1, 0, 1f);
		}
	}
}

SoundPool 은 Builder 를 이용해서 생성해야 합니다.

참고) new SoundPool(maxStreams, streamType, srcQuality); 로 생성하는 방식은 api21 이후에 deprecated 됐습니다.

 

사용하려는 Activity 에서는

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

		MySoundPlayer.initSounds(getApplicationContext());

		findViewById(R.id.button).setOnClickListener((v)->{
			MySoundPlayer.play(MySoundPlayer.DING_DONG);
		});
	}

MySoundPlayer.initSounds(getApplicationContext()); 로 초기화 하고

사용할 땐 
MySoundPlayer.play(MySoundPlayer.DING_DONG); 
또는

MySoundPlayer.play(MySoundPlayer.SUCCESS);

하면 됩니다.

 

2. MediaPlayer 사용.

MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_dingdong); 
mediaPlayer.start();

간단하쥬?

MediaPlayer 는 사운드 외에 동영상도 재생합니다. 

 

상황에 맞게 SoundPool 과 MediaPlayer 를 사용하시면 됩니다.


[출처] https://hello-bryan.tistory.com/83

반응형

댓글()

setImageResource 에 변수를 이용해 적용하기

프로그래밍/ANDROID|2021. 1. 20. 09:39
반응형

아래와 같이 배열을 사용하여 런타임에 이미지를 설정할 수 있습니다.


int[] images = new int[2];

images[0] = R.drawable.image1;

images[1] = R.drawable.image2;


lv.setImageResource(images[i]);



상태에 따라 배열 번호를 변경하고 싶을 경우, 배열 번호를 변경하지 않고 이미지 파일명을 변경하여 적용하면 됩니다.


int[] images = new int[1];

if (check_data.equals("first")) {

    images[0] = R.drawable.image1;

} else {

    images[0] = R.drawable.image2;

}


lv.setImageResource(images[0]);



[출처] https://stackoverflow.com/questions/5760751/android-variable-passed-for-r-drawable-variablevalue

반응형

댓글()

안드로이드에서 서버 포트 열려 있는지 확인하기 (포트 체크)

프로그래밍/ANDROID|2021. 1. 18. 15:16
반응형
안드로이드(자바)에서 포트가 열려 있는지 확인하는 두가지 간단한 방법입니다.
timeout 을 포함 방법입니다.

    Public String result;


        // onCreate 안에 넣기

        // thread 안에 넣어주고, 결과를 출력하기 위해 하단에서 처리되기를 기다립니다.

        Thread t = new Thread(new Runnable() {

            @Override

            public void run() {

                startScan();

            }

        });

        t.start();


        // 스레드 종료 기다리기

        try {

            t.join();

        } catch (Exception e) {

            e.printStackTrace();

        }


        Toast.makeText(getBaseContext(), "결과 : " + result, Toast.LENGTH_SHORT).show();



    // onCreate 바깥에 두기

    private void startScan() {

        result = "close"; // 기본값 (포트 접근되지 않을 경우)

        try {

            Socket socket = new Socket();

            socket.connect(new InetSocketAddress("8.8.8.8", 53), 1000);

            result = "open"; // 포트 접근 될 경우 값 변경

            socket.close();

        } catch (IOException e) {

        }


    }



아래는 다른 블로그에서 가져온 방법입니다.

availablePort 함수를 위와 같이 만들고 함수를 호출해서 
리턴 값으로 결과를 확인하면 됩니다.

boolean portCheck = availablePort("192.168.2.10", 80); // 체크할 서버 IP (String) 와 포트 (Int)

 

if (portCheck) {

    System.out.println("Open"); // 결과 메세지

} else {

    System.out.println("Close"); // 결과 메세지



public boolean availablePort(String host, int port) {

    boolean result = false;

 

    try {

        (new Socket(host, port)).close();

        result = true;

    }

    catch(Exception e) {

    }


    return result;

}


[출처] https://sinwho.tistory.com/entry/JAVA-%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-%ED%8F%AC%ED%8A%B8-%EC%97%B4%EB%A0%A4-%EC%9E%88%EB%8A%94%EC%A7%80-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0

반응형

댓글()

안드로이드 제스처 이벤트 (GestureDetector) 예제

프로그래밍/ANDROID|2021. 1. 5. 07:47
반응형

화면을 손으로 드래그시 이동 방향에 따라 이벤트가 발생하도록 하는 것이 제스처 이벤트 입니다.

아래 java 파일을 만들고 사용하고자 하는곳에서 불러오면 됩니다.



OnSwipeTouchListener.java


import android.content.Context;

import android.view.GestureDetector;

import android.view.GestureDetector.SimpleOnGestureListener;

import android.view.MotionEvent; import android.view.View;

import android.view.View.OnTouchListener;


public class OnSwipeTouchListener implements OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener (Context ctx){

        gestureDetector = new GestureDetector(ctx, new GestureListener());

    }


    @Override

    public boolean onTouch(View v, MotionEvent event) {

        return gestureDetector.onTouchEvent(event);

    }


    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;

        private static final int SWIPE_VELOCITY_THRESHOLD = 100;


        @Override

        public boolean onDown(MotionEvent e) {

            return true;

        }


        @Override

        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

            boolean result = false;

            try {

                float diffY = e2.getY() - e1.getY();

                float diffX = e2.getX() - e1.getX();

                if (Math.abs(diffX) > Math.abs(diffY)) {

                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {

                        if (diffX > 0) {

                            onSwipeRight();

                        } else {

                            onSwipeLeft();

                        }

                    }

                    result = true;

                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {

                    if (diffY > 0) {

                        onSwipeBottom();

                    } else {

                        onSwipeTop();

                    }

                }

                result = true;

            } catch (Exception exception) {

                exception.printStackTrace();

            }

            return result;

        }

    }


    public void onSwipeRight() { }


    public void onSwipeLeft() { }


    public void onSwipeTop() { }


    public void onSwipeBottom() { }


}



필요한 Activity 에서 아래 코드를 이용해 사용 합니다.


View v_swipe = (View) findViewById(R.id.v_swipe);


v_swipe.setOnTouchListener(new OnSwipeTouchListener(DetailsActivity.this) {

            public void onSwipeRight() {

                // 왼쪽에서 오른쪽으로 제스쳐 사용시 동작할 코드 넣기

            }

            public void onSwipeLeft() {

                // 오른쪽에서 왼쪽으로 제스쳐 사용시 동작할 코드 넣기

            }

            public void onSwipeTop() {

                // 아래에서 위쪽으로 제스쳐 사용시 동작할 코드 넣기

            }

            public void onSwipeBottom {

                // 위에서 아래쪽으로 제스쳐 사용시 동작할 코드 넣기

            }

        }); 



반응형

댓글()

안드로이드 소프트 키보드 숨기기

프로그래밍/ANDROID|2021. 1. 3. 18:32
반응형

View view = this.getCurrentFocus();

if (view != null) {  

    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);

}



반응형

댓글()