Ringster's Techblog

Tech, Mobile, Internet

Posts Tagged ‘Android Studio

Android Studio로 버전코드/버전네임 관리하기

with 7 comments

PlayStore에 등록된 앱은 VersionCode와 VersionName의 두가지 속성을 가지고 있다.
VersionCode는 정수값을 이용하는데, 플레이 스토어 내부적으로 상위 버전을 구분하는데 사용되고, VersionName은 플레이 스토어에서 사용자에게 보여주기 위한 값으로 사용된다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.example"
    android:versionCode="0"
    android:versionName="0.0.0.0">

보통 AndroidManifest.xml에 위와 같이 정의하여 사용하는데, 안드로이드 스튜디오에서는 Gradle scripts의 Build.gradle(Module:app)에 정의된 아래 값에 의해 manifest에 정의된 값이 무시된다.

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.android.example"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

자동화된 빌드 툴을 쓰지 않고 일일히 버전코드와 버전네임을 관리하는 것은 귀찮은 일인데, 이럴때 간단하게 버전 코드를 업데이트 해줄 방법은 다음과 같다.


apply plugin: 'com.android.application'
import java.util.regex.Pattern

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.android.example"
        minSdkVersion 14
        targetSdkVersion 21
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
}


task('increaseVersionCode') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

task('incrementVersionName') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
    def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
    def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
    def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'increaseVersionCode'
        task.dependsOn 'incrementVersionName'
    }
}

default config의 versionCode/versionName를 삭제한 후, Build.gradle에 위와 같이 task 구문을 추가해 주면 빌드 시마다 Manifest의 VersionCode가 +1씩 증가하게되고, VersionName은 0.0.0.0 (Major.Minor.Point.Build 버전) 순으로 형성되어 빌드 시마다 빌드버전이 +1씩 증가된다.

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PackageInfo pInfo = null;
        try {
            pInfo = getPackageManager().getPackageInfo(
                    this.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        int versionCode = pInfo.versionCode;
        String versionName = pInfo.versionName;

        TextView versionCodeTextView = (TextView) findViewById(R.id.versionCode);
        versionCodeTextView.setText("VersionCode:"+Integer.toString(versionCode));

        TextView versionNameTextView = (TextView) findViewById(R.id.versionName);
        versionNameTextView.setText("VersionName:"+versionName);

    }
}

매니페스트 상에서도 바로바로 업데이트 되는 것을 볼 수 있지만 위와 같이 버전명과 버전코드를 호출해서 확인도 가능하다.

Written by Ringster

2015/03/06 at 4:33 pm

Android Studio Getter/Setter prefix 설정법

leave a comment »

클래스의 멤버 변수나 스태틱 변수 이름 명명 시 mVariable, sVariable과 같이 접두사를 이용하는데,

안드로이드 스튜디오에서는 Getter/Setter의 prefix를 설정하는 방법을 몰라서 Getter/Setter 자동 생성시

getmVariable, setmVariable과 같이 메소드 명이 생성되어 손이 두번 가곤 했다.

접두어 설정 방법은 메뉴에서 File -> Other Settings -> Default Settings 에 들어간 후 Code Style -> Java

이후 Default에 있는 Code Generation의 Name Prefix를 Field : m, Static Field : s로 설정해 놓으면 된다.

Written by Ringster

2015/03/03 at 4:51 pm

SporTracker 제작 후기 (1) – Twitter Fabric, Crashlytics kit 사용기

with 2 comments

지난달 남는 시간을 들여 만든 앱을 하나 앱스토어에 등록했다.
Eclipse ADT만 사용하다가 Android studio로 갈아탄 후 제작한 첫 앱인데, 처음엔 IDE가 익숙하지 않아 고생했지만 이런저런 시행착오를 한 덕에 Android studio에 익숙해졌다.

앱에 대한 설명을 간단히 하자면, 개인적으로 수영을 즐겨 하기에 내 수영 기록을 로컬 DB에 저장 관리하면서 그래프로 기록 추이를 나타내서 보여주면 좋겠단 생각에서 시작했다. 1주일 정도 짬짬히 시간을 내서 오픈소스와 기본 위젯들을 간단히 변형하여 완성했는데, 켤때마다 투박한 모습이 거슬려서 material 디자인 스타일의 위젯으로 전부다 갈아 엎었다.
기왕 깔끔하게 만들기로 작정한 참에 여러 사람이 쓸 수 있도록 공개해야겠다는 생각이 들어, 여러 사람들의 기록을 저장할 수 있도록 AWS를 이용해서 DB와 웹서버도 붙이고, 구글플러스 로그인 연동을 붙여 구색을 맞추어 놓았다.
IDE에 익숙해지려고 시작한 작은 프로젝트가 너무 커진다는 생각이 들어서, 웹서버쪽의 세세한 구현은 추후 반응이 있으면 추가 구현하기로 마음먹고 버전을 릴리즈했다. 첫 커밋을 한 후 정확히 한달 째 되던 날 코딩을 마무리하고 앱을 마켓에 등록했다.

나름 마켓에 등록한 앱이니 Crash report도 붙여놨는데, 작은 프로젝트들에 대하여 자주 사용했던 URQA (링크) 대신, Twitter Fabric(링크)을 대신 이용해 보았다.

Android Studio에 Fabric을 설치하는 것은 설명이 필요 없을 정도로 쉽다. 플러그인만 설치하면 되고, 이마저도 튜토리얼이 제공된다. 튜토리얼을 따라서 Fabric을 설치하고 나면 안드로이드 스튜디오가 알아서 프로젝트에 Crashlytics를 추가해준다. 추가한 후 에는 Fabric Answer 탭에서 아래와 같은 창을 볼 수 있다.

fabric_answer

DAU등과 더불어 각각의 Activity에 대한 세션 길이또한 보여준다.
덕지덕지 붙여놓은 Google Analytics가 무색해질만큼 간단한 정보는 편리하게 받아 볼 수 있다.

사실 이러한 기능보다 더욱 더 편리하다고 생각되는 것은 Beta라는 기능이다.
소규모 앱개발자들의 경우 베타테스터에게 앱을 릴리즈하고, 테스트 리포트를 받아보는 과정은 상당히 까다로운 과정이다.
APK를 일일히 보내서 업데이트하기도 번거롭고, 그렇다고 구글 플레이 스토어의 베타 업로드 기능을 사용하려면, 한번 업로드 하고 그 내용이 적용되기까지 몇시간은 그냥 날려먹어야 한다.

하지만 Beta를 이용하면 아래의 인터페이스를 통해 간단히 베타 버전을 릴리즈 할 수 있다.
fabric_beta

Add Tester 버튼을 통해 이메일 주소만 추가하면 해당 메일을 통해 베타 테스트 앱 링크가 날아가고,  해당 메일을 선택하여 Accept를 선택하면 Beta 앱이 베타테스터의 디바이스에 설치된다.mobile_beta-side

링크를 선택해 Beta를 실행시키면 위와 같이 베타버전 접속이 가능하다.
권한이 허가되면 마지막 화면과 같이 릴리즈 노트와 베타버전을 다운받을 수 있는 버튼이 표시된다.
베타 테스터들의 테스트 결과는 Crash report와 Fabric Answer에 바로 적용되고, Fabric 인터페이스를 통해 베타테스터의 권한을 회수하거나, 테스터마다 다른 권한을 주어 관리하고, 테스터 그룹을 생성/관리할 수 있다.

마지막으로 Crash report 항목이다.fabric_crash_reporting

위와 같이 어디서 크래쉬가 발생했고, 몇명의 유저가 영향을 받았는지 표시된다.
버전별, 시간대별로 정렬 가능하고 Jira와 같은 Issue 트래킹 시스템 만큼은 아니지만 간단히 Issue의 Open/Closed 상태도 관리가 가능하다.
issue_detail

상세 issue정보를 보면, 기기의 루팅 상태나 Storage, memory 상태들을 볼 수 있고 좀더 자세히 살펴보면crash_detail

위와 같이 기기 정보나, 배터리 정보, UI orientation 에 대한 정보도 출력된다. 커스텀 키를 설정해서 추가 정보를 받을 수도 있는 것 같은데, 여러모로 이슈 트래킹에 도움이 될 것으로 보인다.
issue_detail_closed

이슈를 close 하게되면 위와 같이 표시되며, Crash report 리스트 상에서는 취소선이 표시된다.

간단히 사용할 수 있고, 편리하지만 그렇다고 기능이 가볍지는 않다.
아직 세세한 기능까지는 사용해보지 않았고, Fabric 자체도 아직은 베타 버전이지만 지금까지의 상태만으로도 충분히 강력하고, 기대되는 모습을 보여준다. 특히 Beta의 강력한 베타테스터 배포 기능은 Fabric이 앞으로 널리 쓰이게 될 것이라는 확신을 갖게 해준다.

얼마나 사용히 간편한지 간단한 튜토리얼을 보고 싶다면, 아래의 링크에 접속해보시길 바란다.
http://www.crashlytics.com/blog/launching-beta-by-crashlytics/

Written by Ringster

2015/03/02 at 4:12 pm

Mac 안드로이드 스튜디오 단축키

leave a comment »

Android Studio의 정식버전이 릴리즈 된 이후로 간간히 Android Studio에 익숙해지려고 노력중이다.
Eclipse가 익숙하기도 하고, 형상관리 연동 설정 등이 모두 되있는터라 작업의 효율을 핑계로 계속해서 프로젝트를 Android Studio로 옮기는 것을 주저하고 있었는데 슬슬 더 이상 미룰 수 없는 시기가 다가오고 있는 것 같다.

새로운 툴을 사용하다보면 가장 먼저 부딫치는 것이 생소한 핫키들인데, Eclipse에서 편리했던 기능들에 대한 핫키들에 대해 정리해 보았다. 전체 설정된 핫키는 Android Studio -> Preference -> IDE Settings : Keymap 에서 찾을 수 있으며, 이 중 개인적으로 많이 쓰는 핫키들을 정리한 것임을 참고하길 바란다.

Option + Enter : 빠른 수정 (이클립스 코드에 빨간줄 생길 때 수정 항목 추천과 같은 기능)
Control + Space : 기본 코드 자동 완성
Control + O : Override / Implement methods
Control + Option + O : Optimize imports
Command + N : Generate code( Getters, Setters, Constructors, hashCode/equals, toString )
Control + Shift + Space : 스마트 코드 완성(예상되는 타입의 메소드또는 변수명 )
Command + Option + L : Reformat code

Command + Option + T : Surround with… (if..else, try..catch, for, synchronized, etc.)
Command + / : 한줄주석
Control + Shift + / : 블럭주석
Control + W : 연속적인 코드블럭 선택
Command + Shift + V : 클립보드 히스토리
Control + mouse over code : 간단한 설명
Shift + mouse over code : 약간 더 자세한 설명 (API version, superclass, interface)


며칠전 IR transmitter 관련 앱을 Android Studio로 작성해 보았는데, 라이브러리 추가나 핫키 등이 익숙하지 않아 애를 먹었다.
사실 Keymap 옵션을 보면 Eclipse 핫키에 맞추어 Android Studio 핫키를 변경시켜주는 옵션이 있는데, 일부러 해당 옵션을 사용하고 있지 않다.
사소한 것이지만 하나의 툴이나 하나의 언어에 익숙해지는 것보다, 새로운 것들에  계속 적응하고 익숙한 분야를 넓혀가는 것이 중요하다고 생각하기 때문이다.

P.S

– 아직은 Android Studio 자체에 자잘한 버그가 많은것 같기는 하다. IR transmitter를 사용하기 위해서

ConsumerIrManager irManager = (ConsumerIrManager)getSystemService(Context.CONSUMER_IR_SERVICE);

위 코드를 추가했는데, 계속 Context.CONSUMER_IR_SERVICE 부분에 구문 오류가 표시되어 뭐가 잘못되었는지 한참을 찾았는데, 그냥 컴파일을 수행하니 문제없이 컴파일이 수행되었다. (동일한 코드를 이클립스에서 사용 시에는 구문 오류가 출력되지 않는다.)
계속해서 개선되다보면 이런 버그들은 언젠가는 처리되겠지만, 사실 이런 사소한 문제들에 시간을 뺏길때마다 여러 사람들에 의해 검증된 이후 사용하고 싶기는 하다…

P.S 2
– 조만간 https://developer.android.com/tools/studio/index.html 에 대해서도 한번 훑어봐야겠다.

Written by Ringster

2015/01/22 at 4:23 pm

Yurim Jin, Programmer&Designer

Fork my brain because I'm ready to commit

jamesjungkuelee's biotech story

Biotech, entrepreneur, life

Communications as Ikor

기업 위기관리의 모든 것

Charles Pyo Ventures

시도와 실패, 성장의 기록. 2막에서도 계속되는 모험들.

techNeedle 테크니들

글로벌 테크 소식을 인사이트와 함께 전달합니다

Open API, Cloud, DevOps 와 eBook

Open API, eBook, Cloud, DevOps

Economics of almost everything

Tech, Mobile, Internet

cylee

Tech, Mobile, Internet

gorekun.log

고어쿤로그

Google Developers Korea Blog

Tech, Mobile, Internet

Android Developers Blog

Tech, Mobile, Internet

최피디의 앱스 개발기

기술, 앱스, SNS, 창업

D2 Blog

Tech, Mobile, Internet

All of Software

Tech, Mobile, Internet

'Startup's Story Platform’

'Startup's Story Platform’