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/
여태것 뭐하다 이런걸 이제 알았나 싶다 ..
개념적으로 어려운건 아니지만 사실 이걸 지금 알았다는 내 자신을 돌아보는 계기가 되었다. 난 과연 개발자의 삶을 살려고 하는 것인가 'ㅅ'
여튼 짧게나마 포스팅 해보려 한다.
본론
참고
어떻게 맵핑 방식이 이뤄지는지 상세하게 나와있다. 내가 찾아본 사이트 중 가장 읽기도 좋고 설명도 잘 되어있어던 것 같다.
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] 갤러리 이미지 읽기, 쓰기 코드
할 때 마다 애매한 부분이 있어서 찾아보게 되는 고생을 덜기 위해 정리해 보았다 ;;
" "로 구분자를 넣은 이유는 split로 String 배열을 만들어 넘겨주기 위해서다.
requestPermissions의 인자값을 보면 permissions 이 String[] 으로 선언되어서 사용자의 여러 요청을 받을 수 있다.
사용자에게 요청을 해야 이미지를 비트맵으로 바꾸던가 해서 안드로이드 view에 설정할 수 있다.
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
한 노드를 탐색할 때 재귀적으로 탐색하여 마지막 노드 까지 내려갔다가 다시 위로 올라와서 시작한다.
Depth-First Search
방식 :
https://en.wikipedia.org/wiki/Depth-first_search#/media/File:Depth-First-Search.gif
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값이 아니라면 곤란하다.
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는 다른 포스팅에서 알아보자
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
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
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
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=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/
피드 구독하기:
글 (Atom)