2014年11月8日土曜日

[Java SE 7] Java SE 7新機能: Project Coin

Java SE 7 の新機能は次の4つが目玉:
  • Project Coin: 言語仕様に関する小さな変更群
  • NIO.2: NIOの改良
  • Fork/Join Framework: 並列処理の実装を容易にするらしい
  • InvokeDynamic: 動的型付けでメソッド呼び出しをできるらしい
この内、Project Coinについて。

switch構文のスイッチにStringが使えるようになった

その他使えるのは(おおよそ)、整数型もろもろと列挙型。

数値リテラルに2進数表現が追加された

0b01110010

可読性向上のため、数値リテラルに_が挿入できるようになった

1234_5678
処理前にreplace("_","")される

例外のマルチキャッチ

これ知ってた。
catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

例外の再スロー

再スローする例外を細かく指定できるようになった。
  static class FirstException extends Exception { }
  static class SecondException extends Exception { }
  public void rethrowException(String exceptionName) throws Exception -> FirstException, SecondException 
{
    try {
      if (exceptionName.equals("First")) {
        throw new FirstException();
      } else {
        throw new SecondException();
      }
    } catch (Exception e) {
      throw e;
    }
  }
catchしているのがExceptionになるため、Java SE 6まではthrows節にはExceptionwしか書けなかったんだそうな。

ダイヤモンド演算子

これも知ってた。例は略。

try-with-resources文

リソースのクローズを自動的にやってくれる。
try (
      java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
      java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)

    ) {
      // Enumerate each entry
      for (java.util.Enumeration entries = zf.entries(); entries.hasMoreElements();) {
        // Get the entry name and write it to the output file
        String newLine = System.getProperty("line.separator");
        String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine;
        writer.write(zipEntryName, 0, zipEntryName.length());
      }
    }
tryの()の中(=try-with-resources)で、java.lang.AutoCloseable インタフェースを実装しているオブジェクトの初期化をすると、自動的にclose()が呼ばれる。
クローズ処理は、catch, finallyブロックより先に呼ばれて、作成時と逆の順番で呼ばれる。

try-with-resources文のブロックでもtryブロックでも例外がスローされた場合、tryブロックの中の例外の方が優先されて、try-with-resources文の方の例外は抑制された例外というのになる。
(これによりどういうスニペットができるんだろう?)
詳しい動作についてはいつもの:
ひしだま's 技術メモページ: Javaステートメント リソース付きtry文
http://www.ne.jp/asahi/hishidama/home/tech/java/statement.html#try_with_resources_statement

記法、公募したんですね!pull request募集みたいな感じ?
あとJSRが何か分かってないです。仕様?RFC的な。

参考:

 slideshare: New Feature of Java SE 7 -Java SE 7で切り開く新しいJavaの世界について
(寺田佳央さん)
http://www.ne.jp/asahi/hishidama/home/tech/java/uptodate.html#JDK1.7

ORACLE: 複数の例外型のキャッチと型チェックが改善された例外再スロー
http://docs.oracle.com/javase/jp/7/technotes/guides/language/catch-multiple.html

ORACLE: try-with-resources 文
http://docs.oracle.com/javase/jp/7/technotes/guides/language/try-with-resources.html

ITPro: Java SE 7の新機能を読み解く (桜庭祐一さん)
http://itpro.nikkeibp.co.jp/article/COLUMN/20120417/391316/

2014年1月28日火曜日

[Play Framework] [JPA] Play Framework1.2.xでJPAを利用してUPDATE処理を行う

JPAでは、Play Frameworkのモデルで行われているO/Rマッピングとは異なり、永続コンテキスト中のエンティティの状態はDBと自動的に同期される

JPAを使ったデータアクセスでポイントとなる永続コンテキストについて

管理されていない状態のオブジェクトを主導で更新することもできるし、JPQLを記述して、より柔軟な更新処理を発行することもできる


  • 管理された状態のオブジェクトの更新
  • 管理されていないオブジェクトの更新
  • JPQLを用いたUPDATE

Book: JPA CRUD Update

今回は、更新時のWHERE句指定を行いたいので、JPQLでクエリを記述する方法を取ることにする

JPAおよびJPQLの書き方について、公式のチュートリアル

英語だけど、JPQLの書き方だけならさほど読むのに時間はかからない。
Java EE6 Tutorial - Chapter 32 Introduction to the Java Persistence API (英語)
Java EE6 Tutorial - Chapter 34 The Java Persistence Query Language (英語)

Play Frameworkの中でJPA APIを使うには


  • JPA エンティティマネージャの取得
  • トランザクション管理

play Japan - Documentation - JPA 永続化

クエリ発行の主役になるのはjavax.persistence.Queryインタフェース

javax.persistence.Query

NamedQueryの定義方法

@Entityアノテーションとクラス定義の間で定義する
JPA注釈の参照情報

QuerySyntaxException: (object) is not mapped という例外でコンパイルできないけどどう見てもクエリ文には、問題がなさそうで困った場合、エンティティクラスを完全修飾クラス名で指定したらうまく行きました
Unable to query database - QuerySyntaxException: (object) is not mapped

2012年12月11日火曜日

BacklogのGitレポジトリへの接続設定

BacklogのGitレポジトリを使えるようにする過程で少しハマったのでメモ。

つまづいたのはSSHでの接続。
Backlogに登録する公開鍵と、手元に置いておく秘密鍵のキーペアを生成
Backlogに公開鍵を登録
git cloneしてみる
Permission Denied (publickey)
と言われてアクセスできない。

まず、gitじゃなくて普通にssh接続してみた。
同じメッセージが返ってくる。
ここで、公開鍵は正しく設定できているはずなので、秘密鍵をきちんとsshが参照できていないんじゃないかと推測。
ので、sshのオプションで秘密鍵ファイルとユーザ名を指定して接続した所、次のエラーが返ってきた。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '[鍵ファイル]' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: [鍵ファイル]
Permission denied (publickey).

パーミッションが原因だった。鍵ファイルを600に変更してもう一度ssh接続したら、上手くいった。

Identity added: [鍵ファイル] ([鍵ファイル])
Hi [Backlogユーザ名]! You've successfully authenticated, but Backlog does not provide shell access.
Connection to [Backlogスペース].git.backlog.jp closed.

sshにもIdentityが追加されたようなので、このままgit clone.
こちらも大丈夫だった。


今回、GitHubとキーペア分けたかったので、.ssh/configも今回作った。
接続できない原因がこちらなのか分からなかったので、時間かかってしまった。
参考:http://d.hatena.ne.jp/dkfj/20120401/1333245048




2012年1月26日木曜日

[Java][Derby] Derbyに急にAcccessControlExceptionで接続できなくなったとき

急にDerbyに接続できなくなって、コンソールには次のようなエラーメッセージが出ているとき。特に、複数のプロジェクトをビルドパスに含む構成にしているとき。
java.security.AccessControlException: access denied (java.util.PropertyPermission user.dir read)
とりあえず、依存先のプロジェクトを一旦ビルドパスから外し、再度加えてみる。
プロジェクトのクリーンもする。

参考:http://old.nabble.com/Re%3A-java.security.AccessControlException%3A-access-denied-%28java.io.FilePermission-derby.log-read%29-p19211798.html


セキュリティポリシーの変更をした場合などは、多分そちらが原因。
参考:
http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/security/overview/jsoverview.html
http://db.apache.org/derby/docs/10.7/devguide/cdevcbabejdfj.html

2011年10月31日月曜日

[Java][Maven] 今さらかもだけどMaven入門してみた(5) - パッケージング

今回は、次のような構成にしてみた。
-bin/
  -App.bat: 起動用のバッチファイル
-config/
  -各種設定ファイル
-lib/
  -作成したJar
  -依存しているJar
実際には大体こちらの通り。
http://d.hatena.ne.jp/cnaos/20100102/1262430319
Jarの作成にはmaven-jar-pluginを、bin, config, libの各ディレクトリの作成とリソースのコピー、batファイルの作成にcodehausのappassembler-maven-pluginを使った。
手順は次の通り。

  1. appassemblerなどのリファレンスを見ながら、pom.xmlを書く。
  2. Run As > Maven buildでビルドする(このとき、goalにはpackageを指定する)
  3. 成果物をみて、期待と違えば再度設定する
最終的にできたpom.xmlは以下の通り。
<build>
        <!-- src/main/configはデフォルトではリソースとして登録されていないので、手動で追加
            (src/main/resourcesはデフォルトで登録されている) -->
        <resources>
            <resource>
                <directory>${basedir}/src/main/config</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>jp.example.App</mainClass>
                            <packageName>jp.example</packageName>
                        </manifest>
                    </archive>
                    <!-- 設定ファイルをJarから除外 -->
                    <excludes>
                        <exclude>*.properties</exclude>
                        <exclude>*.xml</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>appassembler-maven-plugin</artifactId>
                <version>1.1.1</version>
                <configuration>
                    <programs>
                        <program>
                            <mainClass>jp.example.App</mainClass>
                            <name>App</name>
                        </program>
                    </programs>
                    <!-- repository作成 -->
                    <repositoryLayout>flat</repositoryLayout>
                    <repositoryName>lib</repositoryName>
                    <!-- 設定ファイル -->
                    <configurationDirectory>config</configurationDirectory>
                    <copyConfigurationDirectory>true</copyConfigurationDirectory>
                    <configurationDirectory>config</configurationDirectory>
                    <!-- コンソールを出すか -->
                    <showConsoleWindow>true</showConsoleWindow>
                </configuration>
                <!-- packageフェーズで実行されるようにする -->
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>assemble</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

[Java][Maven] 今さらかもだけどMaven入門してみた(4) - ユニットテスト

テストコードの作成
ユニットテストにはJUnitが利用されているので、テストコードの作成については、JUnitのリファレンスを参照する。

テストの実行
Run As > Maven test
で実行する。
そうすると、次のような出力が出る。

[INFO] Scanning for projects...
[INFO]                                                                      
[INFO] ------------------------------------------------------------------------
[INFO] Building M2ETest 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ M2ETest ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Trials/M2ETest/M2ETest/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ M2ETest ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ M2ETest ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Trials/M2ETest/M2ETest/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ M2ETest ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.7.1:test (default-test) @ M2ETest ---
[INFO] Surefire report directory: /Trials/M2ETest/M2ETest/target/surefire-reports
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running jp.test.m2e.foo.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.563s
[INFO] Finished at: Mon Oct 31 16:26:59 JST 2011
[INFO] Final Memory: 7M/81M
[INFO] ------------------------------------------------------------------------
加えて、target/surefire-reportsのなかに、テストクラスごとにレポートができる。こんな感じ。
-------------------------------------------------------------------------------
Test set: jp.test.m2e.foo.AppTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 sec



HTMLで結果を一覧して確認
でも、これだと全体を一度に見られないから不便…と検索したら、レポーティングの一部としてテストを実行することもできるらしい。(ていうかJUnitって結果どうやって見てるの?)
これだと全てのテストの結果をHTMLにまとめて見られる。他の人への状況のシェアも(必要なときは)できるし、とりあえずこれを覚えておけばいい気がする。


1) pom.xmlに次の通り記述
<reporting>
    <plugins>
...
        <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-report-plugin</artifactId>
        </plugin>
...
    </plugins>
</reporting>
2) プロジェクトディレクトリで次のコマンドを実行する。
mvn site(プロジェクトサイト作成コマンド。この場合、CSSや画像をダウンロードために実行)
mvn surefire-report:report
以上。良い感じのができてちょっと嬉しい。

[Java][Maven] 今さらかもだけどMaven入門してみた(3) - dependency追加、実行

dependency追加
試しにlog4j追加してみる。以降はEclipse上で作業。
手順は次の通り。
Maven > Add dependency > ライブラリ名入れて検索、選択 > scopeを設定

  • Scope:ビルドプロセスの中のいつ、そのDependencyを使うか。例えば、Log4jだったら、Scopeはtest. これを設定することで、必要ない時にそのdependencyを含めなくてよくなる。
ここでつまづいた。。詳細はこちら

コードを書いて実行
Mavenコマンドで実行してもいいけど、普通にEclipseで実行でいいような気がします。

[Java][Maven] 今さらかもだけどMaven入門してみた(2) - プロジェクト作成、キーワード

■プロジェクト作成

Mavenを実行したい時は(Mavenに限ったことじゃないけど)、mvnコマンドを打ってもいいし、Eclipseプラグインでやってもいい。

1) コマンドで作成→eclipseにインポート
次のコマンドを打つ。
mvn archetype:generate
あとは、聞かれた通りに、

  • 元にするarchetype(プロジェクトのひな形)
  • groupId(パッケージ名)
  • artifactId(プロジェクト名)
を入力する。Eclipseへのインポートは次の通り。
Project Explorerで右クリック、Import > Maven > Existing Maven Project
(このとき.classpathにmavenのプロジェクト構成で決まっているソースパスやコンパイル出力先などが書かれる。)
これで、Eclipse上で作業できるようになる。

2) Eclipseプラグイン(m2e)で作成
Project Explorerで右クリック、New > Project > Maven > Maven Project
で作成。成果物を複数のプロジェクトで構成したい場合は、Maven Projectの代わりにMaven Moduleを選べば、プロジェクト内でのモジュールとなるプロジェクトを作成できる。
ダイアログの途中で選択する項目は次の通り。
  • Archetype
    • webapp向け、scala向け、jetty向け、などなどあるので、自分が作ろうとしているものがないか探す。
    • まずArchetypeカタログを選び、そのカタログに載っている好きなarchetypeを選択する。カタログはとりあえずAll Catalogを選択しておけばいいと思う。ちなみに各カタログについては次の通り。
  • GroupId:パッケージ名
  • ArtifactId:プロジェクト名

■Mavenの概念
ここから先は、とりあえず以下の項目について簡単に理解しておくとスムーズになると思う。

ビルドフェーズ
Mavenでは開発中にどういうフェーズがあるのか、が明確に定義されている。Mavenを実行するときは、フェーズ単位で実行する。
Mavenプラグイン
Mavenの機能は、様々なプラグインの形で提供されている。なので、Mavenを設定する、というのは、実質的には自分のやりたいことに対応するプラグインを選んで、設定して、という作業の繰り返しになる。
  • Ref: Available Plugins: http://maven.apache.org/plugins/index.html

Dependency
=依存するライブラリ、と思っているのだけど、ライブラリ以外にもdependencyになるものってあるのかな?

pom.xml
Mavenプロジェクトの設定ファイル。ここに、使いたいdependencyやプラグイン、プラグインの設定を書いていく。デフォルトのものを継承する形になるので、自分がカスタマイズしたい所だけ書けばいい。デフォルトのPOMはEclipseだとpom.xmlを開くとEffective POMタブで確認できる。

ゴール
プラグインの持つ機能みたいなイメージ。maven archetype:generate, ってするときのgenerateがゴール。pom.xmlで、プラグインに対してどのフェーズで、どのゴールを実行するのかを設定する。

2011年10月28日金曜日

[Java][Maven] 今さらかもだけどMaven入門してみた(1) - メリット、環境構築


今回は、最初にデバイス制御側を作っておいて、少し間があってからデータ取得側を作る、ってスケジュールで細かいこと忘れそう+ユニットテストとか再ビルドとか繰り返す必要がありそう、ということでやってみようかなと。
そういう目的からテスト管理ツール>CIツール(Jenkins)>Maven、って調べて行ってたどり着いた。


■Mavenを使うと嬉しいとき

1. 開発プロセスでの細々とした作業(プロジェクト作成、ライブラリの配置、テストツールの設定、テストレポートの作成など)に時間をかけたくないとき。
大概のステップは、何も準備をしていなくても、
mvn (フェーズ名)
ってすれば、とりあえず何かしらの成果物ができる。そこから、自分のやりたいことに合わせて設定ファイルを作ればいい。

2. ビルド作業を自動化したいとき。
ビルドツールの役割そのままだけど。
何人かビルドする人がいる、開発期間に間が空く、という時、一度設定すれば2度目以降は全く同じようにできる。

3. プロジェクトのディレクトリ構成を考えるのに時間をかけたくないとき。
プロジェクトのディレクトリ構成を考えなくていいし、他のプロジェクトを読むのも簡単になる。それに、Jetty, GAE, Scalaなど、メジャーなターゲットなら大抵プロジェクト構成が提供されているから、スタートしやすくなる。

4. 社内や、個人でもいいけど、自前で作ったライブラリを共有する複数のプロジェクトがあって、そのライブラリが更新されたりするとき。
Mavenローカルレポジトリを作れば、全員がそこに置かれているライブラリの最新版を使うことになるので、プロジェクトごとに違うバージョンのライブラリを使ってて何がなにやら、という状況にならなくて済む。
一番お世話になる機会はなさそうだけど、実現したら一番強力な機能かもしれない。


■環境構築

今回は、自前リモートリポジトリ作成はなし(リポジトリへの配備もなし)、プロキシ設定もなしです。

MavenはもともとSnow Leopardにインストールされているし、EclipseプラグインもEclipse Indigoにm2eが同梱されていた。Mavenのバージョンは最新だった(Maven 3.0.3)ので、環境構築作業はとりあえず何もせずにスタート。


■エントリー時の注意点
Maven 1.xとMaven 2.x/3.xは互換性が無いので、情報収集するときにはMaven 1.xのものでないかどうか注意!
コマンドがmavenだったり、プロジェクト設定ファイルがproject.xmlだったりしたらMaven 1.x(Maven 2.x/3.xではそれぞれmvn, pom.xml)。

2011年10月18日火曜日

[Java][Maven] log4jをdependencyに追加しようとしたらMissing artifactエラーになった

まずはmvnコマンドでプロジェクト作成、Eclipseにインポートしたまではよかったのだけど、試しに、とlog4jをAdd dependencyダイアログからPOMに追加したら、
Missing artifact log4j:log4j:bundle:1.2.16 
と言われた。ちなみにそこのdependencyタグはこんな感じ。
<dependency> 
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.16</version> 
   <scope>compile</scope>
   <type>bundle</type>
 </dependency>
けっこう探した結果、全く同じ問題が解決していた人がいたので、同様に解決。
http://maven.40175.n5.nabble.com/log4j-log4j-bundle-1-2-16-Bundle-or-JAR-td3281135.html

typeタグ(依存関係の種別を書いておく)をbundleでなくてjarにした。
bundleで探せてないってことは、どこかのパスが通ってないのが原因のような気がするけど、それがどれか(まだ)分からないから、とりあえずJarでもいいや。。

2011年9月16日金曜日

Android Monkey ツールを試してみた


MonkeyツールはランダムなUIイベントを発生させて、アプリケーションのストレステストとかを行えるツール。

とりあえず以下を参考にコマンド打ってみた。

http://www.taosoftware.co.jp/blog/2009/04/android_monkey.html
https://sites.google.com/site/androidtestclub/translation/dev-guide/developing/tools/09-developing-tools-monkey

$ adb shell monkey -p com.your.package --throttle 1000 -v 500

なぜかOperaがクラッシュしてすぐに止まった。。

:Monkey: seed=0 count=500
:AllowPackage: com.your.package
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.MONKEY
// Event percentages:
//   0: 15.0%
//   1: 10.0%
//   2: 15.0%
//   3: 25.0%
//   4: 15.0%
//   5: 2.0%
//   6: 2.0%
//   7: 1.0%
//   8: 15.0%
:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10000000;component=com.your.package/.MyActivity;end
    // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.your.package/.MyActivity } in package com.your.package
:Sending Pointer ACTION_MOVE x=-4.0 y=2.0
:Sending Pointer ACTION_UP x=0.0 y=0.0
// CRASH: com.opera.browser (pid 3808)
// Short Msg: java.lang.UnsatisfiedLinkError
// Long Msg: java.lang.UnsatisfiedLinkError: logD
// Build Label: samsung/SC-01C/SC-01C/SC-01C:2.2/FROYO/OMKB1:user/release-keys
// Build Changelist: OMKB1
// Build Time: 1297069177000
// java.lang.UnsatisfiedLinkError: logD
// at com.opera.common.CommonNatives.logD(Native Method)
// at com.opera.common.Log.d(Unknown Source)
(中略)
//
** Monkey aborted due to error.
Events injected: 23
:Dropped: keys=0 pointers=0 trackballs=0 flips=0
## Network stats: elapsed time=7480ms (0ms mobile, 7480ms wifi, 0ms not connected)
** System appears to have crashed at event 23 of 500 using seed 0

が、その後は快調!
イベント回数5000、スロットル(イベント発生間隔)1000ミリ秒で実行した所、
20分以上アプリを動かしつづけてくれました。

$ adb shell monkey -p com.your.package --throttle 1000 -v 5000
:Monkey: seed=0 count=5000
:AllowPackage: com.your.package
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.MONKEY
// Event percentages:
//   0: 15.0%
//   1: 10.0%
//   2: 15.0%
//   3: 25.0%
//   4: 15.0%
//   5: 2.0%
//   6: 2.0%
//   7: 1.0%
//   8: 15.0%
(中略)
Events injected: 5000
:Dropped: keys=2 pointers=2 trackballs=0 flips=0
## Network stats: elapsed time=1274086ms (0ms mobile, 1274086ms wifi, 0ms not connected)
// Monkey finished

2011年6月14日火曜日

[Android] SDカードへのパスの取得方法

SDカードには外部SDカードと内部SDカードがある機種がある。
Samsung端末などがそう。

こういった端末だと、Environment.getExternalStorageDirectory()して取得したSDカードへのパスは、内部パスになる。
それに対して、PCから直接見える場所が、外部パス。
Galaxy Tabの場合,内部パスが/mnt/sdcard、外部パスが/mnt/sdcard/external_sd。

外部パスは、adb shellで、
printenvコマンドで環境変数を出力すると、$EXTERNAL_STORAGEで設定されている。
$EXTERNAL_STORAGEの設定とファイルマネージャから確認できる外部パスは、下記の記事および手元の端末での確認ではすべて合致しているけれど、公式のドキュメントはないので、保証はない、という状態。
確認した端末は、次の3機種。

---
Galaxy Tab
内部SDカード:/mnt/sdcard/ (Environment.getExternalStorageDirectory)
外部SDカード:/mnt/sdcard/external_sd (ファイルマネージャ,adb shell)
環境変数EXTERNAL_STORAGE:/mnt/sdcard/external_sd

Camangi FM600
内部SDカード:/mnt/sdcard (Environment.getExternalStorageDirectory)
外部SDカード:/mnt/sdcard(ファイルマネージャ,adb shell)
環境変数EXTERNAL_STORAGE:/mnt/sdcard

VIA U07AV
内部SDカード:/sdcard (Environment.getExternalStorageDirectory)
外部SDカード:/sdcard(ファイルマネージャ,adb shell)
環境変数EXTERNAL_STORAGE:/sdcard
ちなみにmnt以下にはlocaldiskのみ
---

http://groups.google.com/group/android-group-japan/browse_thread/thread/53deac144d256b27/bdc76c63092ac990?hl=ja
http://blog.tappli.com/article/44620525.html
http://wlog.flatlib.jp/?itemid=1486

2011年6月2日木曜日

端末スリープ時に発生するConfigurationChange

端末スリープ時およびスリープからの復帰時に発生するConfigurationの変更は、orientationだけ。

スリープ時には、実際の端末の向きと関係なく、決まった方向にorientationが変更されるみたい。
この時のorientationの向きは、端末によって異なる。

手元の端末では、
Galaxy TabではORIENTATION_PORTRAIT - Constant Value: 1 (0x00000001)に、
Camangi FM600dではORIENTATION_LANDSCAPE - Constant Value: 2 (0x00000002)になった。

原則、AndroidManifestのactivityタグでscreenOrientationを設定していても、この設定変更は発生する。
(screenOrientationで設定した向きと端末のスリープ時の向きの設定が同じなら、向きが変わったことにならないので発生しない。)

2011年5月30日月曜日

Couldn't create directory for SharedPreferences

急にSharedPreferencesが読み書きできなくなって焦ったら、
何のことはない、AndroidManifestのsharedUserIdを変えたんだった。。。
ディレクトリ作ったのと違うユーザでアクセスしようとしてるんだから、できる訳ないよ。。

2011年4月25日月曜日

EditText長押し時に選択ダイアログを表示させないようにする

何もしないonLongClickメソッドを持つonLongClickListenerを作ってセットする。

EditTextフォーカス時にIMEが表示されないようにする

editable="false"にする。

このとき、digits属性があると有効にならないので注意。

2011年4月6日水曜日

ボタンの状態変化

ボタンの背景、文字、(あれば)アイコンそれぞれにStateListを用意する。

ボタンの種類×3のStateListを書くことになるので、作業量が多そう。
どうにかならないものか。

2011年4月5日火曜日

ListView選択状態カスタマイズ

ListViewでchecked状態のitemをラジオボタンやチェックボックスでなくセレクタのような形で表示するには。

本当は選択状態のキープは推奨されていない。様々な入力モードを持つデバイスをサポートするため。
http://www.techdoctranslator.com/resources/articles/articles-index/touch-mode
http://y-anz-m.blogspot.com/2010/08/androidthe-world-of-listview-item.html

そのため、choiceModeがある。ただ、choiceModeを指定するときは、行のレイアウトにデフォルトではandroid.R.layout.simple_list_item_single_choiceを使う。
これは、チェックボックスやラジオボタンのついたTextView。
sdk/platforms/android-x/data/res/layout/simple_list_single_choice.xml

なので、チェックボックス/ラジオボタンを非表示にする+上手く選択中表示をする、などの手で実現できる。
http://groups.google.com/group/android-sdk-japan/browse_thread/thread/d1b256728c759f01/4a6815f62d1f3616?hl=ja&lnk=gst&q=ListView%E3%81%AEonItemClick%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6#4a6815f62d1f3616

ここでは言及されていないけど、R.attr.state_checkedというstateもあるので、こちらが使えれば、セレクタで選択中表示の部分は実装できるかも。

ProgressDialogのカスタマイズ

Spinnerをデフォルトとは違う輪に画像にしたいなら:
animated-rotateタグのXMLDrawableと、好きな画像をdrawableに入れて、XMLDrawableをProgressDialog.setIndeterminateDrawableで指定する。

XMLDrawableは、
sdk/platforms/android-x/data/res/drawable/progress_medium.xml等を参考にする。
(framesCount, frameDuration 属性は削除する。)

Spinnerを輪ではない何かのアニメーションにしたいなら:
ProgressDialog.setIndeterminateDrawableで自作フレームアニメーションを指定する。
http://d.hatena.ne.jp/narazoro/20101106/1289060564