2012年8月28日火曜日

Out of Memory

Bitmapを使っているときにOut of Memoryエラーが発生
(何回か実行しているうちに、Heapが足りなくなってエラー)

ネットであちこち探しまわったが、結局解決策はない。

  bitmap.recyle();
  bitmap = null;
をやってもだめ。

GCは当てにならないらしい。
System.gc();をやってもだめ。

結局、bitmapのサイズをできるだけ小さくするしかない。
Cameraを使っているなら、PictureSizeを小さくする。
   params.setPictureSize(800,600);
画像ファイルを使うなら、縮小する

   BitmapFactory.Options opts = new BitmapFactory.Options();
   opts.inSampleSize = 2; // サイズ縮小

   Bitmap bitmap = BitmapFactory.decodeFile(file,opts);
ManifestでHeapサイズを大きくする

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
(ただしこれはエラーの発生を遅らせるだけだが)

これ以外、現在打つ手なし。

2012年8月21日火曜日

Bitmapの解放

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@407ed350

bitmap.recycle();を実行したとき、まだ使ってるから解放できない、というエラー

対策:onPauseでまとめて解放する。


@Override
public void onPause()
{
  super.onPause();
  //Bitmap解放
detect1.setImageBitmap(null);
bitmap.recycle();
bitmap = null;
}

2012年7月11日水曜日

AutofocusでJPEG保存


     //*************************
    // Auto Focus後に画像を保存
    //*************************
        private Camera.AutoFocusCallback mAutoFocusListener =
           new Camera.AutoFocusCallback() {
           public void onAutoFocus(boolean success, final Camera camera)
           {
            Log.v(TAG, "AutoFocued");
            //camera.autoFocus(null); //これがあるとフォーカスのとれた画像が取れない
             camera.takePicture(null, null, jpgList);            
           }
         
        };


        private PictureCallback jpgList = new PictureCallback() {
       
        public void onPictureTaken(byte[] data, Camera camera)
        {
                 if (data != null)
                 {
                 //JPEGdataそのままファイル保存
            _path = DATA_PATH + "ocr.jpg";  
            try {
FileOutputStream foStream = new FileOutputStream(_path);
foStream.write(data);
foStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
camera.startPreview();
return;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
camera.startPreview();
return;
}
            Log.v(TAG, "onPictureTaken");  
                }
                 camera.startPreview();
        }
        };


Carema PreviewをJPEGに保存


ただしフォーカスはうまくとれない
AutoFocusCallback後にtakePictureするほうが良い

      private Camera.PreviewCallback mPrevCallback = new Camera.PreviewCallback()
      {
          //@Override
          public void onPreviewFrame(byte[] data, Camera camera)
          {
        Log.v(TAG, "Preview ");

              if (data != null)
              {
             
           //rawデータをJPEGファイルに変換
              Log.v(TAG, "Save JPEG " + _path);
              camera.addCallbackBuffer(data);
               Camera.Parameters params = camera.getParameters();
               Camera.Size size = params.getPreviewSize();
               YuvImage image =new YuvImage(data,params.getPreviewFormat(),
                size.width, size.height, null);
               File file = new File(_path);
               FileOutputStream out = null;
               try {
out= new FileOutputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
               image.compressToJpeg(
                       new Rect(0, 0, image.getWidth(), image.getHeight()), 100,
                       out);
               try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
                                         
              }

          camera.startPreview();

          }
         
      };

2012年6月29日金曜日

NDK & OpenCV

Android NDK をc¥にインストール
cgwin をインストール
(最近はcgwinはいらないようだ)
  make,gccを指定
/home/(user)/.bashrcの最後に
export ANDROID_NDK_ROOT=/cygdrive/c/android-ndk
   export PATH=$PATH:$ANDROID_NDK_ROOT

OpenCV(バイナリ)とAndroid projectは同じフォルダ、かつスペースの無いフォルダ名。すなわちMy Documentの下はだめ。

プロジェクトのjni/Andorid.mk修正
 
include ../OpenCV/share/openCV/OpenCV.mk <<下をこれに変える
#include ../includeOpenCV.mk
#ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
#    #try to load OpenCV.mk from default install location
#    include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk
#else
#    include $(OPENCV_MK_PATH)
#endif

cygwinウィンドウ またはコマンドウインドウでもよい
プロジェクトのTOPフォルダへ移動
C:\android-ndk\ndk-build

  /obj/local/armeabi-v7a/libgnustl_static.a: No such file: Permission denied
 このエラーが出たら
  chmod 777 obj/local/armeabi-v7a/libgnustl_static.a
   で再度ndk-build

\OpenCV-2.3.1\libs\armeabi-v7a内のライブラリはbuild時に参照するが、
apkインストール時には重複エラーになるので、名前を変えておく。
必ずbuild前には戻すこと。

注意)
cソースのJNIEXPORT void JNICALL文の関数名にプロジェクト名とクラス名が含まれているので、これらを変更したときは、ndk-buildをし直す必要がある。

例)
JNIEXPORT void JNICALL Java_com_androidgroup_nyartoolkit_ARToolkitDrawer_decodeYUV420SP(JNIEnv * env, jobject obj, jintArray rgb, jbyteArray yuv420sp, jint width, jint height, jint type)

2012年6月11日月曜日

他のアプリを起動する


アプリを起動するとき

            Intent intent1 = new Intent();
            intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            // パッケージ名, クラス名をセット
            intent1.setClassName(pac,clas);
            startActivity(intent1);

pac : パッケージ名
clas : クラス名
(GetIntentCalssNameというアプリで調べる)

標準の設定アプリの場合はこれだけ

           Intent intent1 = new Intent("android.settings.SETTINGS");
           startActivity(intent1);

パワーオンでアプリ起動


レシーバークラス StartReceiver.java

public class StartReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context arg0, Intent arg1) {

 Toast toast=Toast.makeText(arg0,"Boot...",Toast.LENGTH_LONG);
      toast.show();
     
     Intent i = new Intent(arg0, Activity.class);  //起動するアクティビティ指定
     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     arg0.startActivity(i);
   
   
  }
}

Manifest設定

・ユーザパーミッション

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>

・レシーバー設定

        <receiver android:name="com.widebright.tabmanager.StartReceiver"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
             <intent-filter>
                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
             </intent-filter>
       </receiver>