2020년 11월 17일 화요일

Using SharedPreference, Android

앱을 개발하면서 간단한 사용자의 설정 정보 또는 무겁지 않은 데이터를 저장할때 사용하면 유용합니다.

저장된 데이터는 앱을 삭제하거나 앱 데이터를 삭제하면 지워지는 데이터 이므로 저장하려는 데이터를 어디에 저장할것인 잘 판단해야 합니다.

데이터 저장
setString(key, value);
setInt(key, value);
setLong(key, value);
setFloat(key, value);
setBoolean(key, value);

데이터 조회
getString(key);
getInt(key);
getLong(key);
getFloat(key);
getBoolean(key);

데이터 삭제(key사용)
remove(key);

전체 데이터 삭제
clear();

Class로 만들어 사용하면 편리합니다.


Context.MODE_PRIVATE
앱내부에서만 사용, 외부에서 접근불가

Context.MODE_WORLD_READABLE
앱외부에서 읽기 가능 API17부터는 보안문제로 인해 Deprecation됨

Context.MODE_WORLD_WRITEABLE
앱외부에서 쓰기 가능 API17부터는 보안문제로 인해 Deprecation됨

2020년 8월 31일 월요일

JavaScript, Array.some(), Array.every()

 Array.every(callbackfn: (value: T, index: number, array: T[]) => unknow, thisArg?: any): boolean

    const array = ['A''B''C''D''E'];

    // result : false
    const result = array.every(item => item === 'C');

Array.every()는 배열의 모든 항목이 조건과 일치해야 true를 반환한다.


Array.some(callbackfn: (value: T, index: number, array: T[]) => unknow, thisArg?: any): boolean

    const array = ['A''B''C''D''E'];

    // result : true
    const result = array.some(item => item === 'C');

Array.some()은 배열의 항목중 하나라도 조건과 일치 하면 true를 반환한다.


JavaScript, Array.slice, Array.Splice 비교

Array.slice(start?: number, end?: number): T[];

    const array = [12345];

    // 인자값을 넘기지 않으면 array배열을 반환한다.
    // result : [1, 2, 3, 4, 5]
    const result1 = array.slice();

    // 인자값을 하나 넣으면 start로 지정되고 지정된 Index부터 마지막까지 반환한다.
    // result : [3, 4, 5] 
    const result2 = array.slice(2);

    // 인자값을 두개(모두) 넣으면 start 와 end가 지정된 배열을 반환한다.
    // result : [2, 3]
    const result3 = array.slice(13);


Array.splice(start:number, deleteCount?: number): T[];

    const array = [12345];

    // 인자값을 넘기지 않으면 빈배열을 반환한다.
    // result : []
    const result1 = array.splice();


    const array = [12345];

    // 인자값을 하나 넣으면 start로 지정되고 지정된 Index부터 마지막까지 반환한다.
    // result : [3, 4, 5]
    const result2 = array.splice(2);


    const array = [12345];

    // 인자값을 두개(모두) 넣으면 start 와 end가 지정된 배열을 반환한다.
    // result : [2, 3, 4]
    const result3 = array.splice(13);


slice와 splice는 비슷한 기능을 수행하지만 위 코드를 보면 차이가 있는걸 확인할수 있다.

1. 인자값을 넘기지 않았을때의 반환되는 값

    slice()는 대상 배열의 모든값을 반환하지만 splice()는 아무것도 반환하지 않는다.

2. 두번째 인자값의 처리방법

    slice(), end?:number, 배열의 처음부터 index만큼 움직인다고 생각하면 된다. 또한 index항목의 값은 포함하지 않는다.

    splice(), deleteCount?: number, 배열의 처음이 아닌 첫 인자(start: number)값을 기준으로 두번째 인자값 만큼의 배열값을 반환한다.


Array.slice(), Array.splice()는 처리 대상의 배열이 처리전과 처리후의 값이 다르다.

Array.slice()는 처리후에도 원래의 값을 유지하고 있는 반면 Array.splice()는 처리후 원래의 값이 변경된다.


Array.slice();

    const array = [12345];

    // result : [4, 5]
    // array : [1, 2, 3, 4, 5]
    const result = array.slice(3);


Array.splice();

    const array = [12345];

    // result : [4, 5]
    // array : [1, 2, 3]
    const result = array.splice(3);


어떤 처리를 하느냐에 따라 두 기능을 활용하면 될것같다.

2020년 8월 30일 일요일

JavaScript, Array

length: number;
    const array = [12345];
    // 배열의 길이
    const arrayLength = array.length;

    // 5
    console.log(arrayLength)

pop(): undefined; 
    const array = [12345];
    // 배열의 마지막 항목 제거
    array.pop();

    // [1, 2, 3, 4]
    console.log(array);

push(...items: T[]): number;
    const array = [];
    // 배열에 새로운 항목 추가
    array.push(1);
    array.push(23);

    // [1, 2, 3]
    console.log(array);

concat(...items: ConcatArray<T>[]): T[];
    const array1 = ['A''B'];
    const array2 = [123];

    // 배열을 합친다.
    const array3 = array1.concat(array2);

    // ['A', 'B', 1, 2, 3]
    console.log(array3);

join(separator?: string): string
    const array = [12345];

    // 배열을 string으로 변경
    const result = array.join();
    const result1 = array.join('/');

    // 1, 2, 3, 4, 5 1/2/3/4/5
    console.log(resultresult1);

reverse(): T[];
    const array = [12345];

    // 배열항목을 뒤집는다.
    const result = array.reverse();

    // [5, 4, 3, 2, 1]
    console.log(result);

indexOf(searchElement: T, fromIndex?: number): number
    const array = ['A''B''C''D''E'];

    // 배열의 항목중 같은 항목을 찾아 그 항목의 Index값을 리턴
    const result = array.indexOf('C');

    // 2
    console.log(result);

    const result1 = array.indexOf('Z');

    // -1
    console.log(result1);


2019년 12월 19일 목요일

MongoDB, Like사용


LIKE를 사용하여 이름에 'aaa'가 포함된 데이터를 조회한다.
SELECT *
FROM user
WHERE name LIKE '%aaa%'

MongoDB에서의 사용방법

String name = "aaa";
Query query = new Query();
query.addCriteria(Criteria.where("name").regex(name);

2019년 10월 3일 목요일

ImageView를 사용하여 toggle 기능 사용하기, android

즐겨 찾기 기능을 위해 ImageView를 사용한 Toggle기능을 구현.

먼저 사용할 이미지를 준비한다.
https://www.iconfinder.com/search/?q=star&from=homepage&type=vector&price=free


res/drawable/selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_activated="true"
        android:drawable="@drawable/ic_star_24dp" />
    <item
        android:drawable="@drawable/ic_star_border_24dp" />
</selector>

ImageView
<ImageView
  android:src="@drawable/selector"
  ..
  .. />

ImageView - onClick

star.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(final View view) {
        view.setActivated(!view.isActivated());
    }
});

2019년 8월 22일 목요일

Querydsl, replace

1
2
3
SELECT *
FROM table
WHERE replace(column_name, ' ', '') =  'aaa'



1
2
3
4
5
StringExpression se = StringTemplate.create("replace({0}, ' ', '')", column_name);

return select().from(o).where(
         se.eq('aaa')
       ).list(o);

2019년 8월 1일 목요일

Firebase, Firebase storage에 업로드 및 업로드파일 다운로드 링크 가져오기

로컬파일에서 업로드

1
2
// AndroidManifest.xml에 사용권한 추가
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 내부 사진첩 열기
ImageView imageView = findViewById(R.id.img);
imageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType(MediaStore.Images.Media.CONTENT_TYPE);
        startActivityForResult(intent, 1000);
    }
});

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    switch (requestCode) {
        case 1000:
            // 선택한 이미지를 ImageView에 표시
            imageView.setImageURI(data.getData());
            // 이미지 내부경로
            imagePath = getPath(data.getData());
            break;
    }
}

private String getPath(Uri uri) {
    String [] proj = {MediaStore.Images.Media.DATA};
    CursorLoader cursorLoader = new CursorLoader(this, uri, proj, null, null, null);

    Cursor cursor = cursorLoader.loadInBackground();
    int index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

    cursor.moveToFirst();

    return cursor.getString(index);
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 전역변수 선언
private FirebaseFirestore db;
private FirebaseStorage storage;
private StorageReference storageRef;
private StorageReference recvRef;

// 초기화 및 Storage 버킷설정
private void init() {
    db = FirebaseFirestore.getInstance();
    storage = FirebaseStorage.getInstance("xxx-xxx.appspot.com");
    storageRef = storage.getReference();
}


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
Uri file = Uri.fromFile(new File(companyImgPath));
// 업로드 폴더 지정
recvRef = storageRef.child("company/" + file.getLastPathSegment());
recvRef.putFile(file).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

        // 업로드 완료후 다운로드 경로 가져오기
        recvRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                // 다운로드 경로 표시 (uri.toString())
                Log.d(TAG, uri.toString());
            }
        });
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        Log.d(TAG, "Image Upload failure.");
    }
});

2019년 7월 31일 수요일

Firebase, Coustom objects 사용

Coustom 객체를 사용한 조회

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
db.collection("company")
      .get()
      .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
           @Override
           public void onComplete(@NonNull Task<QuerySnapshot> task) {
                 if (task.isSuccessful()) {
                      for (QueryDocumentSnapshot document : task.getResult()) {
                          companyList.add(document.toObject(Company.class));
                      }
                  } else {
                      Log.w(TAG, "Error getting company documents.", task.getException());
                  }
              }
        });

1
2
// 조회된 데이터 매핑
Company company = document.toObject(Company.class);


Coustom 객체를 사용한 추가

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
db.collection("company")
        .add(company)   // 객체를 넣어준다.
        .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
            @Override
            public void onSuccess(DocumentReference documentReference) {
                finish();
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "Failure save");
            }
       });

2019년 7월 26일 금요일

circularImageView-안드로이드에서 간단하게 원형 이미지 생성

Web site
https://github.com/lopspower/CircularImageView

build.gradle(Module:app)에 추가
1
2
3
dependencies {
    implementation 'com.mikhaellopez:circularimageview:4.0.1'
}

Properties
  • app:civ_circle_color (color) -> default WHITE
  • app:civ_border (boolean) -> default true
  • app:civ_border_color (color) -> default WHITE
  • app:civ_border_width (dimension) -> default 4dp
  • app:civ_shadow (boolean) -> default false
  • app:civ_shadow_color (color) -> default BLACK
  • app:civ_shadow_radius (float) -> default 8.0f
  • app:civ_shadow_gravity (center, top, bottom, start or end) -> default bottom

XML
1
2
3
4
5
6
7
8
9
<com.mikhaellopez.circularimageview.CircularImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/image"
        app:civ_border_color="#3f51b5"
        app:civ_border_width="4dp"
        app:civ_shadow="true"
        app:civ_shadow_radius="10"
        app:civ_shadow_color="#3f51b5"/>

JAVA

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
CircularImageView circularImageView = findViewById(R.id.circularImageView);
// Set Circle color for transparent image
circularImageView.setCircleColor(Color.WHITE);
// Set Border
circularImageView.setBorderColor(Color.RED);
circularImageView.setBorderWidth(10);
// Add Shadow with default param
circularImageView.setShadowEnable(true);
// or with custom param
circularImageView.setShadowRadius(15);
circularImageView.setShadowColor(Color.RED);
circularImageView.setBackgroundColor(Color.RED);
circularImageView.setShadowGravity(CircularImageView.ShadowGravity.CENTER);

안드로이드에서 Picasso사용




Last version
https://github.com/square/picasso

build.gradle 추가
1
2
3
dependencies {
    implementation 'com.squareup.picasso:picasso:2.71828'
}



1
Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);

2015년 5월 8일 금요일

2015년 3월 2일 월요일

Eclipse @author change.

springsource(STS) 기준으로 실행파일(STS.exe)파일이 있는 위치에 STS.ini파일을 열어 설정을 추가 및 변경해준다.

-Duser.name=username

2015년 2월 3일 화요일

Hibernate Error: a different object with the same identifier value was already associated with the session

동일한 primary key로 Insert를 시도할때 발생한다.

primary key값을 확인하고 DB에 이미 등록되어 있는 데이터인지 확인.

2015년 1월 27일 화요일

개발자옵션이 노출되게 하는 방법, Android

 설정의 시스템에 있는 휴대전화 정보메뉴를 선택한다.

제일 하단에 보이는 빌드번호를 계속 터치하게 되면 개발자가 된다. -_-;

2015년 1월 23일 금요일

같은 이름으로 이미지를 변경할경우, JQuery

  // html
  

  // js
  // 일반적인 이미지 변경 할경우
  $('#banner').attr('src', '/image/bb.jpg');
 
  // 같은이름의 이미지로 변경할 경우
  $('#banner').attr('src', '/image/bb.jpg?param=123');

이미지를 변경하기 위해 동일한 이름으로 이미지를 교체하는 경우가 있는데, 캐싱문제로 인해 바로 변경되지 않는 경우가 있다.
위와같이 파라미터를 랜덤한 값으로 붙여 해결할수 있다.

선택된 텍스트값 얻기, JavaScript

var selection_text = document.selection.createRange().text;
alert(selection_text);

팝업창 옵션, JavaScript

function openPopup() {
  var url = '/popup.jsp';
  var option = 'width=100, height=100';
  window.open(url, '', option);
}
window popup option
width : 팝업창 가로사이즈 (px로 표시)
height : 팝업창 세로사이즈 (px로 표시)
top : 화면 상단에서 부터의 팝업창이 뜰 위치 (px로 표시)
left : 화면 왼쪽에서 부터의 팝업창이 뜰 위치 (px로 표시)
toolbar : 도구창 노출 여부 (yes or no로 표시)
menubar : 메뉴 노출 여부 (yes or no로 표시)
location : 메뉴 아이콘 노출 여부 (yes or no로 표시)
directories : 제목 표시줄 노출 여부 (yes or no로 표시)
status : 상태바 노출 여부 (yes or no로 표시)
scrollbars : 스크롤 사용여부 (yes or no로 표시)
resizable : 팝업창 사이즈 변경 가능 여부 (yes or no로 표시)

SpringSource Tool Suite 메뉴등록, Linux mint

STS를 다운받고 /opt 디렉토리로 이동시켜 압축을 해제한다.

sudo gedit /usr/share/applications/STS.desktop

[Desktop Entry]
Name=SpringSource Tool Suite
Comment=SpringSource Tool Suite
Exec=/opt/springsource/sts-3.6.1.RELEASE/STS
Icon=/opt/springsource/sts-3.6.1.RELEASE/icon.xpm
StartupNotify=true
Terminal=false
Type=Application
Categories=Development;IDE;java;

슈퍼키를 눌러 sts를 입력하면 등록된 메뉴를 확인할수 있다.

2015년 1월 22일 목요일

Using SharedPreference, Android

앱을 개발하면서 간단한 사용자의 설정 정보 또는 무겁지 않은 데이터를 저장할때 사용하면 유용합니다. 저장된 데이터는 앱을 삭제하거나 앱 데이터를 삭제하면 지워지는 데이터 이므로 저장하려는 데이터를 어디에 저장할것인 잘 판단해야 합니다. 데이터 저장 ...