2020년 11월 10일 화요일

임시테스트

 


2020년 6월 27일 토요일

[Android] firebase database 데이터 삭제 방법

firebase Database 데이터 삭제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Query query =databaseReference.child("message").orderByChild("userName").equalTo(editTextName.getText().toString());
                query.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        for(DataSnapshot ds:dataSnapshot.getChildren()){
                      Log.d("getKey",ds.getRef().toString());
                            ds.getRef().removeValue();
                            //Toast.makeText(MainActivity.this, dataSnapshot.getKey().toString(), Toast.LENGTH_SHORT).show();
                        }

                    }
                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
                    }
                });
cs




equalTo를 이용하여 userName값이 "temp"인지 확인합니다.
snapshot은 말 그대로 한 순간이죠. 여기엔 쿼리(위에서 언급한 equalTo..)에 맞는 특정 데이터 값이 들어있습니다. 
꼭 dataSnapshot.getChildren() 를 하고서 참조로 접근해야 합니다.
그냥 참조로 냅다 접근해서 삭제하면 Tree 방식으로 이루어져 있기 때문에 전부 삭제될 수 있습니다.

2020년 6월 25일 목요일

Java -> POJO ,POJO -> Java

서론 개소리
여태것 뭐하다 이런걸 이제 알았나 싶다 ..
개념적으로 어려운건 아니지만 사실 이걸 지금 알았다는 내 자신을 돌아보는 계기가 되었다. 난 과연 개발자의 삶을 살려고 하는 것인가 'ㅅ'
여튼 짧게나마 포스팅 해보려 한다.


본론






참고
어떻게 맵핑 방식이 이뤄지는지 상세하게 나와있다. 내가 찾아본 사이트 중 가장 읽기도 좋고 설명도 잘 되어있어던 것 같다.
http://tutorials.jenkov.com/java-json/jackson-objectmapper.html

http://tutorials.jenkov.com/java-json/jackson-annotations.html

상세한 작동 원리 이런거 보다는 간단한 이해와 사용법만 알고 싶다면 아래 사이트를 추천한다.
https://www.geeksforgeeks.org/convert-java-object-to-json-string-using-jackson-api/

혹시 찾고 있을지 모르는 사용자에게  Json에서 ->object 과정을 프리뷰 할 수 있는 사이트를 첨부한다.
http://www.jsonschema2pojo.org/

2020년 6월 24일 수요일

[Android] firebase Image Upload (이미지 업로드하기 )


어제 해본거라 이 글을 작성한 날짜 기준으로는 deprecate된 것도 없고 작동 아주 잘 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void uploadImage() {
        if(fileUri != null)
        {
            final ProgressDialog progressDialog = new ProgressDialog(this);
            progressDialog.setTitle("이미지 업로드...");
            progressDialog.show();
            //UUID 기기식별 firebase 폴더/파일명
            StorageReference ref = storageReference.child("images/"+ UUID.randomUUID().toString());
            //파일입력
            ref.putFile(fileUri)
                    .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            progressDialog.dismiss();
                            Toast.makeText(MainActivity.this"업로드 완료", Toast.LENGTH_SHORT).show();
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            progressDialog.dismiss();
                            Toast.makeText(MainActivity.this"업로드 실패 "+e.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    })
                    .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                            double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
                                    .getTotalByteCount());
                            progressDialog.setMessage("Uploaded "+(int)progress+"%");
                        }
                    });
        }
    }
cs

fileUri  파일 URI같은 경우에는 함수 밖에서 설정 하였다.

ProgressDialog  Toast 매세지와 비슷하게 현재 진행상황을 표시하여 유저가 현 상황을 인식하도록 할 수 있다.
OnProgressListener ControllableTask 가 기능을 수행될 때 호출된다.
그러면 ControllableTask 뭘까 비동기적 운용을 표현해준다. 밑에를 보면 멈춤,취소와 같은 제어적 표현을 비동직적으로 나타낸다라고 되어있다. 이름 그대로 제어할 수 있는 기능을 갖췄다 라고 알아두고 넘어가려구 한다. 
(Represents an asynchronous operation that can be paused, resumed and canceled. This task also receives progress and other state change notifications.)


  • UploadTaskSnapshot   uploadTast에서 작동중인 상황을 transferred와 TotalByte를 통해 가져올 수 있다. 그 외의 메소드 2개가 더 있는데 궁금하면 참고에 사이트가 있으니 들어가 보자.
  • 혹여나 이렇게 해놓고 파일 URI도 완벽하게 가져오는데 안된다면 Toast 메세지를 확인해보라 필자의 경우 권한 인증(구글로그인, 익명로그인 등)을 안해줘서 거부당했으니  


참고
https://firebase.google.com/docs/storage/android/upload-files?hl=ko
https://firebase.google.com/docs/reference/android/com/google/firebase/storage/UploadTask.TaskSnapshot

[Android] 갤러리 이미지 읽기, 쓰기 코드

할 때 마다 애매한 부분이 있어서 찾아보게 되는 고생을 덜기 위해 정리해 보았다 ;;



1
2
3
4
5
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
       temp += Manifest.permission.READ_EXTERNAL_STORAGE + " ";
   }
   if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
       temp += Manifest.permission.WRITE_EXTERNAL_STORAGE + " "; }
cs

 " "로 구분자를 넣은 이유는 split로 String 배열을 만들어 넘겨주기 위해서다.
requestPermissions의 인자값을 보면 permissions 이 String[] 으로 선언되어서 사용자의 여러 요청을 받을 수 있다. 

public static void requestPermissions(final @NonNull Activity activity,        final @NonNull String[] permissions, final @IntRange(from = 0) int requestCode)


1
2
3
4
  if (TextUtils.isEmpty(temp) == false)
       {//split는 특정 구분문자를 중심으로 배열로 바꿔준다.
           ActivityCompat.requestPermissions(this, temp.trim().split(" "),1);
       }
cs

사용자에게 요청을 해야 이미지를 비트맵으로 바꾸던가 해서 안드로이드 view에 설정할 수 있다. 

2020년 6월 6일 토요일

[알고리즘] 깊이 탐색 알고리즘

깊이 탐색 알고리즘 이란 ?
한 노드를 탐색할 때 재귀적으로 탐색하여 마지막 노드 까지 내려갔다가 다시 위로 올라와서 시작한다.

Depth-First Search
방식 :
https://en.wikipedia.org/wiki/Depth-first_search#/media/File:Depth-First-Search.gif


[자료구조] 그래프 자료구조

https://gmlwjd9405.github.io/2018/08/15/algorithm-bfs.html

2020년 6월 3일 수요일

[Kotlin] if-else 조건문

kotlin의 if - else 조금은 생소하다.

val num:Int =10;
    val temp:Int = if(num>5){
        println("num은 5보다 크지")
        num
    }else{
        println("num은 5보다 작다")
        -1
    }
    println(temp.toString())

우선 출력 결과
num은 5보다 크지 
10
이렇게 출력된다.

if-else 구문에서 println 밑에 num이 있다. if문이나 else에 해당하는 경우 밑에 있는 값이 temp의 값이 된다. 만약 ,
println("num은 5보다 크지")
        num
println("메롱")

이렇게 된다면 어떻게 될까 , 보기 좋게 에러가 출력되었다. ㅇㅅㅇ

temp를 Int로 선언하였기에 Int값이 아니라면 곤란하다.

2020년 6월 1일 월요일

[Kotlin] 변수선언

변수선언 

val num:Int =0
val str:String ="abd"

변수 : 변수식별자 

    val num1:Int = 3
    var num2:Int = 4
    
    println(num1.toString());

    println(num2.toString());

출력 결과
3
4

그렇다면 val과 var 차이는 무엇일까
val은 read Only 즉, 읽기만 가능하다 변경 불가능
var 일반 변수

https://try.kotlinlang.org/#/Examples/Hello,%20world!/Simplest%20version/Simplest%20version.kt
해당 페이지로 가서 Convert From Java 에
int a
final int a
를 입력하면 결과가 출력된다.
var a:Int = 0
val a:Int = 0

결국 , 어떠한 의미에서는 상수라는건데 , const가 존재한다.
 val과 const는 다른 포스팅에서 알아보자


[Android] Handler 사용 Memory Leak


내부 클래스 Inner Class
외부 클래스 Outer Class
Static의 개념을 알아야 한다.

Handler mHandler = new Handler(); mHandler.postDelayed(new Runnable() { public void run() {             Do Something } }, 1000);

기능은 다양하게 사용되겠지만 UI 변경을 위해 많이 사용합니다.
그냥 생각없이 사용하다가 이런 사용법은 메모리 누수가 된다는 것을 알아버렸다..
사실 Activity 생명주기가 끝나면 끝나겠지 했는데 , 잘 생각해보면 Handelr의 메세지는 메모리 큐 라는 곳으로 향합니다. 메인쓰레드에서 UI 처리를 당하기 위해서죠.
그런데 내부 클래스인 Handelr




참고
https://medium.com/@joongwon/android-memory-leak-%EC%82%AC%EB%A1%80-6565b817a8fe
https://m.blog.naver.com/yoonhok_524/221724647242

http://gp.styx.link/

http://gp.styx.link/

2020년 5월 31일 일요일

[정보처리기사] 주요 보안약점 조치방안


AttributeSet attrs

참고 :
https://gun0912.tistory.com/38
https://stackoverflow.com/questions/5316686/what-is-attributeset-and-how-can-i-use-it
https://gogorchg.tistory.com/entry/Android-CustomView%EC%97%90-Attribute-%EB%A7%8C%EB%93%A4%EA%B8%B0

2020년 5월 30일 토요일

Activity 스택 어떻게 해야할까



참고: https://m.blog.naver.com/PostView.nhn?blogId=estern&logNo=220012629594&proxyReferer=https:%2F%2Fwww.google.com%2F

Parcel 어떻게 해야 하나

참고
https://milkissboy.tistory.com/34
https://stackoverflow.com/questions/7181526/how-can-i-make-my-custom-objects-parcelable
https://stackoverflow.com/questions/42436012/how-to-put-the-arraylist-into-bundle

2020년 5월 29일 금요일

android progress bar 원형으로 setProgress 설정


progress bar ?

어떠한 작업을 수행할 시 기다려야 하는 하나의 표시로서 나타낼 수 있고, 퍼센트지로 작업 완료시점을 알릴 수 있습니다.


저는 XML을 통해서가 아닌 자바코드를 사용해서 레이아웃에 추가해보도록 하겠습니다.


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);   
    setContentView(R.layout.activity_main);   
    ProgressBar pg = new ProgressBar(getApplicationContext(),null       
     ,android.R.attr.progressBarStyleLarge);  
    ViewGroup layout = findViewById(R.id.linearLayout);   
    layout.addView(pg);
}


이렇게 하면 뺑글뺑글 돌아갑니다.
이렇게 선언 하시면 가장 기본적인 모션으로 돌아가는 것 같습니다.
@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    ProgressBar pg = new ProgressBar(getApplicationContext(),null            ,android.R.attr.progressBarStyleLarge);
    pg.setMax(100);
    pg.setProgress(50);
    LinearLayout layout = (LinearLayout)findViewById(R.id.linearLayout);    layout.addView(pg);}
Max와 Progress 를 설정했지만 위 영상과 같이 열심히 돌아기만 합니다.

하지만 돌아가는 모션이 아닌 상황에 따라 달라지게 할 수 없을까요 ?
setProgress 설정과 똑같이 적용될 수 있도록 말이죠. 



protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);   
 ProgressBar pg = new ProgressBar(getApplicationContext(),null       
     ,android.R.attr.progressBarStyleHorizontal);  
 // pg.set    ViewGroup layout = findViewById(R.id.linearLayout);   
 layout.addView(pg);}

Large -> Horizontal 로 변경했습니다. 
이렇게 하면 setProgress 설정이 반영되어 채워지게 됩니다.
하지만!! 이렇게 하면 원형이 아닌 일직선으로 스타일이 변경이 됩니다
원으로 하고싶은데..;;



drawable 폴더에 이름의 자유롭게 xml 파일로 하나 만들어주세요
저는 progressbar_ring으로 만들었습니다.

<shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="ring"    android:innerRadiusRatio="2.5"    android:thickness="5dp"    android:useLevel="true">    <solid android:color ="@color/colorAccent"></solid>
</shape>

shape = "ring" 과 함께
링 비율과 링을 이루는 두께를 설정합니다.

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    ProgressBar pg = new ProgressBar(getApplicationContext(),null            ,android.R.attr.progressBarStyleHorizontal);    pg.setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_ring,null));    pg.setProgress(100);    pg.setProgress(50);    LinearLayout layout = (LinearLayout)findViewById(R.id.linearLayout);    layout.addView(pg);}

Drawable 폴더에 생성한 xml 파일을 설정해주세요. 그리고 이대로 실행하면 화면이 짤려 보일거에요.
그래서 Layout 설정을 했습니다
짤려보이신다면 아래와 같이 설정해주세요 

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    ProgressBar pg = new ProgressBar(getApplicationContext(),null            ,android.R.attr.progressBarStyleHorizontal);    pg.setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_ring,null));
    LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(200,200);
    pg.setLayoutParams(params);
    pg.setProgress(100);    pg.setProgress(50);    LinearLayout layout = (LinearLayout)findViewById(R.id.linearLayout);    layout.addView(pg);}

LinearLayout.LayoutParams(200,200);

200,200 은 폭과 넓이를 의미합니다 

참고 : https://www.youtube.com/watch?v=FCScsD0ZzOg
https://www.youtube.com/watch?v=hSfN_aYKkzo

2020년 5월 27일 수요일

php 이미지 전송

Transition<? super Bitmap> 
무슨 뜻일까 

Glide.with(context)
        .asBitmap()
        .load(drawURL)
        .into(new CustomTarget<Bitmap>() {
            @Override            public void onResourceReady(Bitmap resource,  @Nullable Transition<? super Bitmap>  transition) {
                // Do something with the Drawable here.                           }

            @Override            public void onLoadCleared(@Nullable Drawable placeholder) {
                // Remove the Drawable provided in onResourceReady from any Views and ensure                // no references to it remain.            }
        });

2020년 5월 26일 화요일

Glide

Glide란?

  • 이미지 로딩 라이브러리이다. 
  • API를 사용하여 쉽게 조작할 수 있다. 

우선 build.gradle 안에 
implementation 'com.github.bumptech.glide:glide:4.9.0'                                                                              annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'


Glide.with(this)
    .load(url)
    .into(imageView);

간단하게 사용하는 방법을 위에 있는 문장을 사용하여 괄호() 안에만 넣어주면 된다.                     자동적으로 다운샘플링 되기 때문에 이미지 사이즈를 줄여서 저장하게 된다. 
여기서 궁금한 점! 대부분의 글이나 이미지를 불러온다면 open 을 명시해주고 close로 닫아준다. 과연 우리의 Glide는 어떤 방법을 써야할까 .
Glide.with(fragment).clear(imageView);
이렇게 사용해야겠지만                                                                    this에 대한 Activity가 destroy 될 때 , 자동으로 clear 된다. 
이 밑에 부터는 제가 필요한 것만 정리해 놓았습니다.

Background Threads

FutureTarget<Bitmap> futureTarget =
  Glide.with(context)
    .asBitmap()
    .load(url)
    .submit(width, height);

Bitmap bitmap = futureTarget.get();

// Do something with the Bitmap and then when you're done with it:
Glide.with(context).clear(futureTarget);

에러처리를 요청으로 

Glide.with(fragment)
  .load(primaryUrl)
  .error(
      Glide.with(fragment)
        .load(fallbackUrl))
  .into(imageView);

Option 적용 

RequestOptions options = 
    new RequestOptions()
      .set(MyCustomModelLoader.TIMEOUT_MS, 1000L);

Glide.with(context)
  .load(url)
  .apply(options)
  .into(imageView);

참고:https://bumptech.github.io/glide/




© 특히하고 특별한
Maira Gall