1. 이미지를 Bitmap으로 변환

1. 안드로이드 리소스를 Bitmap으로 변환

1
2
// drawable에 있는 리소스를 BitmapFactory를 이용해 bitmap 작성
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_guest, options);
cs

 

2. 파일을 Bitmap으로 변환

1
2
3
4
// File의 이미지를 BitmapFactory를 이용해 Bitmap 작성
File file = new File(filePath, fileName);
FileInputStream fileInputStream = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeFile(filePath + "/" + fileName);
cs

 

인터넷에서 이미지 다운로드는 이쪽으로 : https://puzi.tistory.com/31

 

[안드로이드]이미지 다운로드

메인 쓰레드는 이미지 다운로드 동안 기다릴 수 없기 때문에 AsynkTask로 작성한다. 그리고 리스너를 달아주어 다운로드 완료 후 처리를 하도록한다. ImageUrlDown.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1..

puzi.tistory.com

 

2. Bitamp을 byte로 저장 후 Base64로 encoding

1
2
3
4
5
6
// BytArrayOutputStream을 이용해 Bitmap 인코딩
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
// 인코딩된 ByteStream을 String으로 획득
byte[] image = byteArrayOutputStream.toByteArray();
String byteStream = Base64.encodeToString(image, 0);
cs

 

3. html의 자바스크립트를 호출하여 Base64를 넘겨줌

1
2
3
// ByteStream을 자바스크립트를 이용해 전달
binding.mainWebView.loadUrl("javascript:setImageByteCode('data:image/png;base64," + byteStream + "')");
 
cs

 

4. 넘겨받은 Base64값으로 이미지 출력

<HTML>

1
2
3
4
5
6
7
8
9
10
    <head>
        <script id="applicationScript">
            function setImageByteCode(byteCode) {
                document.getElementById("photo").src = byteCode;
            }
        </script>
    </head>
    <body>
        <img id = "photo" src = "trans.png" title="picture">        
    </body>
cs

 

메인 쓰레드는 이미지 다운로드 동안 기다릴 수 없기 때문에 AsynkTask로 작성한다.

그리고 리스너를 달아주어 다운로드 완료 후 처리를 하도록한다.

 

ImageUrlDown.java

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
35
36
37
38
39
40
41
42
43
44
45
package com.example.test_html_bytecode;
 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
 
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
 
public class ImageUrlDown extends AsyncTask<StringString, Bitmap> {
    // 다운로드 완료 후 호출 할 리스너
    public interface OnPostDownLoadListener {
        void onPost(Bitmap bitmap);
    }
 
    private Bitmap bitmap = null;
    private OnPostDownLoadListener onPostDownLoad;
 
    // 리스너 세팅
    public ImageUrlDown(OnPostDownLoadListener paramOnPostDownLad) {
        onPostDownLoad = paramOnPostDownLad;
    }
    
    @Override
    protected Bitmap doInBackground(String... strings) {
        try {
            // 파라미터로 받은 url로 부터 이미지 다운로드
            bitmap = BitmapFactory.decodeStream((InputStream) new URL(strings[0]).getContent());
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
        // 이미지 다운로드 완료 후 리스너 호출
        if (onPostDownLoad != null)
            onPostDownLoad.onPost(bitmap);
    }
}
 
cs

 

호출은 아래와 같이한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    private void downloadImage() {
        String imageURL = "http://puzi.tistory.com/image.png"//이미지 URL
        // 이미지 다운로드 클래스 생성 및 리스너 작성
        ImageUrlDown imageUrlDown = new ImageUrlDown((bitmap) -> {
            try {
                // 파일 생성
                File file = new File(filePath,fileName);
                // 아웃풋 스트림 생성
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                // 아웃풋 스트림 작성
                bitmap.compress(Bitmap.CompressFormat.PNG,100,fileOutputStream);
                // 아웃풋 스트림 출력
                fileOutputStream.flush();
                // 아웃풋 스트림 종료
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        // url 전달
        imageUrlDown.execute(imageURL);
    }
cs

참고 : https://lannstark.tistory.com/34?category=840464 

 

Java InputStream이란?

InputStream OutputStream을 실무에서 사용할 때면, 뭔가 알긴 알고 실제로 둘을 활용해 기능을 구현하는데는 전혀 문제가 없지만, 사용할때마다 찾아보게되고 뭔가 정확히 아는 것 같지는 않다라는 느

lannstark.tistory.com

 

1. 개요

안드로이드 스튜디오에서 제공하는 navigation drawer에 추가한 메뉴들은 기본적으로 테마의 영향을 받으며 색상변경이 자유롭게 되지 않는다.

각 아이콘의 색을 변경 할 필요가 있을 때 해결 방법이다.

그림1. Navigation drawer (출처:https://developer.android.com/guide/navigation/navigation-ui)

2. 해결 방법

다음의 한줄로 해결이 가능하다.

findViewById(R.id.nav_view).setItemIconTintList(null);

위의 코드를 onCreate()에 추가 한 후 다음 과 같이 색이 다른 이미지로 아이콘을 추가하면 색상이 살아나게 된다.

1
2
3
4
5
6
int[] icons = new int[]{R.drawable.ic_disk1, R.drawable.ic_disk2, R.drawable.ic_disk3};            
for (index = 0; index < users.size(); index++) {
    UserInfo userinfo = users[index];
    MenuItem user = menu.add(R.id.user_menu, Menu.NONE, index, userInfo.id);
    user.setIcon(icons[index % 3]);
}
cs

 

 

그림2. Navigation drawer에 색상이 반영된 icon

 

출처 : https://stackoverflow.com/questions/33407448/change-color-of-navigation-drawer-icon-in-android-studio-default-template/62075034#62075034?newreg=a157ba9e1bdc4cdf943858021f8d66c6 

 

Change color of Navigation Drawer Icon in Android Studio default template

The new default Navigation Drawer Activity template in Android Studio defines its titles and icons in a menu file activity_main_drawer like this: ...

stackoverflow.com

 

1. 목적

한번 클릭에 상태가 유지 되고 다시 한번 클릭에 상태가 해제되는 토글 버튼을 만들고싶다.

 

2. 요구사항

1. 배경이보이고 이미지가 있는 뷰를 사용한다.

2. 이미지 크기 이상의 버튼 영역이 필요로 한다.

3. 토글 될때 마다 이미지가 변하도록 한다.

4. 버튼이 눌리는 효과를 주도록 한다. (배경색이 변하도록 한다)

 

3. 구현

1. 이미지 버튼을 준비한다

1
2
3
4
5
6
    <ImageButton
        android:id="@+id/test_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/baseline_favorite_border_24"
        />
cs

 

 

2. 설정영역에 알맞게 뷰의 크기를 조정한다.

1
2
3
4
5
6
    <ImageButton
        android:id="@+id/test_button"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/baseline_favorite_border_24"
        />
cs

 

3. 버튼의 리스너를 작성한다.

1
2
3
4
5
6
7
8
9
10
11
12
        ImageButton button = findViewById(R.id.test_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(button.isSelected()) {
                    button.setImageResource(R.drawable.baseline_favorite_border_24);
                } else {
                    button.setImageResource(R.drawable.baseline_favorite_24);
                }
                button.setSelected(!button.isSelected());
            }
        });
cs

 

4. 클릭시 효과를 주기위해 백그라운를 정의한다. (ripple효과)

1
2
3
4
5
6
7
    <ImageButton
        android:id="@+id/test_button"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/baseline_favorite_border_24"
        android:background="?attr/selectableItemBackground"
        />
cs

1. 서론

안드로이드 스튜디오로 연속 클릭을 감지하는 메서드를 구현하려고 한다.

유니티는 Update() 함수를 지원하여 프레임과 시간을 조작하지만

안드로이드 스튜디오에선 어떻게 구현할지 생각해 보았다.

 

2. 설계

시스템 시간을 이용해 마지막으로 클릭된 시간을 저장 한후 현재시간과 비교하는 방법으로 구현하려한다.

 

3. 구현

 

 일단 클릭 감지를 하기 위해 onCreate()에 리스너를 달아주었다.

1
findViewById(R.id.button).setOnClickListener(v -> TouchContinuously());
cs

 

다음은 연속 클릭을 감지하는 메소드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    private long lastClickTime = 0// 마지막 클릭 시간
    private int clickTime = 0// 클릭 된 횟수
    private final int TIMES_REQUIRED = 5// 총 필요한 클릭 횟수
    private final int TIME_TIMEOUT = 2000;  // 마지막 클릭후 제한시간
 
    private void TouchContinuously() {
        if (SystemClock.elapsedRealtime() - lastClickTime < TIME_TIMEOUT) {
            clickTime++;
        } else {
            clickTime = 1;
        }
        lastClickTime = SystemClock.elapsedRealtime();
 
        if (clickTime == TIMES_REQUIRED) {
            // TODO 연속 클릭 완료 후 메소드 구현
            Toast.makeText(this"연속 클릭 완료", Toast.LENGTH_SHORT).show();
        }
    }
cs

현재시간 (SystemClock.elapsedRealtime())과 마지막으로 클릭 된 시간(lastClickTime) 의 차이가 제한시간( TIME_TIMEOUT)을 넘는다면 클릭 된 횟수를 1로 초기화하고 넘지않는 다면 클릭 된 횟수를 1회 증가시킨다.

 

그리고 클릭 된 횟수가 필요한 클릭 횟수를 도달 하였을 시 원하는 메소드를 호출 하도록 한다.

 

참고 :https://threeidiotscoding.tistory.com/18

 

[Android Studio] 간단하게 버튼 중복클릭 시간 제한하기

[Android Studio] 간단하게 버튼 중복클릭 시간 제한하기 안드로이드 스튜디오에서 onClick 이벤트가 일어나는 버튼이나 이미지, 텍스트 뷰와 같은 곳에 중복클릭이 일어나지않도록 조건을 두려

threeidiotscoding.tistory.com

 

1. 서론

검색을 해보면 다른 엑티비티에서의 활동에서 결과를 가져오기 위해 과거에 startActivityForResult함수가 이용되는 것을 알 수 있는데 실제로 안드로이드 스튜디오에서 확인해보니 startActivityForResult (deprecated) 라며 새로운 API로 마이그레이션이 필요하다고한다. 그런데 새 API의 설명이 공식 문서와 최근에 올라온 블로그의 글만 가지고는 이해가 어려워 작성하기로했다.

 

2. 사용법

0. build.gradle에 

implementation "androidx.activity:activity:1.2.0-alpha04"
implementation "androidx.fragment:fragment:1.3.0-alpha04"

를 추가해준다.

 

MainActivity.Java

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
public class MainActivity extends AppCompatActivity {
 
    ActivityResultLauncher<Intent> mStartForResult = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if(result.getResultCode() == RESULT_OK) {
                    Intent intent = result.getData();
                    Log.d("MainActivity", intent.getStringExtra("result"));
                }
            }
    );
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        findViewById(R.id.mainButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SubActivity.class);
                intent.putExtra("key""value");
                mStartForResult.launch(intent);
            }
        });
    }
}
cs

1. 데이터를 받을 엑티비티에서 ActivityResultLauncher mStartForResult를 정의한다. (콜백 함수가 포인트이다)

그리고 새로운 엑티비티를 활성화 할때 startActivity가 아닌 ActivityResultLauncher함수의 launch를 이용하여 엑티비티를 활성화한다.

 

 

SubActivity.Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SubActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);
 
        Log.d("SubActivity""onCreate: "+getIntent().getStringExtra("key"));
        findViewById(R.id.subButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SubActivity.this, MainActivity.class);
                intent.putExtra("result","resultData");
                setResult(RESULT_OK, intent);
                finish();
            }
        });
    }
}
 
cs

2. 데이터를 전송할 엑티비티에서 Intent에 자료를 저장한다.

꼭 setResult를 호출하여 결과를 설정한다.

 

3. 서브엑티비티 종료후 메인엑티비티로 돌아올시 ActivityResultLauncher로 작성한 콜백함수가 작동하여 필요한 데이터를 가져와 결과를 처리한다.

 

참고 : https://developer.android.com/training/basics/intents/result?hl=ko

 

활동에서 결과 가져오기  |  Android 개발자  |  Android Developers

개발자 앱 내의 활동이든 다른 앱의 활동이든 다른 활동을 시작하는 것이 단방향 작업일 필요는 없습니다. 다른 활동을 시작하고 다시 결과를 받을 수도 있습니다. 예를 들어, 앱에서 카메라 앱

developer.android.com

 

1. 개요

엑티비티간 데이터 통신을 위한 Intent라는 도구를 이용한다.

A엑티비티에서 Intent에 데이터를 저장 한 후

B엑티비티에서 Intent에 저장되어있는 데이터를 불러와 처리를한다.

 

2. 사용

MainActivity.Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        findViewById(R.id.mainButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SubActivity.class);
                intent.putExtra("key""value");
                startActivity(intent);
            }
        });
    }
}
cs

mainButton이라는 버튼 리스너에 Intent를 생성해 putExtra("key", "value")를 이용해 데이터를 저장한다.

그리고 startActivity로 새로운 엑티비티를 활성화 한다.

 

SubActivity.Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class SubActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);
 
        Log.d("SubActivity""onCreate: "+getIntent().getStringExtra("key"));
        findViewById(R.id.subButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}
 
cs

활성화된 엑티비티에서 데이터를 불러오기위해 getIntent()를 사용한다.

그리고 get자료형Extra("key", "value") 로 자료를 불러오게 되는데 여기서 putExtra를 했던 자료형과 일치하지 않으면 에러를 발생하게 된다.

액티비티를 처음 작성하고 onCreate를 오버라이드하면
@Override

public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState)

형의 자동완성이 있는데 여기서 @Nullable PersistableBundle persistentState 이 파라미터를 받으면 액티비티에 아무것도 나오지 않게된다. 지워주자.

+ Recent posts