Androidに関するTips

  • writen by member/Yuki Yahata
    • Androidアプリケーションの開発等で気になったことや備忘録など。基本的には上から書いた順番通り。

Android アプリケーション開発環境

現在では以下のIDEで開発できます。

  • Eclipse(メジャーなIDE)
    • 一番利用されているだろうIDE。使ってて困ったときにググったら一番幸せになれるのがこれじゃないかと。
  • Android Studio(GoogleがリリースしたIDE)
    • JDK6でのみ利用可能。7でも利用できなくはないが、6であるものとして起動される。
  • NetScape(一番ニッチなところ)
    • NetScapeで開発する上でのtipsは用意しない方向。(というか使う人が少ない)

Eclipseでプロジェクトのインポート

メニューバー > ファイル > インポート > Android > Exist Android Project 
>(フォルダを参照)> copy projects on workspace にチェック
> インポートしたいプロジェクトにチェック > Finish 

スクリーンショットを撮影しようとすると保存が出来ない問題を解決したいとき

原因:直近で入れたスクリーンショット撮影アプリと

/mnt/sdcard/picture/ScreenShot/ 

のディレクトリを削除してしまったため?

解決方法:直近で入れたスクリーンショット撮影アプリのアンインストール

スクリーンショット自体はAndroid 4.0(ICS)から標準機能として搭載されています。 (方法:スリープボタンと音量 - ボタンを同時長押し)

まさかこんなことになるとは、と思いつつもggってみたら同様な状態を経験した人がいたため 参考にさせていただきました。 ( 教えてgoo )→http://oshiete.goo.ne.jp/qa/8106958.html

Rを変数に解決できません を解決したい時に確認すること

  • プロジェクト内でR.javaが格納されているパッケージ名とソースコードが格納されているパッケージ名が同じかどうか。
  • 同じ場合はプロジェクトのクリーンをする(プロジェクトを右クリック>ソース>クリーンアップ)
  • 異なる場合はそのソースコード.java 内に import (R.javaが格納されているパッケージ名).R が有るかどうか。
  • 無ければ追加する(おそらくサジェストされる
  • あればプロジェクトのクリーンをする(プロジェクトを右クリック>ソース>クリーンアップ)          

原因:ソースコード上に置けるオブジェクト、変数の中でR.javaに情報が格納されていないものがある。

R.javaはソースコード上の変数、オブジェクトなどの情報を格納しているファイルでソースコード、xmlファイルを保存した時に自動的に更新され、その時に新しい変数等があればその情報が格納されるファイル。

元々R.javaは直接扱うことは無いためなかなか気づけないらしい。 (ソースコードのエラーを解決するためのサジェストでいじったら話は変わるけど。

参考にさせていただいたページ

http://androidfaq.e1blue.net/android/status/31

加えて…。 プロジェクト内のgen フォルダにソースコードが格納されているパッケージ名と異なるパッケージ内にR.javaが格納されている場合→ほとんどあり得ないが、そういう場合は

import (そのパッケージ名).R

をインポートしてあげると解決出来たりもする。

元々は genフォルダ内には 最初にプロジェクトを作成した時のパッケージ名でR.javaが管理されている。

→もし入っていない場合:SDKマネージャーを開いてBuildToolを始めとしたものをインストールされていないものをすべてインストールしよう。これで解決する。

もし、新しくパッケージを追加してソースコードを格納している場合 レイアウトファイルを読み込む時には上記の内容でインポートすると解決する。 (おそらくこの場合はサジェストされる。

カメラが動作するアクティビティに遷移すると"保存先フォルダが見つかりません"で強制終了させられるときに回避する方法

基本的にこんなことは起こらないはずだけど起きた時の備忘録として。 この強制終了が起きてしまう場合、ソースコード内でファイルの保存先の設定が原因。

File path = new File( Environment.getExternalStorageDirectory().getPath());

なら動作するけど

File path = new FIle(Environment.getExternalStorageDirectory().getPath().toString());

だったりすると動作しない。

new File( String path );

だから別に問題なさそうだけど上記の様なエラーで強制終了させられるかも。 getPathメソッドはString型を値として返すからtoStringメソッドでString型にする必要は無いんだけど、どのメソッドにも標準実装されているから使っても使わなくても変わらないはずなのに…という不思議体験。

ちなみに端末によって問題が起こるか変わるかもしれない。

___________________________________________________

Google Nexus7 発生せず

HTC one V 発生せず

Fujitsu ArrowsZ ISW11Fで発生

kyocera ISW11K で発生

___________________________________________________

EditText のnull 判定

EditText message;
boolean hantei;
hantei = message.getText().toString().equals("");

こんなので悩むなよ?

ええ、私は悩みました。

ちなみにisEmpty()はどうなの?という人へ。

isEmptyですとオブジェクトのlength取ってきて、0かどうかを比較するので使おうとするならば

hantei = message.getText().toString().isEmpty();

対して使い方が変わらないため、お好みでどうぞ。

EditTextを使えなくする

EditTextの入力を無効にするには? → タッチすら出来なくすればいい。

ということで

EditText edit = (EditText) findViewById(R.id.edittext);
edit.setFocusable(false);

あとから気づいたけど

edit.setEnable(false);

でもいいらしい。タッチするとソフトウェアキーボードまで出るからユーザビリティ的にはこれは無いかなぁ、と。

AndroidManifest.xmlの警告の解決:Use '$' instead of '.' for inner classes (or use only lowercase letters in package names)

Mac OSX: Eclipseのメニューバー > プロジェクト > クリーンアップ > 全てのプロジェクト にチェック > 完了

で解決。

上記の方法で解決出来ない場合、AndroidManifest.xmlを開いて

Manifestタブの packageの値が src.("パッケージの名前") と同じかどうかを確認する。 違う場合は同じのものにする。

また、同じものにした後に、クラスファイルの方でエラーが検出されるかもしれないが おそらくその場合は

import ("Manifest タブの package の値") 

を削除するだけである。これは消して全く問題無い。

Res > layout はどこに所属する?〜レイアウトファイルのパス〜

クラスファイルであればパッケージ名にクラス名を"."(ドット)でつなげればおkだが…

レイアウトの場合は?

レイアウトは AndroidManifest.xmlのManifestタブのPackageの値が関係する。 パスは

"ManifestのPackageの値".res.layout."レイアウトファイル名" 

になるみたい?

例えば com.example.res.layout.main とか。

位置情報を取得できない(LocationManager.NETWORK_PROVIDER)

NETWORK_PROVIDERは携帯電話の基地局間通信を用いて位置情報を取得する方法。 GPSで取得するより消費電力もすっごく小さいからバッテリーにも優しいやつ。 しかも取得までの時間がGPSと比べると化け物レベルに速い。まじ爆速。

だけど

  • 精度については最大1kmの誤差をはじき出すこともあるかも。(てへっ

そんな化け物を使おうとしたら位置情報が取れるときと取れない時が出て来るかも? そんな時のトラブルシューティングです。

まず

設定>無線とネットワーク>モバイルネットワーク>3Gを有効に。

3G回線が使えないとネットワークプロバイダは使えません。(これ前提条件

  • Android OSのバージョンは?
    • 4.0(ICS)です→原因不明の症状かもしれません。同様の状態にある人がいっぱい居ます。
      http://blog.dtdweb.com/2013/04/06/gps_desc/
      のコメントの所とかにも居る。以下の対処法を試してみては?
      • 端末の再起動で位置情報のキャッシュをぶっ飛ばす。
      • 設定>位置情報(っぽい名前のやつ)>ロケーションサービスの再インストール。
      • コード上のLocationListenerについてrequestとremoveをonCreateやonPause,onStopではっきり書く。
    • 2.3.3(GB) です。→コード見直せ。GBはNETWORK_PROVIDERは↑のURLのコメントにもあるけど問題無く使える人が多い。多分コード上の問題かも。

なんかPaintオブジェクトやらBitmapオブジェクトを生成する部分で警告が出るんだけど。

Avoid object allocations during draw/layout operations (preallocate and reuse instead)

なんて警告じゃないです? そしてonDraw内にPaintオブジェクトやらBitmapオブジェクトを生成するコード書いていないです?

とりあえず、onDrawを呼ぶたびに同じオブジェクトを何回も生成しているからメモリを無駄に消費することになるからやめろや って言われてる。

PaintオブジェクトやらBitmapオブジェクトやらはとりあえずコンストラクタの中で生成しておけば レイアウトが呼ばれた時に一度しか生成しない。

別に何回も呼ばないし、全然メモリを気にする必要がなければ黄色いところにカーソル合わせて 警告を無効化するアノテーションをつけとけばいいよ、うん。

とりあえずアノテーションもつけたくねーんだけどって場合は

手順1.変数の宣言で大域変数?になるような一番外側でする。

手順2.オブジェクトの取得?生成?をコンストラクタの中でする。

これでおk

ImageViewにBitmapをセットしてるが表示されないことがある。

ImageViewに画像をセットしたいときは次の様にするっしょ?

ImageView image = (ImageView)findViewById(R.id.hogehoge);
image.setImageBitmap(BitmapFactory.decodeFiles(ファイルのパス));

大体こんなもんでいけるっしょ?と言うか基本形だよな。でも出来ないことがあるんですわ。 不思議なことだけど、もしそんなことが起きた時は次の方法を試して欲しいのよ?

手順1.setImageBitmapの引数となるBitmapはそれより前に別に変数に格納して準備しておく。

何が言いたいか、というとこんな感じ。

Bitmap picture = BitmapFactory.decodeFiles(ファイルのパス);
......
(なんかテキトーなコード);
...;
image.setImageBitmap(picture);

こうするだけで実は変わったりする。やってることは最初の状態と変わらないはずなのにね。

ん?変わらない??んじゃ次。

手順2.リソースの確保を画像の反映よりもとにかく前に持ってくる。

みんなあれよな?いい子だからAndroidアプリ開発してるとViewオブジェクトのリソースの確保なんて別にメソッド用意して書いてしまうよな? public void findViews() とか。

要は、そのメソッド呼ぶよりも前にBitmap型の変数にファイルパスを引数に画像をデコードしてぶちこんどけ、ってことなのよ。

Bitmap picture = BitmapFactory.decodeFiles(ファイルのパス);
...

hogehoge
hogehoge

...
findViews();

こういうことな。

ぁ、みんないい子だからimage.setImageBitmap(picture)もfindViews()の中に書いちゃってるよな?

いつセットするのよ?って思った人、findViews()の中にそれも入ってるって前提で書いてたわ。すまんこ。

MapAPI v2 で現在地(setMyPosition)を取得しているのは?

GoogleMap map = super.getMap();//←だいたいはMapFragmentからgetMap()するかと思う。
map.setMyPosition(true);

こんなコードを書けば大体GoogleMapのレイアウト上に現在地のマークが出る。これはLocationListenerを使わなくても出る。

  • setMyPosition()の位置情報の取得はどうやってる?→GPS

おそらくLocationListenerを記述しなくてもGoogleMap#setMyPositionの中でLocationListenerがセットされているのかもしれない。(確認なんてしてないから適当に書いてます。ご了承ください。よかったら確認してみてください ←ぉぃ)

んでんで、プロバイダーをGPS_PROVIDER使われているのだろうなぁ、と。

MapFragmentを継承したFragment上ではGoogleMap#setMyPositionとLocationManager# NETWORK_PROVIDERは共存できない

というのは

GoogleMap map = super.getMap();//面倒くさいから端折ってるだけです。
map.setMyPosition(true);

なんて書いてる SupportMapFragmentを継承したFragment上でLocationListenerをimplementsするとどうなるかをやってみた。

結果としてタイトルの通り。

と判断した理由っていうのが、LocationListenerをimplementsしたら実装するメソッドってあるじゃん?

その中で LocationChangedみたいなのがあるっしょ?そのなかでToastをしてるんだけど一向に実行されないのよね。というか通知バーの中ではGPSが動いてますよーって通知があるだけ。んじゃproviderをNETWORL_PROVIDER にしてみても変わらない。

というかあれよね。setMyPositionがあるとGPSが優先されてそっちが動くなんてもんじゃなくて必ずGPSが動くみたい。んでんで、setMyPositionがあるとLocationListenerで位置座標を取得したくてもLocationChanged?が動かないから一切取得できない。

  • 解決案?
    • GPS_PROVIDERを使う → 少なくとも、NETWORK_PROVIDERは共存できないため。

GPS_PROVIDER使えば共存はできるんとちゃうの?と思うけど、試してない。(諸事情でNETRORK_PROVIDERを使いたいんです…(切実) )

GoogleMapオブジェクトから位置座標を取得する(GoogleMapから現在地座標を取得)

GoogleMap#setMyPosition()を使ったらGoogleMap上に現在地座標が出る。この座標を取得するには?

GoogleMap map = super.getMap();//面倒くさいから端折ってるだけです。
map.setMyPosition(true);//GoogleMapに現在地座標のマークを表示

↓↓ んでんでこの座標を取得したい! ↓↓

double lat = map.getMyPosition().getLatitude();
double lng = map.getMyPosition().getLongitude();

これで取得できます。マップをロングタップしたら現在地に飛びたい!(LocationListenerを使わずに!)

map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
           @Override
           public void onMapLongClick(LatLng point) {
              //飛びたい位置の座標とズーム倍率とかのオブジェクト(CameraUpdate)を作る。
              CameraUpdate camera = CameraUpdateFactory
                     .newCameraPosition(new CameraPosition.Builder()
                     //あえて上記の lat lng を使ってないよー。
                     .target(new LatLng(map.getMyLocation().getLatitude(),map.getMyLocation().getLongitude()))
                     .zoom(18.0f).build());
              //現在地の部分に移動!
              map.animate(camera);
           } 
});

でもでも、GoogleMapをgetMapするのって、基本的にはonResume()内で行うと思うんだけどonResume()内で上記の方法で現在地を取得しようとすると  ぬるぽ  が吐かれる。

おそらくこれはonResume()の時点ではFragmentはアクティブじゃないためにGoogleマップもアクティブじゃなくて、現在地座標の部分が存在しないためだと思われー。Fragmentがアクティブになってから意味がある、タップ・ロングタップのリスナーとかのなかでは普通に動作するからそうしちゃってくださいなー。

ちなみにAlertDialog内での DialogInterface.OnClickListenerでは  ぬるぽ  吐かれました。マジキチ。

if文の中で変数に格納された文字列がある文字列と等しいか、をやってしまうとfalseになる件

これはString型の変数に対してこんなことをすると起きる。

String str = "abc";
if(str = "abc"){
       処理
}

どうしてかわかるかな?どうやったら対処できるかな? ということで、Java Tips を参照されたし。 まじで注意。 SpinnerやSQLiteが混ざってきたら下手した時にかなり苦労するかもしれない。

Spinnerの有効と無効を切り替える

  • 無効
    • Spinner#setEnabled(false)をするだけ。
      Spinner spinner = (Spinner)findViewById(R.id.hoge);
      spinner.setEnabled(false);
      これだけ。これをするだけでspinnerを触らせても反応しなくなる。
  • 有効
    • Spinner#setEnabled(true)をして、Spinner#setEnableInTouch(true)をする。
      spinner.setEnabled(true);//ぁ、リソースの確保はできているって前提な。
      spinner.setEnableInTouch(true);
      これだけ。これだけなんだけどsetEnableInTouchにはまじで気付かなかった。気づくまでにホント時間がかかった。

Buttonを押したらSpinnerの無効と有効が切り替わるサンプルを書いてみた。

よかったら参考にするといいですっ(フンヌッ

  • レイアウト側 .xml
    <Button 
            android:id="@+id/switchBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="switchEnable"/>
            <!-- リソースの名前とかは適当に。RelativeLayoutとかでやるなら適当に配置しちゃって。 -->
    <Spinner
            android:id="@+id/spinner"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
  • ソースコード側 .java
    • onCreateとかでリソースの確保とかしとく
      //onCreate内
      Button switchBtn = (Button)findViewById(R.id.switchBtn);
      Spinner spinner = (Spinner)findViewById(R.id.spinner);
    • R.id.switchBtnに対して定義しているonClick時のメソッドを定義。なお、spinnerのアダプターやらは省略してるから勝手にしちゃって。んでんで、引数はView型にすることをお忘れずにっ!
      //onClickのメソッド定義
      boolean isOn = false; 
      private void switchEnable(View v){
              //フラグを切り替える
              if(isOn ==f alse){
                       isOn = true;
              }else{
                       isOn = false;
              }
              //有効無効等の設定をする
              spinner.setEnabled(isOn);
              spinner.setEnableInTouch(isOn);
      }

Androidアプリケーションのデモムービーを撮影したいとき

Android4.4以降で使用できるscreenrecord機能を使おう。

必要なもの

・Android端末(OS:Android4.4以上)
・MicroUSBケーブル(PCと端末を接続する)
・Android SDK/プラグイン等をインストール済み/JDKやadb等のパスを通してあるPC(OS:Linux MacOSX Windows など)

手順1:Android端末とPCをMicroUSBケーブルで接続します。

手順2:PC側のターミナル(Windowsならコマンドプロンプト)を開きます。

手順3:以下のコマンドを実行することで撮影開始。

adb screenrecord (保存ファイル名のフルパス 例:/sdcard/movie/test.mp4)

Nexus7等の解像度が大きい端末では解像度の指定が必要になります。

adb screenrecord フルパス --size 1280x720等

実行コマンド例

adb screenrecord /sdcard/test.mp4 --size 1280x720

これでtest.mp4というファイル名で撮影が開始されます。

・撮影終了 ^c
・撮影中断 ^z (途中までのファイルも残りません。)

まぁ大体これで180秒(3分)行けます。それ以上は知らないw

LatLonインスタンスから位置情報を 緯度,経度 の形で抽出したい

なんかGoogleMap(API v2)でマーカー立てまくってた時にマーカーの座標欲しいな、って人に。

これつかったって。

ぁ、これマーカーのクリックイベントの時の処理ね。そこはわかってくれよな?

@Override
public boolean onMarkerClick(Marker marker) {
	// TODO 自動生成されたメソッド・スタブ
	LatLng latlon = marker.getPosition();

	Pattern p = Pattern.compile("([0-9]+.[0-9]+,[0-9]+.[0-9]+)");
	Matcher m = p.matcher(latlon.toString());
	if(m.find()){
		Toast.makeText(getApplicationContext(), m.group(1), Toast.LENGTH_SHORT).show();
	}										
	return false;
}

一応マーカーをタップしたらToastで位置座標を 緯度,経度 形式で出力できるはず。

AlertDialog をshow()しようとすると強制終了する

BadTokenException: Unable to add window なんてエラーが出てるよな。 これ、Logcatで確認してくれよな?

とりあえずgetApplicationContext()とかでコンストラクタを渡した気になってると詰むらしい。 this使えってことやな。うん。これまじ大事。

ちなみにToastに与えるコンストラクタはgetApplicationContext()でいい、って言うから本当に理不尽。

解決策として、AlertDialogを表示するために新しくメソッドを書くのが一番っぽい。

っつーことでこんな感じにして使ってみてみ?

public void openDialog(){
	new AlertDialog.Builder(this)
	.setTitle("test String")
	.setMessage("test Message")
	.setNegativeButton("no",new DialogInterface.OnClickListener(){
	//やりたいこととか。
	})
	.setPositiveButton("yes",new DialogInterface.OnClickListener(){
	//やりたいこととか。
	})
	.show();
}

参考:http://d.hatena.ne.jp/ats337/20110322/1300803196

Eclipse にADT plugin をインストールしたいとき

例えば既に利用しているEclipseを使ってAndroidアプリケーション開発をしたいあなたんかにおすすめ。 なんちゃっていろんなところでは ヘルプ > 新規ソフトウェアのインストール にて

https://dl-ssl.google.com/android/eclipse/

なんてURLを追加してね!ってことしか書かれてなかったので他の方法をここに書いときますね。

手順

  • まず↓のURLを踏みます。
    http://developer.android.com/sdk/installing/installing-adt.html#Download
  • ページの真ん中よりも下ぐらいに
    Troubleshooting ADT Installation
    とかあるんで、そこのADTxxxx.zipをダウンロードします。
  • (愛用している?)Eclipseを起動します。
  • ヘルプ > 新規ソフトウェアのインストール を開きます
  • 右上ぐらいにある ”追加” を押します。
  • アーガイブを押します。
  • ダウンロードした ADTxxxxx.zipを選択します。
  • 出てきたチェックボックスの"開発ツール"を選択します。
    • (NDK使いたい人はそっちも入れてね!)
  • 次へ次へアンド次へ完了 とかやります。
  • なんかウィンドウ(セキュリティ系の警告を出す感じのやつ)が出るけどOKを押します。
  • 完了!

EclipseでAndroidアプリケーションを開発する際にfragmentというのが使われている

最近のAndroidの学習用テキストではほとんどがFragmentと呼ばれる要素が使われていません。そのためSDKを最新の状態に持ってきた時に今までどおりにプロジェクトを作成していたらfragmentが使われていて、activity_main.xmlをいじればいい、というだけではなくなってきます。

特に学習用テキストのソースコードを手打ちしているとfragmentって何よ、ってなるわけです。

Androidの開発を勉強するにあたって、テキストベースの教材であればそれを回避し、スムーズに進むためにも以下の様にするといいかと思います。

  • 新しくAndroidアプリケーションプロジェクトを立ち上げる
  • 下図の画面になるまで次へ次へ
    activityselect.png
  • もしここでBlankActivityを選択すると…
    activityfragment.png
    このまま行けば前述にある疑問の壁にぶつかることになりますので選択するのは下図の様にしましょう。
  • EmptyActivityを選択
    activityempty.png

以上でおしまいです! 頑張って勉強していきましょう!

AndroidでSQLiteを使いたい人のためのサンプル

タイトル通りです。AndroidでSQLiteを使いたい人のためにサンプル作ってみました。

使ってるもの

・TextView(データベースから読み込んだ内容を出力する用)
・EditText(データベースに挿入する内容を入力する用)
・Button x2(データベース内のデータ吹っ飛ばす用 & データベースに値挿入するとき用)
・SQLite(データ保存する用)

なんとなく気づいたかもしれませんが、EditTextに何か入力して片方のボタンを押せばそれをデータベースに格納し、データベースに保存されている内容を参照して、保存されている内容をTextViewに出力するんだろうなぁ、って感じ…というかそのままのコードですb

研究室のメンバーに説明するために作ってみただけですが、よかったらどうぞb

  • MainActivity.java
    package com.example.testdbsample;
    
    import android.app.Activity;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
    
    	TextView result;
    	EditText text;
    	SQLiteDatabase db;
    	Helper helper;
    	
    	
    	ContentValues value;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		//Viewの紐付け
    		result = (TextView)this.findViewById(R.id.result);
    		text = (EditText)this.findViewById(R.id.text);
    		
    	}
    	
    	
    	public void onResume(){
    		super.onResume();
    		helper = new Helper(this);
    		db = helper.getWritableDatabase();
    		
    	}
    	
    	
    	public void onPause(){
    		super.onPause();
    		db.close();
    	}
    	
    	
    	public void insert(View v){
    		String str = text.getText().toString();
    		Toast.makeText(this, str, Toast.LENGTH_LONG).show();
    		if(str.length()>0){
    			//何か入力されていたら
    			
    			//insert into table_name(column_name......)values(入れたい値....)
    			value = new ContentValues();
    			value.put(Helper.db_column, str); 
    			db.insert(Helper.table_name,null,value );// insert into table_name(string)values(str);
    			text.setText("");
    			reload();
    		}else{
    			Toast.makeText(this, "文字数が0???", Toast.LENGTH_LONG).show();
    		}
    	}
    	
    	public void reload(){
    		result.setText("");
    //		Cursor c = db.query(DBdata.table_name, new String[]{DBdata.db_path}, null, null, null, null, null);
    		Cursor c = db.query(Helper.table_name, new String[]{Helper.db_column}, null,null,null,null,null);
    		
    		
    		StringBuilder sb = new StringBuilder();
    		
    		boolean isEOF = c.moveToFirst();
    		while(isEOF){
    			Toast.makeText(this,"取り出し:"+ c.getString(0), Toast.LENGTH_SHORT).show();
    			sb.append(c.getString(0)+"\n");
    			isEOF = c.moveToNext();
    		}
    		
    		result.setText(sb.toString());
    	}
    	public void delete(View v){
    		result.setText("");
    		db.delete(Helper.table_name, null, null);
    	}
    }
  • Helper.java
    package com.example.testdbsample;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    public class Helper extends SQLiteOpenHelper {
    
    
    	public final static String db_name="testDB";
    	public final static String db_column = "name";
    	public final static String table_name="testTable";
    	final static String create =""
    			+ "create table "+table_name+" ("+ db_column +" text);"; 
    	
    	
    	
    	final static int db_version = 2;
    	
    	public Helper(Context context) {
    		super(context,table_name, null, db_version);
    		// TODO Auto-generated constructor stub
    	}
    
    	@Override
    	public void onCreate(SQLiteDatabase db) {
    		// TODO Auto-generated method stub
    		db.execSQL(create);
    	}
    
    	@Override
    	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    		// TODO Auto-generated method stub
    		db.delete(table_name,  null, null);
    	}
    
    }
  • activity_main.xml
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="${relativePackage}.${activityClass}" >
    
        <EditText
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_marginTop="71dp"
            android:ems="10"
            android:hint="plz input anything"
            tools:ignore="HardcodedText" >
    
            <requestFocus />
        </EditText>
    
        <Button
            android:id="@+id/insert"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/text"
            android:layout_marginRight="132dp"
            android:text="Insert"
            tools:ignore="HardcodedText"
            android:onClick="insert" />
    
        <Button
            android:id="@+id/delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/insert"
            android:layout_alignBottom="@+id/insert"
            android:layout_alignParentRight="true"
            android:layout_marginRight="34dp"
            android:text="delete"
            android:onClick="delete"
            tools:ignore="HardcodedText" />
    
        <TextView
            android:id="@+id/result"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/insert"
            android:layout_marginTop="79dp"
            android:text=""
             />
    
    </RelativeLayout>

レイアウトを液晶サイズ毎に指定するときのswの意味

スマートフォン用のレイアウトと別にタブレット用レイアウトを準備したいんですけど、って時にやらなくちゃいけない swXXX指定。 実際にはタブレット用のレイアウトフォルダを作って、名前を layout-sw600dp とか付ける必要がある。 このswの意味ってのは実は液晶の短い方のサイズが600dpってことみたい。

つまりタブレット用のレイアウトを組むときは縦画面の時は横は600dpってこと。等間隔にボタンを配置したい、とかそういう時にこういう知識って役立ちそう。

Android のActionBarにあるMenuについてXMLでアイコンとテキストを出したい

XMLでメニューを書くときに下みたいに成ると思う。

menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.hogehoge">
    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:orderInCategory="100"
        app:showAsAction="never" />
    <item
        android:id="@+id/action_checkin"
        android:title="Checkin"
        android:icon="@mipmap/ic_action_edit"
        app:showAsAction="ifRoom|withText"/>
</menu>

つまり何がいいたいか、っていうと

    <item
        android:id="@+id/action_checkin"
        android:title="Checkin"
        android:icon="@mipmap/ic_action_edit"
        app:showAsAction="ifRoom|withText"/>

の部分の

app:showAsAction="ifRoom|withText"

これ。 appって名前空間は前述に定義してる通りで、appって名前じゃなくても良かったりする。 要するにメニューにアイコンもメニューのタイトルも出したいときは

ifRoom|withText

って書けばいいってことよ

Android Studioで現在開いているタブ(ファイル)を閉じるショートカット@デフォルト

command+ F4 (Mac OSX)
Ctrl + F4 (Windows)

って感じなわけですが、Eclipseから移行してきた人にはキーマップで

command + w (Mac OSX)
Ctrl + w (Windows)

みたいにしたほうがいいかもしれないっすな。

添付ファイル: fileactivityselect.png 464件 [詳細] fileactivityfragment.png 450件 [詳細] fileactivityempty.png 448件 [詳細]