現在では以下のIDEで開発できます。
メニューバー > ファイル > インポート > 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.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 message; boolean hantei; hantei = message.getText().toString().equals("");
こんなので悩むなよ?
ええ、私は悩みました。
ちなみにisEmpty()はどうなの?という人へ。
isEmptyですとオブジェクトのlength取ってきて、0かどうかを比較するので使おうとするならば
hantei = message.getText().toString().isEmpty();
対して使い方が変わらないため、お好みでどうぞ。
EditTextの入力を無効にするには? → タッチすら出来なくすればいい。
ということで
EditText edit = (EditText) findViewById(R.id.edittext); edit.setFocusable(false);
あとから気づいたけど
edit.setEnable(false);
でもいいらしい。タッチするとソフトウェアキーボードまで出るからユーザビリティ的にはこれは無いかなぁ、と。
Mac OSX: Eclipseのメニューバー > プロジェクト > クリーンアップ > 全てのプロジェクト にチェック > 完了
で解決。
上記の方法で解決出来ない場合、AndroidManifest.xmlを開いて
Manifestタブの packageの値が src.("パッケージの名前") と同じかどうかを確認する。 違う場合は同じのものにする。
また、同じものにした後に、クラスファイルの方でエラーが検出されるかもしれないが おそらくその場合は
import ("Manifest タブの package の値")
を削除するだけである。これは消して全く問題無い。
クラスファイルであればパッケージ名にクラス名を"."(ドット)でつなげればおkだが…
レイアウトの場合は?
レイアウトは AndroidManifest.xmlのManifestタブのPackageの値が関係する。 パスは
"ManifestのPackageの値".res.layout."レイアウトファイル名"
になるみたい?
例えば com.example.res.layout.main とか。
NETWORK_PROVIDERは携帯電話の基地局間通信を用いて位置情報を取得する方法。 GPSで取得するより消費電力もすっごく小さいからバッテリーにも優しいやつ。 しかも取得までの時間がGPSと比べると化け物レベルに速い。まじ爆速。
だけど
そんな化け物を使おうとしたら位置情報が取れるときと取れない時が出て来るかも? そんな時のトラブルシューティングです。
まず
設定>無線とネットワーク>モバイルネットワーク>3Gを有効に。
3G回線が使えないとネットワークプロバイダは使えません。(これ前提条件
http://blog.dtdweb.com/2013/04/06/gps_desc/のコメントの所とかにも居る。以下の対処法を試してみては?
Avoid object allocations during draw/layout operations (preallocate and reuse instead)
なんて警告じゃないです? そしてonDraw内にPaintオブジェクトやらBitmapオブジェクトを生成するコード書いていないです?
とりあえず、onDrawを呼ぶたびに同じオブジェクトを何回も生成しているからメモリを無駄に消費することになるからやめろや って言われてる。
PaintオブジェクトやらBitmapオブジェクトやらはとりあえずコンストラクタの中で生成しておけば レイアウトが呼ばれた時に一度しか生成しない。
別に何回も呼ばないし、全然メモリを気にする必要がなければ黄色いところにカーソル合わせて 警告を無効化するアノテーションをつけとけばいいよ、うん。
とりあえずアノテーションもつけたくねーんだけどって場合は
手順1.変数の宣言で大域変数?になるような一番外側でする。 手順2.オブジェクトの取得?生成?をコンストラクタの中でする。
これでおk
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()の中にそれも入ってるって前提で書いてたわ。すまんこ。
GoogleMap map = super.getMap();//←だいたいはMapFragmentからgetMap()するかと思う。 map.setMyPosition(true);
こんなコードを書けば大体GoogleMapのレイアウト上に現在地のマークが出る。これはLocationListenerを使わなくても出る。
おそらくLocationListenerを記述しなくてもGoogleMap#setMyPositionの中でLocationListenerがセットされているのかもしれない。(確認なんてしてないから適当に書いてます。ご了承ください。よかったら確認してみてください ←ぉぃ)
んでんで、プロバイダーをGPS_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使えば共存はできるんとちゃうの?と思うけど、試してない。(諸事情でNETRORK_PROVIDERを使いたいんです…(切実) )
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では ぬるぽ 吐かれました。マジキチ。
これはString型の変数に対してこんなことをすると起きる。
String str = "abc"; if(str = "abc"){ 処理 }
どうしてかわかるかな?どうやったら対処できるかな? ということで、Java Tips を参照されたし。 まじで注意。 SpinnerやSQLiteが混ざってきたら下手した時にかなり苦労するかもしれない。
Spinner spinner = (Spinner)findViewById(R.id.hoge); spinner.setEnabled(false);これだけ。これをするだけでspinnerを触らせても反応しなくなる。
spinner.setEnabled(true);//ぁ、リソースの確保はできているって前提な。 spinner.setEnableInTouch(true);これだけ。これだけなんだけどsetEnableInTouchにはまじで気付かなかった。気づくまでにホント時間がかかった。
よかったら参考にするといいですっ(フンヌッ
<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"/>
//onCreate内 Button switchBtn = (Button)findViewById(R.id.switchBtn); Spinner spinner = (Spinner)findViewById(R.id.spinner);
//onClickのメソッド定義 boolean isOn = false; private void switchEnable(View v){ //フラグを切り替える if(isOn ==f alse){ isOn = true; }else{ isOn = false; } //有効無効等の設定をする spinner.setEnabled(isOn); spinner.setEnableInTouch(isOn); }
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
なんか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で位置座標を 緯度,経度 形式で出力できるはず。
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を使ってAndroidアプリケーション開発をしたいあなたんかにおすすめ。 なんちゃっていろんなところでは ヘルプ > 新規ソフトウェアのインストール にて
https://dl-ssl.google.com/android/eclipse/
なんてURLを追加してね!ってことしか書かれてなかったので他の方法をここに書いときますね。
手順
http://developer.android.com/sdk/installing/installing-adt.html#Download
Troubleshooting ADT Installationとかあるんで、そこのADTxxxx.zipをダウンロードします。
最近のAndroidの学習用テキストではほとんどがFragmentと呼ばれる要素が使われていません。そのためSDKを最新の状態に持ってきた時に今までどおりにプロジェクトを作成していたらfragmentが使われていて、activity_main.xmlをいじればいい、というだけではなくなってきます。
特に学習用テキストのソースコードを手打ちしているとfragmentって何よ、ってなるわけです。
Androidの開発を勉強するにあたって、テキストベースの教材であればそれを回避し、スムーズに進むためにも以下の様にするといいかと思います。
以上でおしまいです! 頑張って勉強していきましょう!
タイトル通りです。AndroidでSQLiteを使いたい人のためにサンプル作ってみました。
使ってるもの
・TextView(データベースから読み込んだ内容を出力する用) ・EditText(データベースに挿入する内容を入力する用) ・Button x2(データベース内のデータ吹っ飛ばす用 & データベースに値挿入するとき用) ・SQLite(データ保存する用)
なんとなく気づいたかもしれませんが、EditTextに何か入力して片方のボタンを押せばそれをデータベースに格納し、データベースに保存されている内容を参照して、保存されている内容をTextViewに出力するんだろうなぁ、って感じ…というかそのままのコードですb
研究室のメンバーに説明するために作ってみただけですが、よかったらどうぞb
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); } }
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); } }
<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>
スマートフォン用のレイアウトと別にタブレット用レイアウトを準備したいんですけど、って時にやらなくちゃいけない swXXX指定。 実際にはタブレット用のレイアウトフォルダを作って、名前を layout-sw600dp とか付ける必要がある。 このswの意味ってのは実は液晶の短い方のサイズが600dpってことみたい。
つまりタブレット用のレイアウトを組むときは縦画面の時は横は600dpってこと。等間隔にボタンを配置したい、とかそういう時にこういう知識って役立ちそう。
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
って書けばいいってことよ
command+ F4 (Mac OSX) Ctrl + F4 (Windows)
って感じなわけですが、Eclipseから移行してきた人にはキーマップで
command + w (Mac OSX) Ctrl + w (Windows)
みたいにしたほうがいいかもしれないっすな。