동적으로 생성한 view들을 조작하고 싶은데, 해당 view들에는 id가 할당되어 있지 않아 난감한 적이 있었다. 그 때 찾은 방법이 있는데 자세한 코드와 내용은 링크를 참고하자.


1
2
3
4
5
6
7
LinearLayout ll = 
final int childCount = ll.getChildCount();
for (int i = 0; i < childCount; i++) {
      View v = ll.getChildAt(i);
      // Do something with v.
      // …
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SparseArray<Edittext> array = new SparseArray<Edittext>();

private void findAllEdittexts(ViewGroup viewGroup) {

    int count = viewGroup.getChildCount();
    for (int i = 0; i < count; i++) {
        View view = viewGroup.getChildAt(i);
        if (view instanceof ViewGroup)
            findAllEdittexts((ViewGroup) view);
        else if (view instanceof Edittext) {
            Edittext edittext = (Edittext) view;
            array.put(edittext.getId(), edittext);
        }
    }

}



참고


android - Get all child views inside LinearLayout at once - Stack Overflow

블로그 이미지

NCookie

,

Activity와 Fragment의 설계 차이점이 궁금합니다



사실 안드로이드를 개발하면서 이해가 제일 되지 않던게 fragment였다. 액티비티랑 비슷한 역할을 하는데 context 같은거를 부르려면 귀찮은 과정을 거쳐야했다. 그래서 이걸 왜 쓰는지 한 번 알아보았는데 위 링크에서 잘 정리해준 것 같다.


그리고 나 같은 경우는 fragment를 사용하면 항상 코드가 난잡해졌었는데, 안드로이드의 개발 패턴 등에 대해서 공부를 해봐야 할 것 같다. 자세한 내용은 위의 링크를 참고하자.

블로그 이미지

NCookie

,

회사 연구소에서 RF팀이 spectrum analyzer와 PC를 연결해서 dB를 측정하는 프로그램을 사용하더라. 옆에서 RF팀 형을 도와드렸었는데 솔직히 프로그램 사용 방법도 너무 구식이고 불편한 점이 많은 것 같았다. 그래서 내가 직접 만들어보자!! 라는 생각을 하게 되었는데, 하... 생각보다 귀찮고 알아야할 내용들이 많았다. 일단 여기에 간단하게 핵심 개념들만 정리해보고 다음부터 개발에 들어가야할 것 같다.



현재 사용하고 있는 장비들의 정보는 아래와 같다.


Spectrum Analyzer : [Agilent] ESA-L SERIES E4403B

GPIB : [NATIONAL INSTRUMENTS] GPIB-USB-B



GPIB(IEEE 488.2)란


GPIB(General Purpose Interface Bus)는 전자 전기 엔지니어 협회(IEEE)에서 ANSI/IEEE 표준 488로 인정한 산업 표준이다. GPIB는 PC를 프로그램 가능한 계측기로 연결하는 인터페이스 시스템의 전자, 기계, 기능 및 소프트웨어 스펙을 규정한다. 


라고 National Instruments라는 회사의 GPIB 소개란에 써있었다. 그냥 계측 장비와의 통신 프로토콜 같은 것이라고 생각하면 될 것 같다. IEEE 488.2는 488에 업그레이드 버전이다.


이 회사가 GPIB 같은 계측 장비 통신과 관련해서 메이저한 기업인 것 같다. 관련 자료 찾아보면 대부분 이 회사꺼고 LabView도 그렇고... 어쨌든 GPIB는 저런 개념이고 자세한 내용은 굳이 알 필요도 없을 것 같아서 아래의 링크들로 대체하겠다.



VISA란?


카드사 이름이 아니다. 일반적으로 NI-VISA라고 지칭되는 VISA(Virtual Instrument Software Architecture API)를 이용하여 GPIB, USB, 시리얼, 그리고 이더넷 같은 대부분의 instrumentation bus와 통신할 수 있다. VISA는 일관되고 사용하기 쉬운 command set을 제공하여 다양한 계측장비와 통신한다.


VISA는 플랫폼, 버스 및 환경과 독립적이다. 다시 말해, Windows에 설치된 LabVIEW를 이용하여 USB 디바이스와 통신하는 프로그램이나, Mac OS X에서 C를 이용하여 GPIB 디바이스와 통신하는 프로그램이던, 관계없이 동일한 API를 사용할 수 있다는 것이다.



정리하자면, GPIB, IEEE 488.2는 계측장비와 PC간의 프로토콜이고, VISA는 이 프로토콜을 여러 플랫폼에서 동일한 방법으로 사용할 수 있도록 추상화시킨 API이다. 아마 개발은 이 VISA라는 것을 사용하여 하게 될 것 같다.



참고


GPIB 이란?


GPIB란? - National Instruments


IEEE-488 - 위키백과, 우리 모두의 백과사전


NI-VISA Overview - National Instruments


USB 인스투르먼트 컨트롤 튜토리얼 - National Instruments






블로그 이미지

NCookie

,

회사에서 이 라이브러리를 사용하게 되어서 주요 함수들에 대한 주석들을 번역해보았다.(github 주소)




[BleManager.java]



shouldAutoConnect()

protected boolean shouldAutoConnect() {
return false;
}


원격 디바이스에 한번만 연결할지(false), 아니면 사용 가능하게 되면 즉시 자동으로 연결될 디바이스 white list에 주소를 추가할지(true)를 반환한다. 후자의 경우, 블루투스 어댑터가 enable 되면 white list에 있는 디바이스들을 주기적으로 스캔하고, advertising packet을 수신하게 되면 그 디바이스에 연결하려고 시도한다. 연결이 끊겼을 때, 시스템은 그 디바이스에 재연결을 하려고 시도할 것이다. 이 함수가 true를 반환하고 디바이스 연결이 끊기면 BleManagerCallbacks의 onDeviceDisconnected 대신 onLinklossOccur 콜백 함수가 호출된다.


* 이 기능은 최신 기종의 안드로이드 디바이스에서 더 잘 작동하며, 오래된 디바이스는 동작하지 않을 가능성이 높다.

* 이 메서드는 bonded 디바이스만 사용되어야 한다. 그렇지 않은 디바이스들은 주소가 바뀔 수 있다. It will however work also with non-bonded devices with private static address. A connection attempt to a device with private resolvable address will fail(이 부분은 어떤 내용인지 잘 모르곘음)

* 디바이스의 첫 번째 연결은 항상 autoConnect 플래그가 false가 된다(BluetoothDevice의 connectGatt 함수 참고). 대부분의 사용자가 빠른 응답을 기대하고 있기 때문에 이러한 방법을 사용한다. 그러나 처음 연결하는 동안 이 메서드가 true로 반환되고 링크가 손실된 경우 manager 객체는 autoConnect를 true로 강제하는 BluetoothGatt의 connect 함수를 사용하여 reconnect 하도록 시도할 것이다. 



블로그 이미지

NCookie

,

어떤 프로그램이든 릴리즈를 할 때에는 개발 때 사용했던 로그가 찍히지 않도록 해야한다. 안드로이드에서는 기본적으로 Logger를 제공해주는데, 디버깅을 할 때에는 로그가 보여지도록 아래와 같이 커스텀 클래스를 만들 수 있다.


import android.util.Log;

public class Logger {
private static final String LOG_TAG = "APP_NAME";
private static final String FORMAT = "[%s]: # %s";

public static void v(String msg) {
if (!BuildConfig.DEBUG) return;
Log.v(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void d(String msg) {
if (!BuildConfig.DEBUG) return;
Log.d(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void i(String msg) {
if (!BuildConfig.DEBUG) return;
Log.i(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void w(String msg) {
if (!BuildConfig.DEBUG) return;
Log.d(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

public static void e(String msg) {
if (!BuildConfig.DEBUG) return;
Log.e(LOG_TAG, String.format(FORMAT, getCallerInfo(), msg));
}

private static String getCallerInfo() {
StackTraceElement[] elements = new Exception().getStackTrace();
String className = elements[2].getClassName();
return className.substring(className.lastIndexOf(".") + 1, className.length()) + "_" + elements[2].getLineNumber();
}
}


기존에는 Log에 사용할 TAG를 CLASSNAME.class.getSimpleName() 메서드를 사용했었는데, 클래스 이름을 아래의 두 가지 방법을 통하여 얻을 수 있다. 자세한 내용은 첨부된 첫 번째 링크를 참고하자.


  • Thread.currentThread().getStackTrace()
  • new Exception().getStackTrace();


어플리케이션이 디버깅 중인지, 릴리즈 상태인지를 알기 위해서는 다양한 방법이 있는데, 여기서는 BuildConfig를 사용하였다.



참고


[안드로이드] 커스텀 Logger 클래스 만들기


Log | Android Developer


stack overflow - 

Detect if I am in release or debug mode in android


블로그 이미지

NCookie

,