kurukuru-papaのブログ

主に、ソフトウェア開発に関連したメモを書き溜めたいと思います。

H2データベースにODBC接続してみました

ちょっと、Windows環境でODBC接続してSQLを実行したくなりました。

手元にあるPCを確認すると、データベースがインストールされていませんでしたので、手軽にインストールできて、ODBC接続ができるH2データベースを使用して、ODBC接続するまでに行った手順をメモしておきます。

続きを読む

アプリポケット Ver.0.5.0公開

少し時間が経ってしまった話ですが、2012/10/28に、Android用ランチャーアプリ「アプリポケット」のVersion 0.5.0を公開しました。

今回の大きな変更点は、広告表示を廃止したことです。メイン画面以外で広告表示をしていて、個人的には何も疑問にも思わずに開発・使用していたのですが、Google Playへのコメントを見ると、数名の方が、広告表示を気にしていらっしゃいました。より多くの方にアプリを使って頂きたいので、今回、広告表示を廃止させて頂きました。

変更点概要

  1. 広告表示を廃止しました。
  2. アプリ起動情報ダイアログのレイアウトを改善しました。
  3. デフォルトテーマで透過設定をしている場合に、メイン画面を表示すると、タイトルバーが透明になっていました。タイトルバーは透過しないように修正しました。
  4. Android端末のアプリ詳細画面を表示する機能が、アプリ起動情報ダイアログ内に存在しましたが、少々わかりづらいようです。アプリアイコン長押しメニューに表示するように変更しました。

動作環境

  • 対象OS:Android 1.6以降
  • 動作確認端末:Xperia(SO-01B)、Arrows X LTE (F-05D)

Mac&TomcatでJenkins環境構築

Mac上にJenkinsの環境を作ることにしました。

次のことから、一旦、Tomcat環境を構築し、そのTomcatにJenkinsを追加する方法で、環境構築することにしました。

簡単に環境構築してしまおうと思えば、JenkinsとTomcatが一式になったpkgインストーラーがあるようですが、ネット情報では、うまくインストールできていない人がチラホラいるようです。自分が作業してみて問題が発生した場合、Jenkinsの問題と、Tomcatの問題の切り分けがつきにくくなりそうです。

私は、Jenkins以外でも、Tomcatを使う事がありそうです。

Tomcatインストール

Tomcatのページから、最新バージョンをダウンロードしました。バージョンは、7.0.29です。

ダウンロードしたZIPファイルが展開されると「apache-tomcat-7.0.29」というフォルダが出来ました。これを次の場所に移動しました。

フォルダのバージョン番号を気にせず起動できるよう、Tomcatディレクトリに、シンボリックリンクを作成しておきました。ターミナルから実施します。

$ ln -s /Applications/apache-tomcat-7.0.29 /Applications/tomcat

Tomcatを起動しました。シェルへの実行権限付与では、シェル内で他のシェルを呼んでいたりするようですので、全シェルに権限付与しました。

$ cd /Applications/tomcat
$ chmod a+x *.sh
$ ./startup.sh

ブラウザから次のURLにアクセスすると、正常にTomcatのページが表示されることを確認できました。

Tomcatを停止するには、次のコマンドを実行しました。

$ ./shutdown.sh

Jenkinsインストール

Jenkinsのページから最新バージョンのWARファイルをダウンロードしました。

  • Jenkinsホームページ
  • ダウンロードしたファイル
    • jenkins.war(バージョン1.477)

上記jenkins.warを/Applications/tomcat/webappsに配置しました。そして、Tomcatを再起動し、次のURLへアクセスすると、Jenkinsのページが表示されることを確認できました。

とりあえず、Jenkinsの管理ページから、次のプラグインを追加しておきました。

  • プラグイン
    • JobConfigHistory Plugin
    • Copy Artifact Plugin

Denchin 0.2.7 公開

本日、バージョン0.2.7を公開しました。要望と不具合の対応です。

今回取り入れた要望は、Google Playのプロフィールで公開していたメールアドレスに、ご意見を頂いた内容です。メールで会話して、ユーザーの方が、Denchinをどのように使っているかお聞きする事ができ、とても興味深く感じました。

特に印象深かった話があります。私は、Denchinにおまけ的な扱いで追加したステータスバーへの残量表示機能を作成していました。ですが、会話したユーザーの方は、ステータスバー表示のみを使いたいと思い、ウィジェットは不要と考えていました。「おまけ」が「メイン機能」として使われていたんですね。

変更内容

1.Denchinのウィジェットを配置していない場合、バッテリー監視を行わない仕様でしたが、ウィジェットなしでも、ステータスバー/ノーティフィケーションへの残量通知設定が有効になっていれば、バッテリー監視を行うように仕様を変更しました。
2.メイン画面において、経過時間を表す文言が「〜時〜分〜秒」となっていたのを「〜時間〜分〜秒」に修正しました。
3.細かい不具合修正。

動作確認環境

HTML5のWeb Storageを使ってみました

HTML5Web Storage機能を使ってみました。

Web Storageには、sessionStorage, localStorageの2種類が用意されていて、sessionStorageはセッション単位でデータを保持し(ウインドウやタブを開いている間だけデータ保持。閉じたらデータが消える)、localStorageは永続的にデータを保持します。シンプルなメソッドで操作でき、sessionStorageもlocalStorageも同じメソッドが用意されていて、使いやすかったです。

Web Storageは、各種ブラウザの対応も普及しているようですね。概ね、IE8以降、Firefox3.6以降、Chrome8以降、Safari5以降で使えそうです。

では、作成してみたサンプルプログラムを説明します。

画面イメージ

作成したプログラムをブラウザで表示した画面イメージです。sessionStorageとlocalStorageで、入力項目の保存、再表示、1件削除、全件削除を行えるようにしました。

プログラム(画面レイアウト)

HTMLです。Bootstrapを使っています。

<h4>Session Storage</h4>
<input id="sessionText" type="text"><input id="sessionTextDelete" type="button" value="削除" class="btn btn-mini"><br>
<textarea id="sessionTextarea" rows="2"></textarea><input id="sessionTextareaDelete" type="button" value="削除" class="btn btn-mini"><br>
<input id="sessionSave" type="button" value="保存" class="btn">
<input id="sessionLoad" type="button" value="再表示" class="btn">
<input id="sessionClear" type="button" value="クリア" class="btn">

<h4>Local Storage</h4>
<input id="localText" type="text"><input id="localTextDelete" type="button" value="削除" class="btn btn-mini"><br>
<textarea id="localTextarea" rows="2"></textarea><input id="localTextareaDelete" type="button" value="削除" class="btn btn-mini"><br>
<input id="localSave" type="button" value="保存" class="btn">
<input id="localLoad" type="button" value="再表示" class="btn">
<input id="localClear" type="button" value="クリア" class="btn">

プログラム(Web Storage使用可否判断)

sessionStorage, localStorageを見ることで、使用可否を判断できるようです。

        if (window.sessionStorage) {
            console.log("sessionStorage使用可能");
        } else {
            console.log("sessionStorage使用不可");
        }
        if (window.localStorage) {
            console.log("localStorage使用可能");
        } else {
            console.log("localStorage使用不可");
        }

プログラム(データ保存)

画面上の「保存」ボタンをクリックした時に動作する処理です。sessionStorage, localStorageのsetItemメソッドを使って、キー名と値を渡すことで、データ保存できました。

    function saveSessionItems() {
        sessionStorage.setItem("text", $("#sessionText").val());
        sessionStorage.setItem("textarea", $("#sessionTextarea").val());
        console.log("Saved session items.");
    }
    function saveLocalItems() {
        localStorage.setItem("text", $("#localText").val());
        localStorage.setItem("textarea", $("#localTextarea").val());
        console.log("Saved local items.");
    }
    $("#sessionSave").click(function(){ saveSessionItems() });
    $("#localLoad").click(function(){ loadLocalItems() });

プログラム(データ読み込み)

画面上の「再表示」ボタンをクリックした時、または初期表示時に動作する処理です。sessionStorage, localStorageのgetItemメソッドを使って、キー名を渡すことで、データ取得できました。

    function loadSessionItems() {
        $("#sessionText").val(sessionStorage.getItem("text"));
        $("#sessionTextarea").val(sessionStorage.getItem("textarea"));
        console.log(window.sessionStorage);
        console.log("Loaded session items.");
    }
    function loadLocalItems() {
        $("#localText").val(localStorage.getItem("text"));
        $("#localTextarea").val(localStorage.getItem("textarea"));
        console.log(window.localStorage);
        console.log("Loaded local items.");
    }
    $("#sessionLoad").click(function(){ loadSessionItems() });
    $("#localLoad").click(function(){ loadLocalItems() });

プログラム(データ1件削除)

画面上の「削除」ボタンをクリックした時に動作する処理です。sessionStorage, localStorageのremoveItemメソッドを使って、キー名を渡すことで、データ削除できました。データ削除後は、入力項目を再表示しています。

    function removeSessionText() {
        sessionStorage.removeItem("text");
        loadSessionItems();
    }
    function removeSessionTextarea() {
        sessionStorage.removeItem("textarea");
        loadSessionItems();
    }
    function removeLocalText() {
        localStorage.removeItem("text");
        loadLocalItems();
    }
    function removeLocalTextarea() {
        localStorage.removeItem("textarea");
        loadLocalItems();
    }
    $("#sessionTextDelete").click(function(){ removeSessionText(); });
    $("#sessionTextareaDelete").click(function(){ removeSessionTextarea(); });
    $("#localTextDelete").click(function(){ removeLocalText(); });
    $("#localTextareaDelete").click(function(){ removeLocalTextarea(); });

プログラム(データ全件削除)

画面上の「クリア」ボタンをクリックした時に動作する処理です。sessionStorage, localStorageのclearメソッドを呼ぶことで、sessionStorageまたはlocalStorageの全データ削除できました。データ削除後は、入力項目を再表示しています。

    function clearSession() {
        sessionStorage.clear();
        loadSessionItems();
    }
    function clearLocal() {
        localStorage.clear();
        loadLocalItems();
    }
    $("#sessionClear").click(function(){ clearSession() });
    $("#localClear").click(function(){ clearLocal() });

補足

Web Storageのデータは、オリジンと呼ばれる単位で保存されるのですね。オリジンとは、プロトコル、ドメイン、ポートの組み合わせのことをいいます。

今回作成したプログラムは、jsdo.it上で作成しました。次のリンクから、参照可能です。興味が湧いた方は、Forkして、色々動かしてみて下さい。

動作環境

対象ブラウザ

  • IE 8 以降
  • Firefox 3.6 以降
  • Chrome 8 以降
  • Safari 5 以降
  • ※動作確認したブラウザは以下のみです。

動作確認済みブラウザ

利用ライブラリ

  • jQuery 1.8.0
  • Bootstrap 2.1.0

HTML5のFile API:Writerで、動的データのダウンロードを実装してみた。

前回の記事では、HTML5のBlobを使用して、動的データのダウンロードを行いました。非常に簡単に実装できたのですが、ひとつ残念だったのは、ファイル名を指摘できないことでした。

今回、HTML5のFile API:Writerを使って、ファイル名を指定して、動的データのダウンロードを行なってみました。難しいことなく、出来上がったのですが、現状では、対応ブラウザがGoogle Chromeだけとなってしまいました。File API:Writerは、各種ブラウザの実装が普及していないようですね。

では、作成してみたサンプルプログラムを説明します。

画面イメージ

作成したプログラムをブラウザで表示した画面イメージです。ダウンロード時のファイル名と、ファイルの内容を指定するテキストボックスがあります。ダウンロードリンクから、ローカル環境にダウンロードする事ができます。

プログラム

HTMLです。

<input id="fname" type="text" value="sample.txt" /><br>
<textarea id="content" cols="40" rows="5">Hello, World!
こんにちは、みなさん!</textarea><br>
<a id="download" target="_blank">ダウンロード</a>

ユーザ入力のファイル名とファイル内容から、ファイルを作成し、ダウンロードリンクに紐付けるJavaScriptです。jQuery 1.8.0を使っています。

ブラウザが管理する仮想的なファイルシステムに対して、ファイル名を指定してファイルを作成しています。そのファイルに対するURLを取得すると、URLのファイル名部分が指定したファイル名になり、その名前でダウンロード出来るようになりました。

    function setFileUrl(id, fname, content) {
        window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
        window.requestFileSystem(TEMPORARY, 1024*1024, function(fileSystem){
            // ファイル新規作成(上書き)
            fileSystem.root.getFile(fname, {create: true, exclusive: false}, function(fileEntry){
                // ファイル書き込み
                fileEntry.createWriter(function(fileWriter){
                    var blob = new Blob([ content ], { "type" : "text/plain" });
                    fileWriter.write(blob);
                    // ファイル書き込み成功イベント
                    fileWriter.onwriteend = function(e){
                        console.log("ファイル書き込み成功");
                    };
                    // ファイル書き込み失敗イベント
                    fileWriter.onerror = function(e){
                        console.log("ファイル書き込み失敗");
                    };
                });
                
                // リンクへ紐付ける
                $("#" + id).attr("href", fileEntry.toURL());
            }, function(error){
                console.log("error.code=" + error.code);
            });
        });
    }

上記JavaScript処理と、HTMLを関連付ける処理です。

    function setSampleFileUrl() {
        setFileUrl("download", $("#fname").val(), $("#content").val());
    }
    
    $("#fname").keyup(function(){
        setSampleFileUrl();
    });
    $("#content").keyup(function(){
        setSampleFileUrl();
    });
    
    setSampleFileUrl();

今回作成したプログラムは、jsdo.it上で作成しました。次のリンクから、参照可能です。興味が湧いた方は、Forkして、色々動かしてみて下さい。

動作環境

対象ブラウザ

  • Chrome 20.0以降
  • ※動作確認したブラウザは以下のみです。

動作確認済みブラウザ

動作しないことを確認したブラウザ

利用ライブラリ

Denchin 0.2.6 公開

本日、バージョン0.2.6を公開しました。約半年ぶりのバージョンアップですね。そんな久しぶりのバージョンアップですが、何も華々しいことはありません。

今回の変更は、Google Playでコメント頂いていた、いくつかの不具合の修正です。

変更内容

1.メイン画面のオプションメニューから履歴クリア選択時に、エラー発生し、履歴を消せなかった問題を修正。
2.メイン画面における前回充電の充電量が100%にならない端末がある問題を修正。
3.ウィジェットの右と下の余白が、多少広かったのを微調整。
4.DB処理を見直し。

その他

Google Playのコメントにて、端末再起動時に、Denchinが自動起動しない問題が報告されています。私の手持ち端末では、現象が再現しないため、原因が特定出来ていません。

ネットの情報では、Android OS 4.0 (ICS)では、マニフェストファイルの設定(targetSdkVersion)が未設定だと、自動起動の権限が認識されないことがあるようです。DenchinでもtargetSdkVersionを設定していなかったので、今回のリリースでは、設定を行なってみました。

もし、原因を特定できるような情報をお持ちの方がいましたら、情報提供をお願いします。当ブログやGoogle Playへのコメントでも構いませんし、Google Playに公開してあるメールアドレスでも構いません。

動作確認環境