2011年12月5日月曜日

ファイルの拡張子を除外、取得【java】【file】【拡張子】

このような感じでできそうです。

たとえは、ファイルの名前の変更を行うようなダイアログを表示する際には、
拡張子なしのファイル名を表示するのが、おそらくは無難でしょう。
しかし、実際にファイルの名前の変更をする際には、拡張子が必要です。
そのようなときに、下記のようなメソッドが有効です。

    /**
* ファイル名から拡張子を返します。
* @param fileName ファイル名
* @return ファイルの拡張子
*/

public String getSuffix(String fileName) {
if (fileName == null)
return null;
int point = fileName.lastIndexOf(".");
if (point != -1) {
return fileName.substring(point + 1);
}
return fileName;
}
/**
* ファイル名から拡張子除いたファイル名を返します。
* @param fileName ファイル名
* @return 拡張子無しのファイル名
*/

public String removeFileExtension(String filename) {
int lastDotPos = filename.lastIndexOf('.');

if (lastDotPos == -1) {
return filename;
} else if (lastDotPos == 0) {
return filename;
} else {
return filename.substring(0, lastDotPos);
}
}

2011年11月28日月曜日

String.xmlの内容をString型でjavaで扱う【android】【String.xml】【多言語化】

すでにあるvaluesフォルダと同じ階層にvalues-jaを作成し、同じXMLファイルを置いてやることで、
日本語専用のXMLファイルを用意することができ、本体の言語設定に応じて、どちらのXMLファイル
を使用するか選択させることができます。

このような仕組みをandroidでは「多言語化」と呼んでいますが、このような多言語化を行った際に
String.xmlの内容をString型で取得したい。とすぐになります。

一般的なString.xmlファイルからの値の取得方法は、下記のようになりますが、これでは、R.java
に記載されている「id」しか取得できません。

R.string.select_dir
※select_dirはString.xmlに定義されているものとします。

この解決方法として、android.content.Context.getStringメソッドを使用する方法があります。

String str = getString(R.string.select_dir);

としてやることで、String型でString.xmlファイルから値の取得ができます。


この方法は、Activity内では上記のように使用することができますが、共通部品のような、他の
クラスではContextが見つけられない事から、getStringメソッドが見つけられないため、使用
することができません。その場合のひとつの解決方法として、共通部品の引数にContextを増やし、
引数で、thisを渡してあげることで、解決することができます。

2011年11月20日日曜日

画像を画面サイズに合わせる(縮尺・縮小する)の続き【android】【画像表示】【エラー】

以前の投稿の続きです。↓
⇒画像を画面サイズに合わせる(縮尺・縮小する)【android】【画像表示】【エラー】

以前、紹介した画像を画面サイズに合わせる方法ですが、いざ、自分で使ってみると
GC(ガーベッジコレクション)が画像毎に発生して、処理が非常に遅いという問題
が発生しました。
※画像表示処理もそこそこに遅いのに、GCがさらに悪化させているようでした。

なんとかGCの発生を抑制したくいろいろ調べた結果、Bitmap作成処理を下記のように
書き換えることで、GCの発生を抑え、処理時間を短くすることができました。

以前の方法では、画像をそのままBitmapに読み込んでから縮尺していたようで、
メモリにごみができやすいという問題があったようです。
今回は画像のサイズをあらかじめ読み込んでおき、画像の読み込みのタイミングで
縮尺しているので、メモリを無駄なく使用することができます。

あと、不本意ではあるのですが、androidでは短命なオブジェクトや変数を生成しない
ようにしたほうがパフォーマンスがあがるという情報を得て、できるだけクラス変数
で、変数を宣言するようにしています。
※ほかにも下記のようなパフォーマンス対策がありました。
  ・setterやgetterは使用しない。
  ・オブジェクトを作成しない(コードはベタ書きすべき)。
  ・処理が遅くなっても問題ない箇所でGCするようにする。
  ・定数はfinalで宣言する。

ただし、そのままこの情報を受け取ってコーディングをすると、非常に見づらい
コードとなってしまいそうなので何か対策を立てる必要がありそうです。


    //setBitmap変数
Bitmap bmImage;
int zoomWidth;
int zoomHeight;

/**
* ディレクトリリストに表示するBitmapを設定する。
* @param File file(設定するBitmapファイル)
* @return Bitmap bmImage(設定されたBitmap)
* @exception なし
*/

public Bitmap setBitmap(File file){
// ビットマップ作成オブジェクトの設定
BitmapFactory.Options bmfOptions = new BitmapFactory.Options();
// RGBでそれぞれ 5/6/5 ビットの色を使用(メモリ対策)
bmfOptions.inPreferredConfig = Config.RGB_565;
// アプリケーション内でのピクセル密度を設定
bmfOptions.inScreenDensity = DisplayMetrics.DENSITY_LOW;
// 画像の大きさだけ取得
bmfOptions.inJustDecodeBounds = true;
bmImage = BitmapFactory.decodeFile(file.getPath(),bmfOptions);

// 画面のサイズの1/4で画像を縮尺するよう、縮尺率を設定
if (displayMetrics != null) {
zoomWidth = (int)Math.floor(bmfOptions.outWidth / (displayMetrics.widthPixels / REDUCTION_SIZE));
zoomHeight = (int)Math.floor(bmfOptions.outHeight / (displayMetrics.heightPixels / REDUCTION_SIZE));
bmfOptions.inSampleSize = Math.max(zoomWidth, zoomHeight);
}
// 画像そのものを設定された縮尺率で取得
bmfOptions.inJustDecodeBounds = false;
bmImage = BitmapFactory.decodeFile(file.getPath(),bmfOptions);

return bmImage;
}
}

2011年11月7日月曜日

画像を画面サイズに合わせる(縮尺・縮小する)【android】【画像表示】【エラー】

以前の投稿の続きです。↓
⇒java.lang.OutOfMemoryError: bitmap size exceeds VM budget【android】【画像表示】【エラー】 の続き


画像の表示について追記します。

以前、画像の縮小について下記の方法を書きましたが、

// 画像を1/20サイズに縮小(メモリ対策)
bmfOptions.inSampleSize = 20;


実際、表示されるすべての画像を均一に縮小するやり方はよくないということで、
画面の表示サイズを取得し、そこから必要に応じて縮小するやり方を紹介します。
以前紹介した、etBitmap(File file)を下記に変更してみました。
改善点等ございましたら、ご教授くださいませ。

    public Bitmap setBitmap(File file){
// ビットマップ作成オブジェクトの設定
BitmapFactory.Options bmfOptions = new BitmapFactory.Options();
// RGBでそれぞれ 5/6/5 ビットの色を使用(メモリ対策)
bmfOptions.inPreferredConfig = Config.RGB_565;
// GridViewの要素が横に3つ並ぶ想定で、余白も考慮し、画像の縮尺サイズを1/4に設定
// 画面のサイズに縮尺した後に、1/4にさらに縮尺
int reductionSize = Const.COLUMN_IMAGE_GRID_VIEW + 1;

if (metrics == null) {
// 現在の表示メトリクスの取得
DisplayMetrics dm = this.getResources().getDisplayMetrics();
// ビットマップのサイズを現在の表示メトリクスに合わせる(メモリ対策)
bmfOptions.inDensity = dm.densityDpi;
}
// システムメモリ上に再利用性の無いオブジェクトがある場合に勝手に解放(メモリ対策)
bmfOptions.inPurgeable = true;
// システム側で設定されているピクセル密度を無視して設定値を元に画像がスケール
bmfOptions.inScreenDensity = DisplayMetrics.DENSITY_LOW;

// 画像ファイルオブジェクトとビットマップ作成オブジェクトから、ビットマップオブジェクト作成
Bitmap bmImage = BitmapFactory.decodeFile(file.getPath(),bmfOptions);

if (metrics != null) {
float imageWidth = (float)bmImage.getWidth() / (float)metrics.widthPixels;
float imageHeight = (float)bmImage.getHeight() / (float)metrics.heightPixels;
float imageScale = Math.max(imageWidth, imageHeight);
if (imageScale > (1 / reductionSize)){
int newImageWidth = (int)((bmImage.getWidth() / imageScale) / reductionSize);
int newImageHeight = (int)((bmImage.getHeight() / imageScale) / reductionSize);
bmImage = Bitmap.createScaledBitmap(bmImage,newImageWidth,newImageHeight,false);
}else{
bmImage = Bitmap.createScaledBitmap(bmImage,bmImage.getWidth(),bmImage.getHeight(),false);
}
}
return bmImage;
}




【クラス変数宣言】
private DisplayMetrics metrics;


【onCreateメソッドで】
metrics = new DisplayMetrics();
display.getMetrics(metrics);




と、こんな感じです。
Const.COLUMN_IMAGE_GRID_VIEWは画面に表示している画像の列数です。
私のアプリでは、画像が3列表示されているので、余白も考え、
画面のサイズ/4 のサイズに縮小しています。
画面いっぱいいっぱいのサイズなら、reductionSizeを1にするとよいでしょう。

如何でしょうか?やっつけで作ったので、ちょっと不安ですが、
一応、今のところ、元気に動いているようですw

2011年10月31日月曜日

アプリにSDカードへの書き込み権限を付与する【android】【SDカード】【権限】

SDカードに書き込みを行う為には、下記の内容を AndroidManifest.xml に書いておく必要があります。


    </application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>



他にも、下記のような権限の設定が可能です。


権限の名前 内容
android.permission.ACCESS_COARSE_LOCATION 低精度の位置情報の取得
android.permission.ACCESS_FINE_LOCATION 高精度の位置情報の取得
android.permission.ACCESS_MOCK_LOCATION デバッグ用の位置情報の取得
android.permission.CONTROL_LOCATION_UPDATES 位置情報の更新
android.permission.ACCESS_NETWORK_STATE ネットワーク状態を取得
android.permission.ACCESS_WIFI_STATE WiFiの状態を取得
android.permission.BLUETOOTH BlueToothを操作
android.permission.BLUETOOTH_ADMIN BlueToothの探索と接続
android.permission.CALL_PHONE 電話のダイアル(救急と警察を除く)
android.permission.CALL_PRIVILEGED 電話のダイアル(救急と警察を含む)
android.permission.PROCESS_OUTGOING_CALLS 電話の発信処理への介入
android.permission.MODIFY_PHONE_STATE 電話の状態の書き換え
android.permission.VIBRATE バイブ機能の利用
android.permission.DEVICE_POWER 低水準電源管理の利用
android.permission.WAKE_LOCK 高水準電源管理の利用
android.permission.CAMERA カメラの利用
android.permission.RECORD_AUDIO 音声録音の利用
android.permission.MODIFY_AUDIO_SETTINGS 音声機能の設定の書き換え
android.permission.FORCE_BACK 「戻る」ボタンに相当する処理
android.permission.READ_INPUT_STATE キーとスイッチの直接の読み込み
android.permission.INTERNET インターネットへの接続
android.permission.WRITE_GSERVICES Google mapサービスの利用
android.permission.READ_HISTORY_BOOKMARKS 履歴とお気に入りの読み込み
android.permission.WRITE_HISTORY_BOOKMARKS 履歴とお気に入りの書き込み
android.permission.SET_TIME 日付と時刻の設定
android.permission.SET_TIME_ZONE タイムゾーンの設定
android.permission.READ_CONTACTS 「連絡先」データの読み込み
android.permission.WRITE_CONTACTS 「連絡先」データの書き込み
android.permission.WRITE_SETTINGS 「設定」データの書き込み
android.permission.MOUNT_FORMAT_FILESYSTEMS SDカードのフォーマット
android.permission.MOUNT_UNMOUNT_FILESYSTEMS SDカードのマウント・アンマウント
android.permission.WRITE_EXTERNAL_STORAGE SDカードの書き込み
android.permission.REBOOT Androidの再起動
android.permission.RECEIVE_BOOT_COMPLETED Androidの起動完了の検出

2011年10月24日月曜日

TextViewの文字列を一行に収め、改行しないようにする【android】【TextView】【Layout】

TextViewの内容をユーザが入力する場合、想定されたサイズを超過して、
2行に渡り表示されてしまうようなことが、しばしばあります。

このようなときに、長い文字列の先頭や中間、最後について「…」に
置き換えて表示するオプションがTextViewに存在しています。

android:scrollHorizontally="true"
android:ellipsize="start"

scrollHorizontally については固定で"true"を設定し、ellipsize
について、先頭を省略したい場合は"start",中間を省略したい場合は"middle"、
最後を省略したい場合は、"end"を指定します。


たとえば、下記のように設定すると、画面の操作で入力されたテキストについて、
先頭が「…」で省略され、表示されます。

    <TextView android:id="@+id/textview11"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:layout_gravity="left"
android:layout_marginLeft="2dip"
android:layout_marginTop="2dip"
android:textColor="@color/white"
android:textSize="35dip"
android:textStyle="bold"
android:scrollHorizontally="true"
android:ellipsize="start"
/>

Re-installation failed due to different application signatures.【android】【エラー】【実機】

私はHTC製の端末を普段使用しておりますが、その端末で開発したアプリの
デバッグをしてみようとしたところ、下記のようなメッセージか出力され、
インストールできませんでした。

Re-installation failed due to different application signatures.

上記の原因は、前回インストールしたPCとは違うPCから端末へアプリケーションの
インストールする場合、あらかじめ、端末からそのアプリケーションをアンインストール
する必要があるとの事でした。

実際に、端末の操作でアンインストールを行った後にインストールを行うと
正常にインストールが完了しました。


【ドコモ HTC端末でデバッグ】
http://wikiwiki.jp/android/?%A5%C9%A5%B3%A5%E2%20HTC%C3%BC%CB%F6%A4%C7%A5%C7%A5%D0%A5%C3%A5%B0#driver

【コラム:Androidアプリ開発初心者がつまずきやすい7のポイント】
http://www.dm-android.com/column/begginer.html