ノンプログラマー・プログラミング・ガイド

ほぼ独学。もはやおっさんになりかかってからプログラミングの勉強開始。HTML、CSS、JavaScript、SQL、PHP、Javaがなんとなく解る。Joomla!とandroidで書いたプログラムを配布中。iPhoneアプリ作りたいからMacくれ(下さい)。

2013年08月

Activity間の値の受け渡しでは、Intentに値を渡してやって、呼び出し先のActivityからIntentの値をとってやるってなやりかたがあるんですが、面倒くさいです!ちょっとした値の受け渡しならいいんですけどね。どーすればいいのかと考えたところ、こんなやりかたがあるのかと・・・。シングルトンとか呼ばれるやつなのかな・・・?


解決策 値を保持するstaticなクラスを作る

値を保持するクラスを作ってやればいいのかと。DataHolderのインスタンスはひとつだけ作成するようにして、常にDataHolder.getInstance()から呼び出すようにすれば、データはひとつのインスタンス内に保持されます。たぶんきっとこんな感じ。
public class DataHolder{
	
	
	static DataHolder _instance = null;
	
	/**
	 * 常にこのメソッドから呼び出すようにする
	 * 
	 * 
	 * @return
	 */
	static public DataHolder getInstance(){
		if(_instance==null){
			_instance = new DataHolder();
		}
		return _instance;
	}
	
	
	
	String test ="AAAAAAAAAAAAAAAAAAAA";
	
	public String getTestString(){
		return test;
	}
	
	public void setTestString(String txt){
		this.test = txt;
	}
}
 
たとえば、Activity Aで、こんな感じで値を渡してやれば、
DataHolder holder = DataHolder.getInstance();
holder.setTestString("Passed String on Activity A!");

Activity Bでは、こんな感じで値を取れます。
DataHolder holder = DataHolder.getInstance();
holder.getTestString();

まず、Activity AでgetInstanceを呼び出したときには、_instanceは生成されていないので、新しく作られます。で、その_instance内に値を渡してます。次に、Activity BでgetInstance()で呼び出した_instanceは、ActivityAで作成した_instanceが残っているので、Ativity Aの_instanceと同じものです。

細かく言うと、A->B->Aって戻った場合は、最初のAで作成したDataHolderが残ってるので、値を初期値にするようなメソッドが必要な場合もあるのかと・・・。まぁ、しらね。



 で、ここまでは、普通に思いついたんですけど、いろいろみているとなにやらApplicationなるクラスが用意されている模様です。このクラスを拡張したほうが、もっと永続的にデータが保持されるぜwwwwってコメントを見かけたんですけど、真偽不明。Android DevelopersのReferenceには、Applicationのクラスは、ほぼ使う必要ねーよって書かれてるし・・・。アプリのContextが取れるのがいいのかな・・・?

Applicationを拡張して、値を保持するクラスを作る


ほぼ一緒。違いは、Applicationをextendsしてるだけです。
public class DataHolder extends Application{
	
	
	static DataHolder _instance = null;
	
	/**
	 * 常にこのメソッドから呼び出すようにする
	 * 
	 * 
	 * @return
	 */
	static public DataHolder getInstance(){
		if(_instance==null){
			_instance = new DataHolder();
		}
		return _instance;
	}
	
	
	
	String test ="AAAAAAAAAAAAAAAAAAAA";
	
	public String getTestString(){
		return test;
	}
	
	public void setTestString(String txt){
		this.test = txt;
	}
}

あと、manifest.xmlのapplicationのnameをクラス名にしてやる必要があるみたい。
    <application
        android:name=".DataHolder"  >



 

Androidでデバイスの画面サイズを取りたいってな場合の方法。ここに載ってました。


How to get screen dimensions : Stackoverflow



ポイントとして、画面のサイズ取得メソッドがAPI13以降とその前でメソッドが違うみたいです。
int Measuredwidth = 0;
int Measuredheight = 0;
Point size = new Point();
WindowManager w = getWindowManager();

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
    w.getDefaultDisplay().getSize(size);

    Measuredwidth = size.x;
    Measuredheight = size.y; 
}else{
    Display d = w.getDefaultDisplay(); 
    Measuredwidth = d.getWidth(); 
    Measuredheight = d.getHeight(); 
}
API13以降だとgetSizeを使ってpointに渡してやって、getWidth(),getHeight()のメソッドを使うのかの違いみたいです。getSize(size)は、Java特有の変数の値渡しとかいうやつで、このメソッドでsizeの値は更新されていて、画面サイズがxとyに挿入されています。個人的には、返り値で渡せよとか思ってしまう・・・。なんか気持ち悪い。


Activity以外から画面サイズを取得する


Activity上だと、getWindowManager()で直接WindowManagerが取れるんですけど、Activityじゃない場合は、Contextから、こんな風にするみたい

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

contextは、Activityから渡してやる必要があります。




 

Androidで、一定時間の後に実行したいコードがある場合の書き方です。俗称でdelayとか言われるメソッドかと。まんまか・・・・。遅延メソッド?よくしりません・・・。作成方法は、簡単でhandlerを作って、handlerのpostDelayedメソッドを使用します。引数には、runnableです。


final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
	@Override
	 public void run() {
		 //ここにかく
	}
 }, 500);
 上記のサンプルコードでは、500ミリ秒後(0.5秒後)に、run内のコードが実行されます。

 

Androidアプリ内で保存した画像をギャラリーで表示させる方法です。全ては、このチュートリアル(Taking Photos Simply)にかいてあります。


要点だけ
  1. 保存先をパブリックフォルダーのPicturesにする
  2. 保存した画像をAndroidさんに教える

保存先のフォルダーを取得する

保存先のパブリックフォルダーへのパスを取得します。
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

ルートなので、適当に下位のフォルダー名を入れてもいいんじゃないのかと・・・・。


Androidに画像追加を知らせる

	    Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
	    Uri contentUri = Uri.fromFile(file);
	    mediaScanIntent.setData(contentUri);
	    this.sendBroadcast(mediaScanIntent);


fileは、保存した画像のパスです。


 

Androidのアプリは、シングルスレッドとかいう処理の仕組みを採用していて、別のスレッドを作成した場合に、その別スレッドからアプリ内のViewを操作することはできなくなってます。僕の乏しい理解力だと、そもそもスレッドとはなんぞや?というレベルなんですが、まぁ、別のスレッドからはUI操作はできないと言うことらしいです。もし別のスレッドからUIを操作したら、こんなエラーが表示される模様

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.


解決策:外部スレッドからUI操作をするためのメソッド

        runOnUiThread(new Runnable() {

            public void run() {
                 //UI操作するコードをここに書く
            }
        });     

ActivityのメソッドにrunOnUiThreadなるメソッドが用意されています。runの中では、UI操作ができる模様。


 

このページのトップヘ