Android2015. 2. 8. 18:59

먼저, 밑의 참고 사이트를 참고해 만든 예제 소스를 먼저 올리겠습니다.


UTubeTest.zip


검색어를 가지고 유튜브에서 검색한 후 결과를 리스트뷰로 보여주는 예제인데요.


두가지를 짚고 넘어가겠습니다.



첫번째로, StartActivity를 보시면 검색 시에 get방식으로 정보를 전달하는걸 볼 수 있습니다. 어떤 name으로 무슨 정보를 전달해야 하는지는 다음의 링크를 참고하시기 바랍니다.


https://developers.google.com/youtube/v3/docs/search


첨부한 예제에는 반환되는 리스트의 갯수를 20개로 늘려놨습니다. (기본은 5개입니다)



두번째로는, 서버 키를 얻는 방법입니다.


https://console.developers.google.com/project


에 가셔서 프로젝트를 하나 생성한 후, 그 프로젝트를 클릭하면 왼쪽에 API 및 인증이 보입니다. 그 하위메뉴인 API에서 YouTube Data API v3활성화 해야합니다.


그 후, 사용자 인증 정보에서 공개 API 액세스를 위해 새 키를 만들어야 하는데요


새 키 만들기 클릭 후 서버 키를 만드세요.


그리고 안드로이드 폰의 IP주소를 구해서(www.ipip.kr) 해당 IP주소를 요청 허용해주세요.


이제, 만들어진 서버 애플리케이션 키의 API키를 첨부한 예제의 StartActivity와 MainActivity에 각각 넣어야 정상 작동 됩니다.



구글 GCM를 사용하거나 기상청 정보를 얻을 때 이러한 방법이 종종 이용되곤 하죠.


또한 유튜브에 요청한 데이터 결과는 JSON 형식으로 돌아오는데 알맞게 파싱하여 사용해야 합니다.


다행히 관련 라이브러리가 있어서 편하게 사용할 수 있네요.



참고 사이트 : http://ondestroy.tistory.com/49

API 가이드 : https://developers.google.com/youtube/v3/







Posted by 너를위한노래
Android2015. 1. 27. 20:40

어플에 바코드나 QR코드 인식 기능을 넣는 방법엔 두가지가 있습니다. 첫번째는 intent로 바코드 인식 기능이 있는 앱(ex.바코드리더기)을 실행시킨 후 결과를 받는거구요, 두번째는 아예 앱 자체에 바코드 인식 기능을 넣어버리는 겁니다.


첫번째 방법은 구현하기 매우 간단하지만 바코드리더기 앱이 없고 인터넷이 안되는 상황이라면 만든 앱이 정상작동을 안하겠죠..


두번째는 라이브러리 구해서 추가하고 매니패스트 수정하고 등등 할게 많지만 독립적으로 운용 가능한 앱을 만들 수 있다는 장점이 있습니다.


이번 포스팅에서는 두번째 방법에 대해 간단히 설명하려 합니다. 자세한 설명은 밑의 출처 링크를 클릭해서 보시구요. 저는 겪은 시행착오에 대해 언급하겠습니다.


먼저, 출처에 소스코드가 있지만 혹시나 해서 여기에도 올리겠습니다.


zxing_exam.zip


먼저 만들어진 앱에 이 부분만 붙이신다면 우선 core.jar를 옮겨야 하구요.


com.google.zxing.client.android

com.google.zxing.client.android.camera

com.google.zxing.client.android.integration

com.google.zxing.client.android.result


그리고 이 네개의 패키지를 모두 옮겨야 사용 가능합니다.


물론 매니페스트나 xml파일은 위 패키지들 안의 소스에 맞게 수정하고 옮기셔야 작동하겠죠


이렇게 해서 바코드 스캐너 기능을 가진 앱을 만들 수 있는데, 약간 꺼림칙한 부분이 있어요. 단말기에 바코드 스캐너 앱이 여러개 설치되어있는 경우, 어떤걸 열건지 물어보는 창이 뜨게되는데 아마 intent 이름이 같아서 선택하라고 뜨는것 같습니다. 우리는 앱 내부에 있는 클래스(CaptureActivity)를 열기 때문에 다른 앱은 필요가 없죠. 이걸 없애는 방법은 다음과 같습니다.


IntentIntegrator 클래스에서

Intent intentScan = new Intent("com.google.zxing.client.android.SCAN"); 부분을

Intent intentScan = new Intent(activity, CaptureActivity.class); 로 바꾸고


CaptureActivity클래스에서

if (intent != null && action != null) 부분의 else 부분에 

source = Source.NONE;

decodeFormats = null;

characterSet = null;

가 있는데 이걸

Source.NATIVE_APP_INTENT;
decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);

로 바꾸면 됩니다.


여러군데 흩어져 있는 정보를 짜깁기해서 만든 포스팅이라 좀 혼잡하네요.. 



출처 - http://theeye.pe.kr/archives/1339








Posted by 너를위한노래
Android2014. 11. 28. 16:10

이번에는 안드로이드 NDK개발환경 구축에 관해서 간단하게(스크린샷 없이) 포스팅 할건데요, 제 얕은 지식으로 이해한 바를 최대한 써보겠습니다. ㅜㅜ


개발환경 구축에 필요한 툴과 라이브러리는 다음과 같습니다.


JDK

JDK_7_51 - (http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html#jdk-7u51-oth-JPR)

환경변수 설정

이클립스

케플러 - (http://www.eclipse.org/downloads/packages/release/Kepler/SR2)

안드로이드 ADT설치 (help - install new software)

안드로이드

SDK - adt-bundle-windows-x86_64-20140321

안드로이드용 OpenCV

OpenCV-2.4.9-android-sdk

안드로이드 NDK

android-ndk-r10c-windows-x86_64


다운로드, 설치 방법과 경로 설정 등은 다른 블로그에 많이 나와있으니 생략하겠습니다.


모두 설치하셨다면, 프로젝트를 만들어야 할텐데요. 맨땅에다가 만들지 않고 예제를 수정하는 방법으로 만드려고 합니다.


OpenCV 예제 중 OpenCV Tutorial 2 - Mixed Processing 이라는 예제가 있을텐데요, 이 안에서는 CameraBridgeViewBase로 카메라를 다루지만 AutoFocus기능을 사용하기 까다롭더라구요 (Camera객체를 만들어서 start시키려고 하면 CameraBridgeViewBase와 충돌하는 듯 합니다). 하지만 NDK개발이 가능합니다.


그리고 OpenCV Tutorial 3 - Camera Control 이라는 예제는 CameraBridgeViewBase를 상속받은 JavaCameraView를 사용해서 카메라를 다루는데, 이 클래스 안에 mCamera가 Camera 객체이기 때문에 AutoFocus기능을 사용하기 수월합니다. 하지만 NDK개발 구축이 안되어있습니다.


이 두 예제를 합칠건데요, 일단 그냥 Tutorial 2 의 패키지를 지워버리고  Tutorial 3의 패키지를 가져오는 식으로 하셔도 됩니다. 


다만 두 프로젝트간에 다른건 조정 해줘야합니다. Menifest파일의 패키지와 액티비티 이름, 옮긴 후 액티비티의 onCreate에서 레이아웃 이름 등등은 알아서 조절하시길 바랍니다.


이렇게 해서 만들어진 프로젝트는 JavaCameraView의 mCamera를 이용한 AutoFocus가 가능하고, JavaCameraView의 onCameraFrame에서 OpenCV영상처리도 가능하며 onCameraFrame에서 native 함수를 호출함으로써 NDK 영상처리 개발도 가능합니다.




Tip : native 함수는 Java_com_abc_core_MainActivity_func() 처럼 생겼는데 맨 처음 Java는 고정이고 다음은 com.abc.core.MainActivity라는 액티비티의 func()함수로 사용하겠다는 의미입니다. 즉 위처럼 선언된 네이티브 함수는 com.abc.core.MainActivity 액티비티에 public native void func(); 이렇게 선언되어있어야 합니다. 오타가 나거나 경로가 틀리면 native 함수를 찾을 수 없다고 출력되며 앱이 종료됩니다.





Posted by 너를위한노래
Android2013. 7. 18. 11:20

사실 안드로이드와 아두이노간의 통신을 구현한거는 좀 오래돼서 기억을 더듬어 포스팅합니다.

 

먼저 시리얼 통신은 진저브레드 이상의 안드로이드 OS버전에서만 작동한다고 하니 참고하시구요~

 

맨 바닥부터 코딩할 순 없으니 시리얼통신 라이브러리를 사용하겠습니다.

 

 

usb-serial-for-android-v010.jar

 

출처는

 

https://code.google.com/p/usb-serial-for-android/

 

입니다. 위의 링크로 가시면 Quick Start 부분에 사용 방법이 다 나와있네요.

 

하지만 링크의 예제 소스만 가지고는 통신을 원활히 할 수가 없더라구요.. 한 바이트 읽고 쓰는거는 아주 쉽지만 패킷을 만들어서 전송하려면

약간의 프로그래밍이 따라야 합니다.

 

먼저, BaudRate부분이 115200으로 되어있는데 이거 안돼요. 저는 Arduino MAGE2560을 사용했는데 9600빼고는 아무것도 안되더라구요..

이거때문에 몇시간을 날려먹은건지 ㅠ

 

그리고 패킷 제작은 사용하시는 분 마음대로 규격을 정하셔도 괜찮을거 같아요. 저는 모든 정보를 문자로 변환한 후 알파벳으로 구분했습니다.

 

"a1.23b2.34c3.45z" 이렇게요. 그러면 전송받은 측에서 a, b사이의 문자("1.23")을 빼 낸 다음에 숫자(1.23)로 변환하는 방법을 사용했습니다.

 

패킷을 송신 했다면, 수신을 해야할텐데 코드 작성 전에 문득 이런 생각이 들더군요

 

'한 패킷 전송 속도와 안드로이드 반복문의 속도가 다르면 패킷이 잘릴까?' '패킷이 잘린다면 다음번에 수신된 나머지 패킷과 연결할 순 없을까?'

 

그래서 고민하다 링 버퍼를 만들었습니다. 패킷보다 긴(2배이상) 충분한 저장공간(배열)을 만들어 놓고 수신한 바이트들을 배열 안에 순서대로

차곡차곡 쌓아 두는거죠. 차례대로 쌓여있다면 그 배열을 검사하면서 내가 정한 패킷에 맞는 데이터가 있다면 빼서 사용하는겁니다.

 

밑에 소스 첨부 하겠습니다~ 어떤 함수를 사용했는지 참고하시고 자신만의 통신을 구현해 보시길~

 

 

 

 

----------------------------------------------- 7월 27일 추가내용 --------------

http://procider.tistory.com/201

저는 Arduino MEGA2560 사용하는데요, 위 블로그에 나와있는 젠더를 사용해서 전력 공급을 해결했습니다~

Arduino MEGA ADK for android 는 젠더가 없어도 될거같습니다~

 

Posted by 너를위한노래
Android2013. 4. 1. 15:08

 

칼만필터 적용 과정중에 구현한 행렬 연산 소스입니다.

 

안드로이드에서 만든건데 당연히 자바에서도 되겠네요

 

4x4 행렬의 덧셈, 뺄셈, 곱셈을 이중 for문으로 계산해서 반환해줍니다.

 

행렬 연산하시는분 참고하세요~

 

 함수 정의 부

 // 4x4 행렬 덧셈
  double[][] matrix_plus(double[][] A, double[][]B) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      C[i][j] = A[i][j] + B[i][j];
     }
     
    }
   return C;
  }
  // 1x4 행렬 덧셈
  double[] matrix_14plus14(double[] A, double[] B) {
   double[] C = new double[4];
   for(int i=0; i<4; i++) {
      C[i] = A[i] + B[i];
    }
   return C;
  }
  // 4x4 행렬 뺄셈
  double[][] matrix_minus(double[][] A, double[][]B) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      C[i][j] = A[i][j] - B[i][j];
     }
     
    }
   return C;
  }
  // 1x4 행렬 뺄셈
  double[] matrix_14minus14(double[] A, double[]B) {
   double[] C = new double[4];
   for(int i=0; i<4; i++) {
      C[i] = A[i] - B[i];
     }
   return C;
  }
  // 4x4 행렬 곱셈
  double[][] matrix_mul(double[][] A, double[][]B) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
     for(int k=0; k<4; k++) {
      C[i][j] += A[i][k] * B[k][j];
     }
     
    }
   }
   return C;
  }
  // 1x4 * 4x4 행렬 곱셈
  double[] matrix_14mul44(double[] A, double[][]B) {
   double[] C = new double[4];
   for(int i=0; i<4; i++) {
     for(int j=0; j<4; j++) {
      C[i] += A[j] * B[j][i];
     }
   }
   return C;
  }
  // 4x4 행렬 전치
  double[][] matrix_transed(double[][] A) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      C[i][j] = A[j][i];
    }
   }
   
   return C;
  }
  // 4x4 행렬 역행렬
  double[][] matrix_inverse(double[][] A) {
   
   double[][] C = new double[4][4];
   
   Matrix mat = new Matrix(4,4);     // Matrix.java는 파일첨부
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
     mat.values[i][j] = A[i][j];
    }
   }
   Matrix.Invers inv = mat.new Invers();
   C = inv.Invers(mat);
   
   return C;
  }

 

밑에 소스는 구글링에서 퍼온건데.. 기억이 안나네요 ㅠㅠ (아시는분 댓글 달아주시면 바로 출처 올리겠습니다~)

 

4x4 역행렬 연산에 쓰이는 Matrix 클래스입니다.

 

 Matrix.java

 public class Matrix {
 public int row; // 행 전역변수 선언
 public int col; // 열 전역변수 선언
 public double[][] values; // 2차원 배열 행렬 전역변수 선언

 public Matrix(int row, int col) { // 생성자 Matrix 생성
  this.row = row; // 행의 값을 받는다.
  this.col = col; // 열의 값을 받는다.
  values = new double[row][col];// 전역변수 values에 row값과 col값을 넣어준다.
 }

 class Invers // Invers 메소드
 {
  determi det = new determi(); // 행렬식을 이용하기 위해 불러옴

  public double[][] Invers(Matrix mat) {
   Matrix inv = new Matrix(mat.row, mat.col); // 역행렬을 저장한 행렬 생성
   Matrix cofactor = new Matrix(mat.row, mat.col);
   double de = (double) 1 / det.data(mat);

   if (det.data(mat) == 0) // 행렬식이 0일 경우
   {
    System.out.println("역행렬이  있지 않습니다.");// 메세지 툴력
    System.exit(0); // 그리고 시스템 exit
   }

   for (int i = 0; i < mat.row; i++) { // 0부터 행 값까지 반복
    for (int j = 0; j < mat.col; j++) {// 0부터 열 값까지 반복
     cofactor.values[i][j] = Mino(mat, i, j);
     inv.values[j][i] = de * Math.pow(-1, i + j)
       * cofactor.values[i][j];
    }
   }
   return inv.values;// inv를 리턴한다.
  }
  
  public double Mino(Matrix mat, int r, int c) {// 여인수전개를 위한 메소드
   double cof;
   Matrix minor = new Matrix(mat.row - 1, mat.col - 1);
   int k = 0;
   if (k == r) {
    k++;
   } // C_ij의 소행렬은 i행j열을 제외하므로 이런 if를 쓴다.
   for (int i = 0; i < minor.row; i++) // 0부터 행값까지 반복
   {
    int l = 0; // l은 초기값으로 0
    if (l == c) {
     l++;
    }// l값이 열값과 같다면 l증가
    if (k == r) {
     k++;
    }// k값이 행값과 같다면 k증가
    for (int j = 0; j < minor.col; j++) {
     if (l == c) {
      l++;
     } // 열값과 같아면 l증가
     minor.values[i][j] = mat.values[k][l];
     l++;
    }
    k++;
   }
   cof = det.data(minor);// 소행렬을 구해 반환
   return cof;
  }
 }

 static class determi {
  static int order;
  static double[][] matrix;

  public double data(Matrix mat) // 행렬식을 구할 행렬을 받는다.
  {
   matrix = new double[mat.row][mat.col];
   order = mat.row; // order는 받은 행렬의 행의 수이다.
   for (int i = 0; i < mat.row; i++)// i를 행의수만큼 돌리고
   {
    for (int j = 0; j < mat.col; j++) // j는 열의수만큼 돌려서
    {
     matrix[i][j] = mat.values[i][j]; // matrix에 mat과 같은 값을 넣는다.
    }
   }
   return compute(); // 리턴을 compute함수로 시켜준다.
  }

  public static double compute() // 그럼 여기로 오는데,
  {
   double check[] = new double[20]; // check란 20칸짜리 배열을 만든다.
   double det = 0; // det는 초기화하고
   int row, col = 0; // row와 col도 초기화선언한다.
   for (row = 0; row < order; row++) // row는 받은 행의 수 만큼 돌리고
   {
    check[row] = 1; // 이때 check의 행의수만큼의 index를 1로 지정
   }

   if (order == 1)// 만약 order가 1이면
   {
    det = matrix[0][0]; // det는 a11값이 된다.
   }

   for (row = 0; row < order; row++) // 다시 row를 수만큼 돌림
   {
    check[row] = 0;// row[i]에 0을 집어넣음
    det += matrix[row][0] * Math.pow(-1, row)
      * minor(row, col + 1, check);
    // det를 1열의 수 곱하기 minor함수에서 받은 값으로 온다
    check[row] = 1; // 이렇게 계산 되면 다시 check를 1로 해준다.
   }
   return det; // det 값을 반환
  }

  public static double minor(int Row, int Col, double trans[]) {
   double result = 0;// 결과값으로 초기값을 0을 준다.
   int i = 0;
   if ((order - Col) == 0) {
    return 1;
   }
   for (int row = 0; row < order; row++)// 0부터
   {
    if (trans[row] != 0)// 만약 trans[row]가 0이 아니라면
    {
     trans[row] = 0; // 0을 넣어준다.
     result += matrix[row][Col] * Math.pow(-1, (double) i)
       * minor(row, Col + 1, trans);
     // 여인수전개에 의한 식이다. 재귀함수로 계속 돌리게된다.
     trans[row] = 1; // trans[row]에 1을 넣어준다.
     i++;// i 값 증가
    }
   }
   return result; // result 반환
  }
 }

}


 

 

Posted by 너를위한노래