Programming/Android2015.12.23 11:27

최근에 안드로이드 프로젝트를 새로 시작했습니다.

혼자하고 작은 프로젝트라서 Kotlin으로 하고 있습니다. (유지보수는 누가하지...)

Swift와 비슷해서 시작했는데 다른 부분이 더 많네요.

여러 부분에서 막히고 문서 보고를 반복하다가 방금 찾아 본 것을 남겨봅니다.


Android 에서 새로운 Activity를 실행하려고 할때 Activity 의 class type을 넣어줘야 하는데요.

Java

Intent intent = new Intent(this, MainActivity.Class);


Kotlin

val intent = Intent(this, javaClass())


위 방법은 현재 deprecated 입니다. 

현재 버전에서는 다음과 같이 사용해야 합니다.


Kotlin

val intent = Intent(this, MainActivity:class.java)


https://kotlinlang.org/docs/reference/java-interop.html#getclass

신고
Posted by 초프(초보 프로그래머)
Programming/Android2014.09.27 02:50

빌드해서 aar을 생성했는데… 그냥 dependency에 넣어서는 추가가 안된다. 뭐지;;


일단 duplicate 오류가 나면 aar과 겹치는 리소스가 있어서 그렇다.

그래서 모듈 리소스명 앞에 prefix를 붙여서 해결함.


그후 빌드는 성공했는데 class를 찾을 수 없다!!!!!! 뭐지…

compile fileTree(dir: 'libs', include: ['*.jar','*.jar'])
compile files('libs/chope-1.0.0.aar')


이 방법 둘다 안 먹힌다.


해결 방법은 다음과 같다.

aar은 꼭 repository에서만 추가되어야 하나 보다. 그래서 일단 local repository를 추가해준다.

repositories {
    flatDir {
        dirs 'libs'
    }
}

그리고 dependency는 다음과 같이 추가 한다.

compile(name:'chope-1.0.0', ext:'aar')


이제 빌드하면 제대로 나온다!~~!!

aar에 관련된 부분을 전체적으로 보면 다음과 같다.

repositories {
    flatDir {
        dirs 'libs'
    }
}

dependencies {
    compile(name:'chope-1.0.0', ext:'aar')
}


신고
Posted by 초프(초보 프로그래머)
Programming/Android2014.09.27 02:50

Android Module은 빌드되면 .aar (Android ARchive) 파일로 생성됩니다.

기본으로 build/outputs/aar 위치에 [module].aar 로 생성됩니다.

[module]-[version].aar 으로 변경하려면 아래와 같이 설정합시다!

android {
    .....

    buildTypes {
        release {
            project.archivesBaseName='chope'
            project.version=defaultConfig.versionName

            .....
        }
    }
}


신고
Posted by 초프(초보 프로그래머)
Programming/Android2014.09.12 01:16

Mac 을 Server로 하고 Android를 Client로 하여 서로 데이터를 주고 받도록 하는 것이 1차 목표였다.

둘의 통신은 BLE가 아닌 기본 Bluetooth 이다.

Mac은 IOBluetooth를 사용하지 않고 Python LightBlue library를 사용하여 작성하였다.

아래는 기본 테스트이므로 접속이 완료되면 데이터를 주고 받고 끝난다.


Android Code

package com.yhg.bluetoothclient;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Set;
import java.util.UUID;


public class MyActivity extends ActionBarActivity {
    private final int REQUEST_ENABLE_BT = 10;
    private final String SERVICE_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    private final String TAG = "ChopeTest";
    private BluetoothAdapter mBluetoothAdapter;

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

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, "bluetooth not supported", Toast.LENGTH_SHORT).show();
            return;
        }

        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
        else {
            connectServer();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_ENABLE_BT && resultCode == RESULT_OK) {
            connectServer();
        }
    }

    private void connectServer() {
        Set pairedDevices = mBluetoothAdapter.getBondedDevices();
        BluetoothDevice pairedDevice = null;

        if (pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                Log.d(TAG, device.getName() + "\n" + device.getAddress());

                // 테스트를 빠르게 하기 위해...
                pairedDevice = device;
                break;
            }
        }

        if (pairedDevice != null) {
            new ConnectThread(pairedDevice).start();
        }
    }

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        @TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
        public ConnectThread(BluetoothDevice device) {
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            BluetoothSocket tmp = null;
            mmDevice = device;

            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {
                // MY_UUID is the app's UUID string, also used by the server code
                tmp = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(SERVICE_UUID));
            } catch (IOException e) { }
            mmSocket = tmp;
        }

        public void run() {
            // Cancel discovery because it will slow down the connection
            mBluetoothAdapter.cancelDiscovery();

            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
            } catch (IOException connectException) {
                // Unable to connect; close the socket and get out
                connectException.printStackTrace();
                try {
                    mmSocket.close();
                } catch (IOException closeException) { }
                return;
            }

            // Do work to manage the connection (in a separate thread)
            ReaderThread thread = new ReaderThread(mmSocket);
            thread.start();
        }

        /** Will cancel an in-progress connection, and close the socket */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

    private class ReaderThread extends Thread {
        private InputStreamReader mReader;

        public ReaderThread(BluetoothSocket socket) {
            try {
                mReader = new InputStreamReader(socket.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            char[] buffer = new char[255];

            try {
                int len = mReader.read(buffer);
                String content = new String(buffer, 0, len);
                Log.d(TAG, "receive data : "+content);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


Python Code

import lightblue

s = lightblue.socket()
s.bind((lightblue.gethostaddr(), 0))  # bind to 0 to bind to dynamically assigned port 
s.listen(1)
lightblue.advertise("00001101-0000-1000-8000-00805F9B34FB", s, lightblue.RFCOMM)
conn, addr = s.accept()
print "Connected by", addr
conn.send("Hi Chope!")
conn.close()
s.close()


처음에 service uuid를 uuidgen으로 생성하니 연결이 안되서 한참을 헤맸다….

기존에 존재하는 service uuid만 사용해야 할것 같다.


실행해 보면 정상적으로 연결되는 것을 확인할 수 있다.


데이터를 계속 주고받는 테스트를 해봐야지 :)



신고
Posted by 초프(초보 프로그래머)
Programming/Android2014.08.26 17:10
android {
    defaultConfig {
        ndk{
            moduleName "moduleName"
            ldLibs "GLESv1_CM", "log"
        }
    }
}
신고
Posted by 초프(초보 프로그래머)

도서관 좌석 정보 v3.2.0 – Android

  • 전면광고 위치 변경
  • 좌석정보 공유하기 추가
  • 오류 수정


Download

신고
Posted by 초프(초보 프로그래머)
Programming/Android2014.06.11 01:29

Crashlytics (https://www.crashlytics.com) 는 crash 정보 수집을 하는 좋은 서비스입니다.

몇일 만에 접속하니 새로운 기능이 생겼습니다. 


Beta (http://try.crashlytics.com/beta)


간단히 봐서는 iOS의 TestFlight (https://testflightapp.com) 와 비슷한 동작을 하는듯 합니다.


이제 직접 체험해 보겠습니다.

Crashlytics Plugin 을 실행하고 apk파일을 드래그 합니다.



이 화면 뒤에는 테스터들의 email을 입력하면 끝이난다.

테스터들은 초대 메일을 받습니다.



모바일 디바이스에서 Let Me In 을 누르면 Beta 앱이 설치됩니다.



테스트를 원하는 앱을 선택합니다.



앱명, 패키지명, 버전명, 버전코드, 릴리즈노트 등이 표시됩니다.

테스트를 진행하려면 Download를 터치하세요.


iOS 앱 다운로드 처럼 진행상태가 표시되며 다운로드가 완료되면 설치화면이 나옵니다.



설치를 선택하세요.


완료되었다고 바로 '열기'를 누르시면 안됩니다.

Crashlytics Beta에서 테스터의 상태를 Lunch 로 변경하기 위해서는 완료를 누르고 Lunch를 터치하세요.



이제 테스트를 위한 준비가 모두 끝났습니다.

Dashboard에서 확인해 보면 현재 상태가 표시됩니다.


빠른 배포와 편한 테스트를 위해 많이 쓰였으면 좋겠네요.

테스터별로 issue 를 확인하고 싶었지만... crash를 발생시키지 못해 확인 못했습니다. ㅜ.ㅜ


Android 앱만 테스트했지만 곧 iOS도 테스트해볼 예정입니다.


2014/06/11 - [Programming/iPhone] - Crashlytics Beta 기능 - iOS


신고
Posted by 초프(초보 프로그래머)
Tools/VCS2014.04.18 12:02

두명이서 Android Studio로 개발을 하다 보니 build .ideal 폴더에 있는 파일때문에 계속 충돌이 발생합니다.

.gitignore를 아무리 적용해도 실제로 적용되지 않는군요...

제대로 적용한 것 같은데... 잘못 작성했나 해서 http://www.gitignore.io/ 여기에서 Android Studio, Android 키워드로 생성해서적용해도 반응이 없네요.

google 님에게 계속 물어 본 끝에 답변을 받았습니다.


git rm -r --cached .

git add .

git commit -m "fixing .gitignore"


생각보다 너무 간단하네요....;


출처)

Randall Kent / .gitignore not working

http://www.randallkent.com/development/gitignore-not-working

신고
Posted by 초프(초보 프로그래머)

벌써 3월 11일이네요..

새학기가 시작되는 달이라 다운로드 수가 어떻게 변경했는지 확인해 봤습니다.

예상대로 개강하자마자 다운로드가 많이 늘어 났는데 그것도 하루뿐이네요.


'도서관 좌석 정보' Android


'도서관 좌석 정보' iOS


실제 수치 차이는 크지만 Android, iOS모두 3/1에 큰 수치로 늘었습니다.

이번주 수치는 정확히 나오지 않아서 모르겠지만 아마 주말에 많이 올라갔을 것으로 보입니다.


신고
Posted by 초프(초보 프로그래머)
Programming/Android2013.10.16 00:54

WebView 의 loadData 매소드를 이용하여 html을 보여주는데 한글이 깨지는 현상이 발생했습니다.

그것도 Galaxy S 시리즈에서만... 


구글링을 하다 해결책을 찾아서 적용했습니다.

의외로 간단하지만....

webview.loadData(content, "text/html; charset=utf-8", "utf-8");

출처 : http://www.androidpub.com/index.php?mid=android_dev_qna&listStyle=webzine&page=10&document_srl=2344906&sort_index=voted_count&order_type=desc

신고
Posted by 초프(초보 프로그래머)