Androidのアプリ開発関連のブログ

昨日の続きで非同期でSSH

昨日のSSHがうまく行かなかったのは、最後UIスレッドで通信しようとしてるからじゃないか?
ってことに気づいたんで、今ちょっと試した。

昨日はganymed-ssh-2の
conn.connect();
で例外が発生してる気配だったが、
AsyncTaskLoaderでやってみたら。この行は突破できたぽい。

だが、SSHはつなぎっぱでコマンド送るもんだから、
非同期処理したままUIスレッドに結果を送り続けなければいけない。
が、LoaderManager.LoaderCallbacksではonLoadFinishedで完了時のデータ受け取る以外に何も受け取れないのね・・・


前にお蔵入りしたアプリでAsyncTaskを使ったことがあるが、AsyncTaskには途中経過を受け取る機能があるようなんだが、
AsyncTaskだとActivityがonCreateされるとAsyncTaskも初期化されちゃうらしい。それはそれで困るな・・・

AsyncTaskLoader側から一時的に処理を止めてUIの操作とかはできそうだから、
次回はそっち方向でUIスレッドの変更をやってみたいと思う。

コード量は多くならなそうだが、めんどいな。

UIスレッドで接続しようとしてるからかもしれん・・・

jsch使ってSSHしようとしたらよくわからん例外出てダメだったが、ganymed-ssh-2の方も試してみた。


ganymed-ssh-2のビルド方法がわからなかったが、
android create lib-project
でライブラリ用のプロジェクトを作成して、srcにソースを全部コピー。

アプリのプロジェクト側で、project.propertiesに、
android.library.reference.1=../ganymed-ssh-2
って感じで作成したlib-projectへの相対パス書いたら使えたぽい。


で、ganymed-ssh-2の方で試してみたんだが、こっちも、
conn.connect();
でそれっぽいの出力されないが何か例外発生しちゃってる。

お手上げか・・・
と思ったんだが、これUIスレッドで通信しようとして例外発生してるのかもしれんことに気づいた。
時間かかっちゃったから明日非同期で試してみる。


今日はjschもganymed-ssh-2も全く動かなかったが、
jschの方はInputStreamとOutputStreamを設定して勝手に読み書きする感じぽいが、
ganymed-ssh-2の方はInputStreamを取得して、それがサーバーからのレスポンスみたい。
jschの方はOutputStreamがレスポンスと判断したんだが、それだとメモリで読み取ろうとすると排他処理が必要なはずで無理ぽい気が・・・
ganymed-ssh-2の方はInputStreamなんで、1行ずつ読み取りができるから排他処理が不要。
と思ったんだが、jschの方、InputStreamとOutputStream逆に判断してるような・・・
JavaのInputStreamとOutputStreamは単純なファイル読み書き以外で使うとどっちがどっちだかわからんわ。

ちょっと使った感じだと、ganymed-ssh-2の方がわかりやすいかなーって感じ。
まあ、続きは明日試す。
非同期で通信できないようならお手上げだな。

jschだめぽい・・・

AndroidでSSHするアプリ作ろうとしていてjschってライブラリ使おうと思ってたが、
session.connect();

E/ThrottleService( 1195): problem during onPollAlarm: java.lang.IllegalStateException: problem parsing
stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No su
ch file or directory)
こんな感じで例外出ちゃってるぽくてダメだわ・・・

なんかシステムファイルがない感じ?

JSchが良いかな・・・

JavaのSSHライブラリちょい調べて、
JSchってのとganymed-ssh-2ってのが候補かなあ・・・

って感じなんだが、使い方の書いてあるような両方共ドキュメントはなしで、サンプルコードだけがソースに同梱されてる。
ライセンスは共に3条項BSDライセンスってのな感じで、ライセンスの表示だけすればバイナリで同梱可能ぽい。

最初ganymed-ssh-2っての使おうかと思ったが、ライブラリのビルド方法がわかんない。
JSchってのはbuild.shが同梱されててantでビルドする感じになってるようなんだが、エラー出てビルドできなかった・・・
が、JSchの方はバイナリも配布されてる。
ってわけで、JSchのバイナリ使おうかなと。


当初の目的はSFTPなんだが、ライブラリの使い方知るのにまずターミナルアプリを作ろうかなと思ってちょっとやったんだが、
InputStreamとOutputStreamを設定して使う感じみたいで、サンプルコードだとInputStreamが標準入力でOutputStreamが標準出力になってる感じ。
てことは、InputStreamから入力してOutputStreamを読み取るのかな?
OutputStreamの読み取りを非同期でやらんといかんな。
ちとめんどいような・・・

ターミナルアプリの作成は中止してSFTPの実装からにするかもしれないが、
SSHアプリ配布してもいいし、両方作る感じかな・・・

SFTPの実装に外部ライブラリが必要そう

ブログエディターの次に、FTP経由でリモートの編集ができるテキストエディタ的なのを作ろうとしてるが、
今日の作業はエディタ画面用にEditTextを置いたくらい。

EditTextを置いたActivity作って、ファイル選択の仕様を考えて、
  • ググったら、ダイアログでファイル選択を実装してる例が多い?
  • ギャラリーで画像を取得するように他アプリ経由で取得できないか?
ダイアログでの実装だと、誤タッチでキャンセルされないようにしたほうが良さそう?
他アプリ経由の取得はギャラリーと同じようにできそうだが、root権限のアプリで読み書きできないファイルが渡される可能性あるかも?

とか考えてたが、
他アプリ経由だとrootの可能性があるが、自前でファイル選択用のアクティビティー作っちゃうと今後も流用できそうだし、
ファイル選択用のアクティビティーを作る方法が良さそう。


で、リストはListViewで作るが、
まずローカルファイルのファイル一覧を表示する処理作ろうとして、
File android.content.Context.getFilesDir()
でjava.io.Fileが取得できる。


アクティビティーのレスポンスはURIの様だし、後からネット上のファイルも選択できるようにするためには、FileじゃなくてURIの方が良いかな?
File.toURI()
で簡単にURIに変換できるぽい。


その辺りで気づいたんだが、後からネット上のファイルも選択できるようにしたいが、最低でもFTPは実装しようと思うが、
FTPって言っても今はSSH経由のSFTP使うことが多いよね。

FTPやらSFTP(SSH)を実装するのにAndroidのAPIを検索したが、
恐らく無い・・・


公開されてるAndroidのFTPクライアントアプリはどうやって実装してるんだろう・・・自力実装する人がそんなに多いと思わないが・・・
と思って調べたりしてたが、
JavaのSSHライブラリはいくつか存在するみたいだね。
完全にフリーで使えるのはないかもしれないが、一番有名の?はBSDライセンスだった。
BSDライセンスは、ライセンス表示さえすれば利用するアプリ自体はクローズドで良く、ライブラリもバイナリのみ同梱でいいみたい。
ライセンス表記すら要らないのがあればいいが、BSDライセンスのライブラリでも利用可能な感じなんで、ライブラリ使って実装しようかと。


考えてるだけで今日はほぼ終わり。
ファイル選択はまずローカルファイルの選択機能から実装するが、
SSHライブラリの使い方知るために、まずSSHクライアントを作る方が良いかもしれんな・・・