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"
(ただしこれはエラーの発生を遅らせるだけだが)
これ以外、現在打つ手なし。
Androidアプリ開発で今後も流用できそうなサンプルを中心に主に「自分のために」投稿しています。 細かい説明はしません。とりあえずご参考まで。 ただし自己責任でお使いください。 開発は ICONIA TAB A500(Andorid 3.1,)、Sony Tablet S(4.1)で行っています。
2012年8月28日火曜日
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;
}
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
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フォルダへ移動
プロジェクトの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)
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>
登録:
投稿 (Atom)