フロントカメラを使おうとしたが、うまくいかない。真っ黒画面。
ネットでも情報が少ない。
結果(変更点)
mCamera = Camera.open(1); //フロントカメラ指定
//params.setFocusMode(Camera.Parameters.FLASH_MODE_AUTO);
//FLASHが使えないのでこれがあるとだめ。
//params.setPictureSize(800,600);
//フロントは640x480が最大なのでこれもカット
あとはビットマップ処理があれば、この解像度を意識しないとだめ。
Androidアプリ開発で今後も流用できそうなサンプルを中心に主に「自分のために」投稿しています。 細かい説明はしません。とりあえずご参考まで。 ただし自己責任でお使いください。 開発は ICONIA TAB A500(Andorid 3.1,)、Sony Tablet S(4.1)で行っています。
2012年9月13日木曜日
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"
(ただしこれはエラーの発生を遅らせるだけだが)
これ以外、現在打つ手なし。
(何回か実行しているうちに、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;
}
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>
2012年6月8日金曜日
ソース難読化
逆コンパイルでソースを盗まれないように難読化する
ADT18以前
project.propetiesに追加
proguard.config=proguard.cfg
ADT18以降
project.propetiesに追加
proguard.config=android-sdk/tools/proguard/proguard-android.txt:proguard-project.txt
(proguard.cfgは無く、共用ファイルと個別ファイルに分かれた)
Dalvik format faild with error1 が出る場合は、SDKのバグを修正
\android-sdk\tools\proguard\bin\proguard.bat
最後の行を以下のようにする(%1 %2 %3 %4 %5 %6 %7 %8 %9の部分)
call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
2014/5/12追記
apacheのライブラリを使うときは以下を、proguard.project.txtに追加する
# Ignore warning
-dontwarn org.apache.**
ADT18以前
project.propetiesに追加
proguard.config=proguard.cfg
ADT18以降
project.propetiesに追加
proguard.config=android-sdk/tools/proguard/proguard-android.txt:proguard-project.txt
(proguard.cfgは無く、共用ファイルと個別ファイルに分かれた)
Dalvik format faild with error1 が出る場合は、SDKのバグを修正
\android-sdk\tools\proguard\bin\proguard.bat
最後の行を以下のようにする(%1 %2 %3 %4 %5 %6 %7 %8 %9の部分)
call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
2014/5/12追記
apacheのライブラリを使うときは以下を、proguard.project.txtに追加する
# Ignore warning
-dontwarn org.apache.**
リリース用証明書とパッケージ作成
証明書発行とパッケージ作成
eclipseで対象プロジェクト、右クリック
Android Tools - Export Signed Application Package
証明書は新規作成か、既存のものを使用 xxxx.keystoreができる
証明書付パッケージ xxxx.apkができる
(Google MAP APIを使っている場合は、この証明書を先に作って、APIキーを入手してソースに埋め込む必要がある)
インストール
コマンドツール adb install -r xxxxx.apk
Batファイルにしておくとクリックでインストールできる install.bat等
eclipseで対象プロジェクト、右クリック
Android Tools - Export Signed Application Package
証明書は新規作成か、既存のものを使用 xxxx.keystoreができる
証明書付パッケージ xxxx.apkができる
(Google MAP APIを使っている場合は、この証明書を先に作って、APIキーを入手してソースに埋め込む必要がある)
インストール
コマンドツール adb install -r xxxxx.apk
Batファイルにしておくとクリックでインストールできる install.bat等
画面キャプチャ
AndroidをUSBケーブルでPCに接続
コマンドツールの場合
ddmsと入力
Deviceメニュー、Screen captureをクリック
eclipseの場合
DDMSのDeviceタグの、Screen captureアイコンをクリック
リアルタイム表示
java -jara asm.jar
Android Screen Monitor (asm.jar)は以下からダウンロード
http://code.google.com/p/android-screen-monitor/
コマンドツールの場合
ddmsと入力
Deviceメニュー、Screen captureをクリック
eclipseの場合
DDMSのDeviceタグの、Screen captureアイコンをクリック
リアルタイム表示
java -jara asm.jar
Android Screen Monitor (asm.jar)は以下からダウンロード
http://code.google.com/p/android-screen-monitor/
Video再生
private MediaController mc;
private VideoView videoView;
private ProgressDialog waitDialog;
String url; //ここに再生したいビデオのURLを入れる
try {
//ビデオビューの生成
videoView = (VideoView) findViewById(R.id.videoview);
videoView.requestFocus();
mc = new MediaController(this);
videoView.setMediaController(mc);
mc.show(0); //常にコントローラ表示 ==なぜか効かない!
//プログレスダイアログ(くるくる回る)
waitDialog = new ProgressDialog(this);
waitDialog.setMessage("読込中... しばらくお待ちください");
waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
waitDialog.show();
//ローディング終了
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer arg0) {
// 読込終わったらプログレスダイアログ終了
if(waitDialog != null){
waitDialog.dismiss();
waitDialog = null;
}
}
});
//エラー
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
if(waitDialog != null){
waitDialog.dismiss();
waitDialog = null;
}
return false;
}
});
//再生終了処理
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer arg0) {
finish();
}
});
//動画の再生
videoView.setVideoURI(Uri.parse(url));
videoView.start();
} catch (Exception e) {
android.util.Log.e("",e.toString());
if(waitDialog != null){
waitDialog.dismiss();
waitDialog = null;
}
}
Layout xml
<VideoView
android:id="@+id/videoview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
2012年6月7日木曜日
Webビュー
//Webビューの生成
WebView webView=(WebView) findViewById(R.id.webview);
WebSettings settings=webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSavePassword(false);
settings.setSaveFormData(false);
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
String startURL = "http://www.yahoo.co.jp";
//Web表示
webView.loadUrl(startURL);
リンク(http://xxxx)をクリックしたとき、標準ブラウザで表示されてしまうので、以下を設定
webView.setWebViewClient(new WebViewClient(){
//URLジャンプ前に呼ばれる(デフォルトでは標準ブラウザに表示してしまう)
// (相対パスなら、同じWebView内で表示される)
@Override
public boolean shouldOverrideUrlLoading(WebView view,String url) {
//view.loadUrl(url); //このWebViewでそのまま表示するとき
//他のActivityへ移るとき
Intent intent = new Intent(Activity.this, 起動するクラス.class);
intent.putExtra("url", url);
// アクティビティ起動
startActivity(intent);
return true; //他のアプリ、Activity起動のとき、true
//同じWebView内ならfalse
}
Layout xml
<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
/>
CSVファイル
CSVファイルのRead/Write
opencsvのライブラリを使用
http://java.akjava.com/library/opencsv
ダウンロードしたsrc/auフォルダを、Eclipseの対象プロジェクトのsrcにコピーする。
読み出しプログラム例
FileInputStream input = openFileInput("CSVファイル名");
InputStreamReader ireader=new InputStreamReader(input, "UTF-8");
CSVReader reader = new CSVReader(ireader,',','"',0);
String[] csv; //1行分のデータ格納用
opencsvのライブラリを使用
http://java.akjava.com/library/opencsv
ダウンロードしたsrc/auフォルダを、Eclipseの対象プロジェクトのsrcにコピーする。
読み出しプログラム例
FileInputStream input = openFileInput("CSVファイル名");
InputStreamReader ireader=new InputStreamReader(input, "UTF-8");
CSVReader reader = new CSVReader(ireader,',','"',0);
String[] csv; //1行分のデータ格納用
//1行づつ最後まで読み出し
while((csv = reader.readNext()) != null)
{
1行毎の処理
}
書き込みは、opencsvの上記サイトに下のような例があるが、自分でカンマを付けて、OutputStreamでも良い。
CSVWriter writer = new CSVWriter(new PrintWriter(System.out));
writer.writeNext(test);
writer.flush()
FTPファイル送信
FTPファイル送信サンプル
変数定義
String sHost = "192.168.11.27"; //ftp server IP
String sUser = "user"; //ユーザ名
String sPass = "pass"; //パスワード
String sRemotePath = "/"; //サーバーパス
FTPClient ftpCli;
転送ファイル指定、送信
FTPFile ftpFile = new FTPFile();
ftpFile.setName("ファイル名");
uploadFTP(ftpFile);
送信ルーチン
//FTP送信
private void uploadFTP(FTPFile ftpFile) {
//3.1からこれを入れないとエラー(android.os.NetworkOnMainThread Exception)
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
int nPort = 21;
int nTimeout = 100*1000;
try {
ftpCli = new FTPClient();
// タイムアウト設定
ftpCli.setDefaultTimeout(nTimeout);
// 接続
ftpCli.connect(sHost,nPort);
if (FTPReply.isPositiveCompletion(ftpCli.getReplyCode()) == false) {
// 接続エラー
throw new Exception(
new StringBuffer("FTP接続エラー Code=")
.append(ftpCli.getReplyCode())
.toString()
);
}
// ソケットタイムアウト設定
ftpCli.setSoTimeout(nTimeout);
// ログイン
if (ftpCli.login(sUser, sPass) == false) {
// 認証エラー
throw new Exception(
new StringBuffer("FTP認証エラー Code=")
.append(ftpCli.getReplyCode())
.toString()
);
}
// ファイル転送モード設定
ftpCli.setFileType(FTP.ASCII_FILE_TYPE);
ftpCli.enterLocalPassiveMode();
ftpCli.setDataTimeout(nTimeout); // タイムアウト設定
// ディレクトリ移動
if (ftpCli.changeWorkingDirectory(sRemotePath) == false) {
throw new Exception(
new StringBuffer("Failed changeWorkingDirectory() ")
.append(sRemotePath)
.append(" Code=")
.append(ftpCli.getReplyCode())
.toString()
);
}
// アップロード
FileInputStream fos = openFileInput(ftpFile.getName());
ftpCli.storeFile(ftpFile.getName(), fos);
fos.close();
// 完了処理
ftpCli.disconnect();
} catch (SocketException e) {
showDialog(Activity.this,"sエラー",e.toString());
} catch (IOException e) {
showDialog(Activity.this,"iエラー",e.toString());
} catch (Exception e) {
showDialog(Activity.this,"eエラー",e.toString());
}
}
//ダイアログの表示
private static void showDialog(Context context,String title,String text) {
AlertDialog.Builder ad=new AlertDialog.Builder(context);
ad.setTitle(title);
ad.setMessage(text);
ad.setPositiveButton("OK",null);
ad.show();
}
2012年6月6日水曜日
MAP表示
地図表示サンプル
private MapView mapView;//Mapビュー
private MapController mapCtrl;//Mapコントローラ
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.setting);
//Mapビューの生成
mapView=(MapView) findViewById(R.id.Map); //(this,API_KEY);
mapView.setBuiltInZoomControls(true);
mapCtrl=mapView.getController();
//中心の緯度、経度を指定
mapCtrl.setCenter(new GeoPoint(
(int)(36.24831*1E6),
(int)(139.533294*1E6)));
mapCtrl.setZoom(16);
}
Layout xml (API Keyをあらかじめ取得しておく)
<com.google.android.maps.MapView
android:id="@+id/Map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="05fjECm****************ZgcHR6SzVdUmQ"
/>
Manifestへ追加
<application>の中へ
<uses-library android:name="com.google.android.maps"/>
target はGoogle APIにする。
データベース・アクセス
private final static String PDB_NAME ="product.db";//DB名
private final static String PDB_TABLE="product"; //テーブル名
private final static int PDB_VERSION=1; //バージョン
private static SQLiteDatabase pdb; //データベースオブジェクト
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//データベースオブジェクトの取得
PDBHelper pdbHelper=new PDBHelper(this);
pdb=pdbHelper.getWritableDatabase();
}
//DB検索
private void readDB(String id) throws Exception {
//idで検索
Cursor c=pdb.query(PDB_TABLE,new String[]{"id","Name","Category","Price"},
"id='" + id + "'",null,null,null,null);
if (c.getCount()==0) throw new Exception();
c.moveToFirst(); //最初に一致したもの
//順番に取り出す場合は、c.moveToNext(); で次のレコードへ
//DBから取り出し
String id =c.getString(0);
String name =c.getString(1);
String category =c.getString(2);
String price =c.getString(3);
c.close();
}
//DBへの書き込み
private void writeDB(String id,String Name,String Cate,String Pr) throws Exception {
ContentValues values=new ContentValues();
values.put("id",id);
values.put("Name",Name);
values.put("Category",Cate);
values.put("Price",Pr);
//idの同じレコードを更新
int colNum=db.update(DB_TABLE,values,"id='" + id + "'" ,null);
//新しいidなら追加
if (colNum==0) {
db.insert(DB_TABLE,"",values);
((TextView) findViewById(R.id.Message)).setText("1レコード追加しました");
}else{
((TextView) findViewById(R.id.Message)).setText("1レコード更新しました");
}
}
//データベースヘルパーの定義
private static class PDBHelper extends SQLiteOpenHelper {
//データベースヘルパーのコンストラクタ
public PDBHelper(Context context) {
super(context,PDB_NAME,null,PDB_VERSION);
}
//データベースの生成
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table if not exists "+
PDB_TABLE+"(id text primary key,Name text,Category text,Price text)");
}
//データベースのアップグレード
@Override
public void onUpgrade(SQLiteDatabase db,
int oldVersion,int newVersion) {
db.execSQL("drop talbe if exists "+PDB_TABLE);
onCreate(db);
}
}
位置情報の取得
現在位置を取得するサンプル
//起動時、画面復帰時に位置確認
//画面復帰時にも位置確認をするため、onCreateでなく、onResumeに書く
@Override
public void onResume(){
super.onResume();
//ロケーションマネージャの設定
LocationManager lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
//10秒ごとに10m変化を通知
//GPSとネットワーク どちらでも可能。GPSの方が精度が高い
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,10000,10,this);
// lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,10000,10,this);
//最新の位置情報を取得
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
getLoc(location,);
}
//位置が変わったら再取得する
public void onLocationChanged(Location location) {
getLoc(location);
}
//位置情報取得有効化
public void onProviderEnabled(String provider) {
}
//位置情報取得無効化
public void onProviderDisabled(String provider) {
showDialog(Activity.this,"Map","位置情報取得 無効");
}
//位置情報状態変更
public void onStatusChanged(String provider,
int status,Bundle extras) {
}
//位置確認
private void getLoc(Location location){
if (location !=null){
//緯度と経度の取得
double cLat = location.getLatitude();
double cLong = location.getLongitude();
}else {
errDialog("現在位置が取得できませんでした。");
}
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onStop() {
super.onStop();
//ロケーションマネージャー停止
lm.removeUpdates(this);
}
protected boolean isRouteDisplayed() {
return false;
}
Manifestの設定
//ネットワーク許可
<uses-permission android:name="android.permission.INTERNET" />
//GPS
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
//エミュレータ用
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
//起動時、画面復帰時に位置確認
//画面復帰時にも位置確認をするため、onCreateでなく、onResumeに書く
@Override
public void onResume(){
super.onResume();
//ロケーションマネージャの設定
LocationManager lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
//10秒ごとに10m変化を通知
//GPSとネットワーク どちらでも可能。GPSの方が精度が高い
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,10000,10,this);
// lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,10000,10,this);
//最新の位置情報を取得
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
getLoc(location,);
}
//位置が変わったら再取得する
public void onLocationChanged(Location location) {
getLoc(location);
}
//位置情報取得有効化
public void onProviderEnabled(String provider) {
}
//位置情報取得無効化
public void onProviderDisabled(String provider) {
showDialog(Activity.this,"Map","位置情報取得 無効");
}
//位置情報状態変更
public void onStatusChanged(String provider,
int status,Bundle extras) {
}
//位置確認
private void getLoc(Location location){
if (location !=null){
//緯度と経度の取得
double cLat = location.getLatitude();
double cLong = location.getLongitude();
}else {
errDialog("現在位置が取得できませんでした。");
}
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onStop() {
super.onStop();
//ロケーションマネージャー停止
lm.removeUpdates(this);
}
protected boolean isRouteDisplayed() {
return false;
}
Manifestの設定
//ネットワーク許可
<uses-permission android:name="android.permission.INTERNET" />
//GPS
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
//エミュレータ用
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
MACアドレスの取得方法
MACアドレスの取得方法
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String macAddress = wifiInfo.getMacAddress();
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String macAddress = wifiInfo.getMacAddress();
Manifestに以下を追加
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
2012/6/21追記
無線LANが、電源ON時にOFFになっていると、MACアドレスは取得できないことが判明。
デバイス識別として他に使えるのはシリアル番号くらいしかなさそう。
2012/6/21追記
無線LANが、電源ON時にOFFになっていると、MACアドレスは取得できないことが判明。
デバイス識別として他に使えるのはシリアル番号くらいしかなさそう。
String serialId = android.os.Build.SERIAL;
試してないが、今度やってみよう。
Home,Backキーが押されたときの処理
Backキーが押されたとき
Backキーが押されると、Activityが終了してしまう。誤操作を防止したいので・・・・
Backキーを禁止するには、
//BACKキー禁止
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction()==KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK:
return true; //trueでActivityを終了しない
}
}
return super.dispatchKeyEvent(event);
}
終了していいか確認する
//BACKキーで終了確認
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction()==KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK:
// 終了していいか、ダイアログで確認
showDialog(WBsetActivity.this,"終了","終了してもよろしいですか");
return true;
}
}
return super.dispatchKeyEvent(event);
}
//ダイアログ
private void showDialog(Context context,String title,String text) {
AlertDialog ad=new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(text)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish(); //終了
}
})
.setNegativeButton("キャンセル", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
})
.show();
}
Backキーが押されると、Activityが終了してしまう。誤操作を防止したいので・・・・
Backキーを禁止するには、
//BACKキー禁止
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction()==KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK:
return true; //trueでActivityを終了しない
}
}
return super.dispatchKeyEvent(event);
}
終了していいか確認する
//BACKキーで終了確認
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction()==KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK:
// 終了していいか、ダイアログで確認
showDialog(WBsetActivity.this,"終了","終了してもよろしいですか");
return true;
}
}
return super.dispatchKeyEvent(event);
}
//ダイアログ
private void showDialog(Context context,String title,String text) {
AlertDialog ad=new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(text)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish(); //終了
}
})
.setNegativeButton("キャンセル", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
})
.show();
}
HOMEキーが押されたとき
HOMEキーが押されたことはキャッチできるが、HOME画面に戻るのは阻止できない。
Activityが中断されたまま残るのが困るときはどうする?
強制的にActivityを終了させるしかない。
@Override
public void onCreate(Bundle savedInstanceState) {
//HOMEキーが押されたときのレシーバ設定
HomeButtonReceive m_HomeButtonReceive = new HomeButtonReceive();
IntentFilter iFilter = new IntentFilter();
iFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
this.registerReceiver(m_HomeButtonReceive, iFilter);
}
//HOMEボタンで終了する。
public class HomeButtonReceive extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent arg1){
Toast.makeText(getApplicationContext(), "終了" ,Toast.LENGTH_SHORT).show();
finish();
}
}
登録:
投稿 (Atom)