2012年07月06日


バッテリー残量取得アプリのフォルダを監視してデータを取得する / Android Java

呼び出されるアプリは、こちらです。実際は専用のフォルダを設定して権限設定するべきだと思いますが、テストに余計な時間がかかるので、files の下を監視しています。

package jp.winofsql.app01;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.FileObserver;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ClickAndCallActivity extends Activity {
	private static final String TAG = "Call";
	private static final boolean D = true;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		if(D) Log.i(TAG, "+++ ON CREATE : 初回の開始 +++");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		observer.startWatching();


		// 呼び出しボタン( 自作アプリの結果取得 )
		Button btn4 = (Button) this.findViewById(R.id.button4);
		btn4.setOnClickListener(new OnClickListener() {  
			  
			 public void onClick(View v) {  
	
				 if(D) Log.i("呼び出し3", "------");
				 
				 Intent intent = new Intent();
				 intent.setClassName("jp.winofsql.app02", "jp.winofsql.app02.BatteryChangedActivity");
				 // 結果を取得する為の呼び出し( バッテリー残量の取得 )
				 startActivity(intent);

			}

		});

	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		observer.stopWatching();
		if(D) {
			Log.i(TAG, "onDestroy に到達しました");
			Log.i(TAG, "--- ON DESTROY ---");
		}
	}

	// バッテリー残量取得アプリのフォルダを監視してデータを取得する
	private FileObserver observer = new FileObserver("/data/data/jp.winofsql.app02/files/") {

		@Override
		public void onEvent(int event, String path) {
			if (event == FileObserver.CLOSE_WRITE) {
				try{
					Context ctxt = createPackageContext("jp.winofsql.app02",0);
					FileInputStream input = ctxt.openFileInput("BatteryLevel.txt");  
					BufferedReader reader = new BufferedReader(new InputStreamReader(input));
					String line = reader.readLine();
					reader.close();
					Log.i(TAG, "--- ファイル監視の結果 ---");
					Log.i(TAG, line);
				}
				catch(Exception e) {
				 	Log.i(TAG, e.getMessage());
				}
			}
		}
	};

}




タグ:android
posted by at 2012-07-06 20:04 | Android Java | このブログの読者になる | 更新情報をチェックする

2012年07月05日


呼び出し元にバッテリー残量を知らせるアクティビティ

呼び出し元は、startActivityForResult で呼び出して、onActivityResult で結果を受け取ります。呼び出し元には返していませんが、バッテリーの情報が入った intent 内のキーの一覧をログに表示しています

ファイルに書き込んでいるのは特別な場合のデータの受け渡しの為に用意しています。例えば、データを戻したい相手が AIR ベースの拡張を使っていて、こちら側を呼び出した場合に直接イベントによる受信ができない場合です。その場合はタイマーあるいはフォルダの監視で取得する事を想定しています。
package jp.winofsql.app02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

public class BatteryChangedActivity extends Activity {
    private static final String TAG = "Battery";
    private static final boolean D = true;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        if(D) Log.i(TAG, "+++ ON CREATE : 初回の開始 +++");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    @Override
    protected void onResume() {
        if(D) Log.i(TAG, "--- 再開 ---");
        super.onResume();
        
        IntentFilter filter = new IntentFilter();
        
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(mBroadcastReceiver, filter);
    }

    @Override
    protected void onPause() {
        if(D) Log.i(TAG, "--- 一時停止 ---");
        super.onPause();
        
        unregisterReceiver(mBroadcastReceiver);
    }

    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        	// バッテリーの情報が入った intent 内のキーの一覧
            Bundle bundle = intent.getExtras();
            Set<String> set = bundle.keySet(); 
            Iterator<String> it = set.iterator();
            while (it.hasNext()) {
            	if(D) Log.i(TAG, it.next());
            }
            
            // バッテリー残量の取得
            int level = intent.getIntExtra("level", 0);
            if(D) Log.i(TAG, Integer.toString(level));
            // Activity の呼び出し元へデータを戻す
            BatteryChangedActivity.this.setResult(level);

        	try {
        	    FileOutputStream output = openFileOutput("BatteryLevel.txt", MODE_WORLD_READABLE);  
        	    // 書き込み  
        	    output.write(Integer.toString(level).getBytes());  
                if(D) Log.i(TAG, "--- ファイルへ書き込みました ---");
        	    // ストリームを閉じる  
        	    output.close();
        	    
        		// 他からフォルダを監視する為に読み込み権限を与える(初回用)
        		File file = new File("/data/data/jp.winofsql.app02/files");
        		file.setReadable( true, false );
        	    
        	} catch (IOException e) {  
        		e.printStackTrace();  
        	}
            
            
            if(D) Log.i(TAG, "--- 処理を終了します ---");
            finish();
        }
    }; 
  

}
07-06 10:51:27.828: I/呼び出し3(24048): ------
07-06 10:51:27.898: I/Battery(23912): +++ ON CREATE : 初回の開始 +++
07-06 10:51:27.918: I/Battery(23912): --- 再開 ---
07-06 10:51:27.938: I/Battery(23912): icon-small
07-06 10:51:27.938: I/Battery(23912): scale
07-06 10:51:27.938: I/Battery(23912): present
07-06 10:51:27.938: I/Battery(23912): technology
07-06 10:51:27.938: I/Battery(23912): level
07-06 10:51:27.938: I/Battery(23912): voltage
07-06 10:51:27.938: I/Battery(23912): status
07-06 10:51:27.938: I/Battery(23912): plugged
07-06 10:51:27.938: I/Battery(23912): health
07-06 10:51:27.938: I/Battery(23912): temperature
07-06 10:51:27.938: I/Battery(23912): 50
07-06 10:51:27.938: I/Battery(23912): --- ファイルへ書き込みました ---
07-06 10:51:27.938: I/Battery(23912): --- 処理を終了します ---
07-06 10:51:27.968: I/Battery(23912): --- 一時停止 ---
07-06 10:51:27.988: I/Call(24048): --- ファイル監視の結果 ---
07-06 10:51:27.988: I/呼び出し結果(24048): 50
07-06 10:51:28.019: I/Call(24048): 50
07-06 10:51:28.898: I/Call(24048): --- タイマーの結果 ---
07-06 10:51:28.898: I/Call(24048): 50

※ エミュレータのバッテリー残量の変更は、telnet で接続して power capacity nn (ドキュメントは誤記)

※ 通常 telnet localhost 5554 で接続。
※ Windows7 の telnet は追加でインストールする必要があります





posted by at 2012-07-05 02:15 | Android Java | このブログの読者になる | 更新情報をチェックする

2012年07月04日


クリックしてサーチを呼び出す / Android Java

既存のアプリケーションを呼び出す為に、intent を使用して Activity を開始します。
サーチ1では、クラス名で直接『サーチ』を呼び出していますが、サーチ2では、API を使って呼び出しています(その際、検索文字列が指定できます)。また、自作アプリの呼び出しでは、呼び出されたアプリから結果が戻されるようになっています

※ DDMS の stop では、ON DESTROY には移行しません
package jp.winofsql.app01;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ClickAndCallActivity extends Activity {
    private static final String TAG = "Call";
    private static final boolean D = true;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        if(D) Log.i(TAG, "+++ ON CREATE : 初回の開始 +++");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 呼び出しボタン( サーチ1 )
	    Button btn1 = (Button) this.findViewById(R.id.button1);
	    btn1.setOnClickListener(new OnClickListener() {  
	    	  
	         public void onClick(View v) {  
	
	        	 Intent intent = new Intent();
	        	 
	        	 intent.setClassName(
	        			 "com.android.quicksearchbox",
	        			 "com.android.quicksearchbox.SearchActivity"
	        			 );
	        	 
	        	 if(D) Log.i("呼び出し1", "------");
	        	 startActivity(intent);     	        	 

	        }
		          
	    });          
	    
        // 呼び出しボタン( サーチ2 )
	    Button btn2 = (Button) this.findViewById(R.id.button2);
	    btn2.setOnClickListener(new OnClickListener() {  
	    	  
	         public void onClick(View v) {  
	
	        	 if(D) Log.i("呼び出し2", "------");

	        	 startSearch("android startSearch", false, null, true); 	        	 

	         }
		          
	    });          

	    // 終了ボタン( ON DESTROY へと移行 )
	    Button btn3 = (Button) this.findViewById(R.id.button3);
	    btn3.setOnClickListener(new OnClickListener() {  
	    	  
	    	public void onClick(View v) {
	    		// 終了
	    		finish();
	        }
		          
	    });          

        // 呼び出しボタン( 自作アプリの結果取得 )
	    Button btn4 = (Button) this.findViewById(R.id.button4);
	    btn4.setOnClickListener(new OnClickListener() {  
	    	  
	         public void onClick(View v) {  
	
	        	 if(D) Log.i("呼び出し3", "------");
	        	 
	        	 Intent intent = new Intent();
	        	 intent.setClassName("jp.winofsql.app02", "jp.winofsql.app02.BatteryChangedActivity");
	        	 // 結果を取得する為の呼び出し( バッテリー残量の取得 )
	             startActivityForResult(intent,0);

	             Timer mTimer = new Timer(true);
	             mTimer.schedule( new TimerTask(){
	                 @Override
	                 public void run() {

	             		try{
		         			Context ctxt = createPackageContext("jp.winofsql.app02",0);
		        			FileInputStream input = ctxt.openFileInput("BatteryLevel.txt");  
		        			BufferedReader reader = new BufferedReader(new InputStreamReader(input));
		        			String line = reader.readLine();
		        			reader.close();
		                	Log.i(TAG, "--- タイマーの結果 ---");
		                	Log.i(TAG, line);

	             		}
	            		catch(Exception e) {
	                    	Log.i(TAG, e.getMessage());
	            		}
	                	 
	                 }
	             }, 1000);	             
	             
	        }
		          
	    });          

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        
        if(D) {
        	Log.i(TAG, "onDestroy に到達しました");
        	Log.i(TAG, "--- ON DESTROY ---");
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	if(D) Log.i("呼び出し結果", Integer.toString(resultCode));
    }
    
}
07-06 04:55:10.837: I/呼び出し1(331): ------
07-06 04:55:16.377: I/呼び出し2(331): ------
07-06 04:55:23.116: I/呼び出し3(331): ------
07-06 04:55:23.446: I/Battery(354): +++ ON CREATE : 初回の開始 +++
07-06 04:55:23.546: I/Battery(354): --- 再開 ---
07-06 04:55:23.556: I/Battery(354): icon-small
07-06 04:55:23.566: I/Battery(354): scale
07-06 04:55:23.566: I/Battery(354): present
07-06 04:55:23.566: I/Battery(354): technology
07-06 04:55:23.566: I/Battery(354): level
07-06 04:55:23.566: I/Battery(354): voltage
07-06 04:55:23.566: I/Battery(354): status
07-06 04:55:23.566: I/Battery(354): plugged
07-06 04:55:23.566: I/Battery(354): health
07-06 04:55:23.566: I/Battery(354): temperature
07-06 04:55:23.566: I/Battery(354): 50
07-06 04:55:23.566: I/Battery(354): --- 処理を終了します ---
07-06 04:55:23.616: I/Battery(354): --- 一時停止 ---
07-06 04:55:23.656: I/呼び出し結果(331): 50

参考

Activity | Android Developers
Intent | Android Developers
Log | Android Developers


posted by at 2012-07-04 21:30 | Android Java | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します