안드로이드

반응형





https://blog.stylingandroid.com/permissions-part-3/

위 블로그 글을 참고 하였고 

프로젝트는 작성자의 깃허브 사이트 

https://github.com/StylingAndroid/Permissions/tree/Part3

를 참고 하였다.


프로젝트를 실행하면 이러한 모습이다



코드를 참고하면서 내 프로젝트에 필요한 것만 참고함.


먼저

PermissionsActivity.java 와 PermissionsChecker.java를 프로젝트에 붙여넣기 하였다.

추가 설명은 코드 내 주석을 달아놓았다.



PermissionsActivity.java

37라인

setContentView(R.layout.new_custom_full);

이 부분은 팝업을 표시할 액티비티의 xml 파일명으로 변경해준다.

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
 
 
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
 
public class PermissionsActivity extends AppCompatActivity {
    public static final int PERMISSIONS_GRANTED = 0;
    public static final int PERMISSIONS_DENIED = 1;
 
    private static final int PERMISSION_REQUEST_CODE = 0;
    private static final String EXTRA_PERMISSIONS = "com.stylingandroid.permissions.EXTRA_PERMISSIONS";
    private static final String PACKAGE_URL_SCHEME = "package:";
 
    private PermissionsChecker checker;
    private boolean requiresCheck;
 
    public static void startActivityForResult(Activity activity, int requestCode, String... permissions) {
        Intent intent = new Intent(activity, PermissionsActivity.class);
        intent.putExtra(EXTRA_PERMISSIONS, permissions);
        ActivityCompat.startActivityForResult(activity, intent, requestCode, null);
    }
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getIntent() == null || !getIntent().hasExtra(EXTRA_PERMISSIONS)) {
            throw new RuntimeException("This Activity needs to be launched using the static startActivityForResult() method.");
        }
        setContentView(R.layout.new_custom_full); //xml 파일명 변경 필요
 
        checker = new PermissionsChecker(this);
        requiresCheck = true;
    }
 
    @Override
    protected void onResume() {
        super.onResume();
        if (requiresCheck) {
            String[] permissions = getPermissions();
 
            if (checker.lacksPermissions(permissions)) {
                requestPermissions(permissions);
            } else {
                allPermissionsGranted();
            }
        } else {
            requiresCheck = true;
        }
    }
 
    private String[] getPermissions() {
        return getIntent().getStringArrayExtra(EXTRA_PERMISSIONS);
    }
 
    private void requestPermissions(String... permissions) {
        ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
    }
 
    private void allPermissionsGranted() {
        setResult(PERMISSIONS_GRANTED);
        finish();
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {
            requiresCheck = true;
            allPermissionsGranted();
        } else {
            requiresCheck = false;
            showMissingPermissionDialog();
        }
    }
 
    private boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {
        for (int grantResult : grantResults) {
            if (grantResult == PackageManager.PERMISSION_DENIED) {
                return false;
            }
        }
        return true;
    }
 
    //모두 거부 하였을 때 나타나는 팝업 창 설정입니다.
    private void showMissingPermissionDialog() {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(PermissionsActivity.this);
        dialogBuilder.setTitle(R.string.help); //팝업 창 타이틀
        //팝업 안내 메시지 부분으로 string.xml에서 설정한 메시지를 노출합니다.
        dialogBuilder.setMessage(R.string.string_help_text);
        //팝업 창 버튼 2개를 노출합니다.
        //확인버튼을 누르면 앱 종료?인데 저는 팝업 창만 사라졌네요
        dialogBuilder.setNegativeButton(R.string.quit, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                setResult(PERMISSIONS_DENIED);
                finish();
            }
        });
        //설정 버튼을 누르면 설정 화면으로 이동합니다.
       dialogBuilder.setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                startAppSettings();
            }
        });
        dialogBuilder.show();
    }
 
     private void startAppSettings() {
        Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));
        startActivity(intent);
    }
}
cs



PermissionsChecker.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
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.content.ContextCompat;
 
class PermissionsChecker {
    private final Context context;
 
    public PermissionsChecker(Context context) {
        this.context = context;
    }
 
    public boolean lacksPermissions(String... permissions) {
        for (String permission : permissions) {
            if (lacksPermission(permission)) {
                return true;
            }
        }
        return false;
    }
 
    private boolean lacksPermission(String permission) {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_DENIED;
    }
 
}
 
cs


발생하는 에러는 알맞게 처리한 다음

AndroidMenifest.xml 에 PermissionsActivity를 추가해준다.

1
2
3
4
5
6
7
8
9
10
        <!--PermissionsActivity 를 추가해줍니다.-->
        <!--팝업 적용을 위해 @style:AppTheme 추가해줍니다-->
        <activity
            android:name="com.yonoo.my.PermissionsActivity"
            android:configChanges="orientation|screenSize|screenLayout|keyboard|keyboardHidden"
            android:label="@string/app_name"
            android:theme="@style/AppTheme"
            android:screenOrientation="nosensor" >
        </activity>
 
cs


권한도 추가

1
2
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.CAMERA" />
cs



앱 테마 적용을 위해 style.xml에 다음을 추가해준다.

(다국어 설정이 되어있다면 국가별 style.xml에도 추가해준다.)

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<resources>
 
    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>
    <!--팝업 호출을 위해 아래 스타일이 필요합니다.-->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    </style>
</resources>
 
cs


그리고 권한 팝업 노출시 권한 설명을 위한 메시지를 string.xml에 추가하여준다. 마찬가지로 다국어 string에도 추가

이 메시지는 PermissonsActivity의 showMissingPermissionDialog에서 사용된다.

1
2
3
4
5
6
    <!--권한 팝업에서 노출될 메시지를 설정합니다.-->
    <string name="settings">설정</string>
    <string name="help">Help</string>
    <string name="string_help_text"> 저장소와 카메라 권한이 필요합니다. </string>
    <string name="quit">확인</string>
 
cs


그리고 권한 팝업을 띄울 액티비티파일에 다음 코드를 추가해준다.

ex) NewCustomFullActivity 에 권한 팝업을 띄울거라면 변수를 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class NewCustomFullActivity implements OnClickListener{
 
    //권한 체크를 위한 값 선언
    private static final int REQUEST_CODE = 0;
    /*요청받은 권한을 설정합니다. 여기선 저장소와 카메라를 설정
    * android.Manifest.permission.WRITE_EXTERNAL_STORAGE
    * android.Manifest.permission.CAMERA
    * */
    private static final String[] PERMISSIONS = 
            new String[]{
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    android.Manifest.permission.CAMERA
            };
    //PermissionChecker를 사용하기 위해 선언
    private PermissionsChecker checker;
cs


OnCreate에 다음 코드 추가

1
2
//Oncreate 에서 Checker를 호출
checker = new PermissionsChecker(this);
cs


그리고 다음 함수를 추가해준다.

1
2
3
    private void startPermissionsActivity() {
        PermissionsActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);
    }
cs


이제 팝업을 어디서 띄울지 결정해야했는데 카메라를 선택했을 때 띄우기로 결정

그래서 startActivityForResult(intent, PICK_FROM_CAMERA); 이 부분이 호출될 때 팝업이 뜨게 하였다.

권한 때문에 SecurtiyException 이 발생할 때

1
2
3
4
    //권한을 체크
    if (checker.lacksPermissions(PERMISSIONS)) {
        startPermissionsActivity();
    }
cs

이 부분을 추가해주어 권한 허용 유무를 체크하여 미허용상태면 팝업을 띄우도록 startPermissionsActivity() 을 요청한다.


추가된 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//카메라를 호출할 때 권한이 없으면 권한요청팝업이 뜨도록 설정
try{
    startActivityForResult(intent, PICK_FROM_CAMERA);
}catch (SecurityException e) {
    //권한을 체크
    if (checker.lacksPermissions(PERMISSIONS)) {
        startPermissionsActivity();
    }
    //토스트로 안내메시지도 같이 호출해보았습니다.
    e.printStackTrace();
    if(language.equals("en"|| language.equals("th"|| language.equals("vi"))
        Toast.makeText(getApplicationContext(),
                "check phone settinig >  application manager > app permission Camera approve",
                Toast.LENGTH_LONG).show();
    else
        Toast.makeText(getApplicationContext(),
                "설정 > 애플리케이션 관리자 >앱권한에서 카메라 권한을 허용해주세요",
                Toast.LENGTH_LONG).show();
}
cs


이렇게 해주면 카메라를 킬 때 허용 팝업이 노출된다.


외국인 블로거가 짜놓은 코드를 사용하였기 때문에 자세한 설명보다는 크게 크게 이해해보려고 하였다.

나중을 위해서 적어 놓은건데 빼 먹은 건 없나 모르겠다.


원래는 앱 시작하자마자 팝업 띄우려고 헀는데 뭔가 계속 안된다.. 

그래서 그냥 해당기능 켤 때  띄우는 걸로..


이런 걸 취미로 포스팅 하는 개발자들은 참 대단하다.

난 아무리 봐도 이해가 안가는데..





반응형
반응형


Android API 23 에서 바뀐 부분이 있나보다

코드에서 getDrawable 부분에서

  'getDrawable(int)' is deprecated more...

이게 발생했다.

수정 방법은 다음과 같았다

기존 코드

img_season = (BitmapDrawable)context.getResources().getDrawable(getMap().get(str_season));


수정 코드

img_season = (BitmapDrawable) ContextCompat.getDrawable(context, getMap().get(str_season));



ContextCompat 를 추가하고 나서 아래 사진처럼 뜨는데 Alt + Enter를 해주면 정상적으로 적용된다.




반응형
반응형


고난의 연속.. Eclipse에서 Android Studio로 넘어오려고 애쓰는데 스트레스만 받고 있었다.

이클립스에 있던 프로젝트를 import 해도 계속 에러에러에러... 

결국 그냥 안드로이드 스튜디오에서 새 프로젝트만들고 거기다 붙여넣어 보는 식으로 어찌어찌 해결하다가 갑자기 왠 아웃오브메모리???


대략 이런 에러가 발생


Error:UNEXPECTED TOP-LEVEL ERROR:


Error:java.lang.OutOfMemoryError: GC overhead limit exceeded


:app:transformClassesWithDexForDebug FAILED


Error:Execution failed for task ':app:transformClassesWithDexForDebug'.


> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_05\bin\java.exe'' finished with non-zero exit value 3


버틸 수가 없었다. 내 한계에 부딪히는듯 했다.

찾아보니 build.gradle 파일에서 defaultConfig 에 multiDexEnabled true를 추가해주래서 했는데 해결이 되지 않았고

질문 게시판에 올려보았는다 친철한 분께서 다음과 같은 제안을 해주셨다.

build.gradle 파일에 android 내부에 다음 코드를 넣어보세요


dexOptions {

  jumboMode true

  javaMaxHeapSize "4g"



바로 적용해보았더니 오오오오 아웃오브메모리 에러가 사라졌다.

감동적인 순간이었다. 앱이 실행이 되다니..

아래와 같이 적용했다.


 



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
apply plugin: 'com.android.application'
 
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
 
    defaultConfig {
        applicationId "패키지네임"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
//dexOptions 추가
    dexOptions {
        jumboMode true
        javaMaxHeapSize "4g"
    }
}
cs




물론 이게 100% 해결책이 아닐 수 있다. 언제나 그랬듯이 남의 해결책이 나의 해결책이 되진 않기 때문에..


여기까지 오기에 많은 에러가 있었는데 그 에러들이 어떻게 해결되었는지는 모르고 어찌어찌 넘어왔다.

 

그 에러들 해결방법도 다시 찾아봐야겠다.





반응형
반응형




사전환경셋팅이 되어있어야 한다.

java 와 Android sdk가 설치되어 있어야 하고 환경변수도 설정되어 있어야한다.



http://recorder.robotium.com/downloads/re-sign.jar



re-sign.jar



위 링크에서 re-sign.jar 파일을 받아서 실행한다.


그럼 아래와 같은 창이 뜨고 여기다 재서명할 apk를 끌어다 놓으면 된다.






이런 창이 뜬다면 zipalign 파일이 없다는 것이므로 해당파일을 ~~sdk/tools 폴더에 붙여넣어준다.




zipalign 파일은 sdk 가 설치된 폴더에 보면 build-tools 라는 폴더가 있는데 

들어가서 아무 폴더에서 쉽게 찾아볼 수 있다.



zipalign.exe



재서명이 끝나면 아마 apk 명 끝에 -debug라고 붙은 apk가 생성되었을 것이다.

(또는 직접 정해준 파일명으로)


이 apk 를 사용하면 끝이다.


이렇게 간단한 방법이 있었다니..






반응형
반응형




Android Run 시 아래와 같은 에러가 났을 경우


[2016-02-15 11:25:55 - Dex Loader] Unable to execute dex: Multiple dex files define

[2016-02-15 11:25:55 - Test] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define


android-support-v7-appcompat 프로젝트가 Library 에 추가 되었는지 확인해본다.


해당 프로젝트 우클릭 - Properties - Android 탭 하단에서 볼 수 있다.


Library 를 보면 android-support-v7-appcompat 프로젝트가 추가 되었는지 볼 수 있는데 필자의 경우 android-support-v7-appcompat 라이브러리가 사라져 있었다.






이런 경우 android-support-v7-appcompat 라이브러리 프로젝트를 따로 import 시켜주어야 한다. 



이 프로젝트는 아마 처음 Android Project를 새로 생성할 때 OS 4.4.4 킷캣 이상 버전으로 생성하면 자동으로 생성되었던 라이브러리이다.

(android-support-v7-appcompat 이게 생성 안되게 프로젝트를 생성하는 방법이 있다곤 하는데 우선 급한 불 부터 꺼보겠다)


그런데 이게 가끔 지멋대로 프로젝트가 사라진다거나 이상하게 깨지는 경우가 많다. 

그래서 이게 생성안되게 새 프로젝트 생성시 4.1.2로 만들곤 한다.


혹시 몰라 첨부..


android-support-v7-appcompat.zip



android-support-v7-appcompat를 import 하였다면 이제 작업하는 프로젝트에 추가해주어야 한다.


Add 버튼을 누르면 라이브러리 프로젝트 선택화면이 나온다.




android-support-v7-appcompat를 선택하고 ok를 누르면







초록색으로 체크표시가 되고 추가가 될 것이다. Apply를 눌러 적용시키고


이제 다시 한번 프로젝트를 Run 해본다.


그래도 안된다면 다음 링크를 참고해본다.


http://stackoverflow.com/questions/7870265/unable-to-execute-dex-multiple-dex-files-define-lcom-myapp-rarray


http://www.androidside.com/bbs/board.php?bo_table=B56&wr_id=27196



반응형
반응형




sdk 를 업데이트 하려는데 자꾸 로그에



Download interrupted: peer not authenticated 


이런게 뜨면서 설치가 되지 않았다.


그래서 찾아보니 옵션을 수정해주어야 된다고 한다.


sdk 매니저 상단 Tools > Options 에 들어간다.





그리고 하단 others에 


Force https;// 를 체크해준다.






Close 한뒤 설치를 다시 시도해본다.


설치가 진행된다!








반응형
반응형




이 방법을 시도해보기 전에 더 간단한 방법이 있으므로 시도해보길 추천함

안드로이드 apk 쉽게 재서명 resign 하기

http://yonoo88.tistory.com/808




이미 릴리즈 된 안드로이드 apk 를 내 개인 서명키로 바꾸는 방법

여기서는 이미 있는 debug.keystore 파일을 이용하여 해보았다.


우선 재서명할 apk를 준비한다.


압축프로그램이 있다면 우클릭을 하고 압축을 푼다. (ex. astro apk)





압축을 풀고 나서 해당 폴더에 들어가면 파일이 많이 있는데 여기서 



META-INF 폴더를 삭제한다. 이 폴더에 서명관련한 파일들이 있기 때문이다.



삭제한 다음 다시 이 폴더를 압축하는데 꼭 폴더 내부로 들어가서 모든파일 선택 후 압축을 해야한다.!





그럼 압축파일이 생기는데 보기 편한 곳으로 이동시켜놓고




확장자를 ,apk로 바꿔준다.



그럼 위처럼 apk 로 변경된다 (기존 apk와 이름이 같아 resign으로 변경해주었다)


혹시 뒤에 확장자가 안보이면 폴더옵션에서

알려진 파일 형식의 파일 확장명 숨기기를 체크 해제 해준다.







그럼 cmd 창을 연다.


해당 폴더가 있는 경로로 진입한다. 여기서는 d:\astro 이다


그리고 서명할 키가 있어야 하는데 여기서는 debug.keystore를 이용하겠다.


이 키스토어는 C:\Users\Administrator\.android 폴더에 위치하고 있다.





그럼 이제 서명을 해줘야 하는데 명령어는 다음과 같다.


출처

http://developer.android.com/tools/publishing/app-signing.html


$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1
-keystore my-release-key.keystore my_application.apk alias_name


jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore [키스토어경로] [서명할apk경로] [키스토어별명]


여기서 jarsigner 경로가 환경변수에 등록되어 있어야한다.


하지만 자바를 처음 설치할 때 


%JAVA_HOME%\jdk\bin


이런 식으로 환경변수를 등록해주므로 아마 이미 되었을 것이다.


기본 경로는 다음과 같다(64비트)


C:\Program Files\Java\jdk1.8.0_05\bin




이렇게 해주면 된다.


기본적으로 debug.keystore 는 다음과 같은 정보를 가지고 있다


  • 키스토어 이름 : "debug.keystore"
  • 키스토어 비밀번호 : "android"
  • 키 별명 : "androiddebugkey"
  • 키 비밀번호 : "android"
  • CN: "CN=Android Debug,0=Android,C=US"

  • 키스토어 별명은 확인은


    keytool -list -v -keystore [키스토어경로] 


    로 확인할 수 있다.






    그럼 다음과 같이 입력 후 


    jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore c:\.android\debug.keystore com.metago.resign.apk androiddebugkey


    실행하면 암호를 치라고 나오는데 android 라고 써준다.




    그럼 뭐가 좌르륵 나오면서 끝에 jar signed 라고 뜰 것이다.



    이제 서명은 되었고 apk를 다시 재정렬?시켜줘야 한다.


    그러기 위해서는 


    zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

    zipalign -v 4 [서명한apk] [apk 새이름]


    위 명령어를 실행해 줘야 하는데 zipalign 경로가 환경변수 Path에 추가 되어 있어야 한다.



    Path 변수 값 예시C:\ProgramData\Oracle\Java\javapath;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;%JAVA_HOME%\bin;D:\backup\eclipse\adt-bundle-windows-x86_64-20140702\sdk\platform-tools;%ANDROID_HOME%\tools;%ANDROID_HOME%\build-tools\android-4.4W 



    zipalign 은 sdk 폴더에 buiild-tools 에서 안드로이드 아무 버전이나 폴더에 들어가면 있다.


    ex ) C:\adt-bundle-windows-x86_64-20140702\sdk\build-tools\android-4.4W




    그래서 


    zipalign -v 4 com.metago.astro.resign.apk astro.apk



    라고 실행해주면


    아까보다 더 많은 좌르륵이 나오면서 


    Verification succesful 





    이라고 뜰 것이다.



    해당 폴더에 가보면 apk 가 생성되어 있을 것이다.





    확인을 해보고 싶다면

    jarsigner -verify my_application.apk //간단히 서명확인할 때

    jarsigner -verify -verbose -certs my_application.apk //서명 외 다른 정보도 자세히 확인할 때


    다음과 같이 실행해준다.


    원본 apk 파일인 com.metago.astro.apk 의 서명 정보 확인


    jarsigner -verify -verbose -certs com.metago.astro.apk





    debug.keystore 로 재서명한 astro.apk


    jarsigner -verify -verbose -certs astro.apk




    재서명한 astro.apk를 보면 Android Debug로 바뀐게 보인다.


    그럼 재서명 완료!!



    반응형
    반응형




    우선 아래와 같이 asset 폴더에 폰트파일을 추가해준다.





    폰트파일의 경로는 C:\Windows\Fonts 여기서 찾을 수 있다.


    그런 다음 폰트를 바꾸고 싶은 뷰에다 적용을 해주면되는데 개인적으로 버튼의 텍스트 폰트를 바꾸고 싶었다.



    Button btn2 = (Button)findViewById(R.id.button_custom);
    btn2.setOnClickListener(this);
    	
    Typeface typeFace = Typeface.createFromAsset(getAssets(), "fonts/NEXONFootballGothicB.ttf"));  //asset > fonts 폴더 내 폰트파일 적용
    btn2.setTypeface(typeFace);
    
    


    위와 같이 버튼에 폰트를 적용하였다.


    Typeface typeFace = Typeface.createFromAsset(getAssets(), "fonts/NEXONFootballGothicB.ttf")); // 폰트 설정 후

    btn2.setTypeface(typeFace); //btn2 버튼에 폰트 적용


    끝!


    반응형

    + Recent posts