- JavaでSambaアクセスをキーワードに色々ググる
- JCIFSというライブラリを使う方法がスタンダードな感じ
外部jarの読み込みは、GradleのバージョンとかIDEの有無によって方法も異なるので、
ここではgradle build
で試してできた方法だけ書いておきます。
以下からjarファイルをダウンロードします。
jcifs - Download
以下をbuild.gradle
に設定します。
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile files('libs/jcifs-1.3.18.jar')
}
import jcifs.smb.*;
がビルド通るようになれば問題ありません。
以下をAndroidManifest.xml
に追加します。
<uses-permission android:name="android.permission.INTERNET"/>
各APIのドキュメントは以下にあります。
jcifs - API Document
Androidでメインスレッド上での
ネットワークアクセス処理を許可していません(NetworkOnMainThreadException)。
ですので、jcifsによるネットワークアクセス処理を
新しく定義したスレッド上で実行する必要があります。
Android上での非同期処理については細かく書きませんが、
Sambaサーバへアクセスして処理を行った後、
その結果を取得するためにThread.join()
を使う方法と、
Android.os.Handler
を使う方法を紹介します。
ここではThread.join()
を使って、Sambaサーバへの接続確認を行う機能を実装してみます。
Thread.join()
は処理を開始したスレッドが完了するまで待機する機能を持ちます。
別のスレッドとして処理を呼び出すクラスを書きます。
import java.lang.InterrupteException;
import java.io.IOException;
import jcifs.smb.SmbFile;
public class Samba
{
private int _isConnectionCode = -1;
/**
* 指定されたホストへのSamba接続を試行します。
* 接続に成功したらtrue、失敗したらfalseを返します。
*/
public boolean connect(
final String host)
{
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//thread.start()で処理される
try {
//smb://{host}の接続文字列を作る
SmbFile smb = new SmbFile("smb://" + host);
smb.connect();
_isConnectionCode = 0;
} catch (IOException e) {
//Process of error.
_isConnectionCode = 1;
}
}
});
thread.start();
try {
thread.join();
} catch (InterrupteException e) {
//Process of error.
_isConnectionCode = 1;
}
return _isConnectionCode != 0 ? false : true;
}
}
スレッドの定義と完了待ちのThread.join()
を実行する機能はできました。
あとはどこからでも呼び出すだけで、Sambaサーバへの接続確認ができます。
//必要なら上で作ったクラスをimport
import {package}.Samba;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity
extends Activity
{
@Override
public void onCreate(
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Samba samba = new Samba();
if (samba.connect("192.168.1.1")) {
System.out.println("Sambaサーバの接続に成功");
} else {
System.out.println("Sambaサーバの接続に失敗");
}
}
}
せっかくの非同期処理をわざわざ待つという方法ではありますが、
上記のような接続確認などを前処理として行いたい場合などに使えます。
ここではandroid.os.Handler
を使って、
Sambaサーバ上のファイルやディレクトリの存在確認を行う機能を実装してみます。
android.os.Handler
は、ある処理の完了を通知する為に使われます。
Sambaアクセスのように、非同期で行われるような処理の結果通知を受ける事ができます。
import android.os.Handler;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbException;
public class Samba
{
public void exists(
final Handler handler,
final String host,
final String target)
{
new Thread(new Runnable() {
@Override
public void run() {
//thread.start()で処理される
Message message = Message.obtain(handler);
try {
//smb://{host}/{target}
SmbFile smb = new SmbFile("smb://" + host + target);
message.what = 0;
message.obj = smb.exists();
} catch (SmbException e) {
//Process of error.
message.what = 1;
message.obj = e.getMessage();
} finally {
handler.sendMessage(message);
}
}
}).start();
}
}
スレッドの定義と完了、例外通知を実行する機能はできました。
呼び出し元では、非同期処理の完了通知を受ける為のハンドラの定義を行い、
処理を呼び出す事で、Sambaサーバ上のファイル・ディレクトリの存在確認ができます。
//必要なら上で作ったクラスをimport
import {package}.Samba;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class MainActivity
extends Activity
{
@Override
public void onCreate(
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case 0:
//ファイルが存在していればtrue
//ファイルが存在していなければfalse
System.out.println(message.obj);
break;
case 1:
//Process of error.
break;
}
}
};
Samba samba = new Samba();
samba.exists(handler, "192.168.1.1", "/share/exists.txt");
}
}
このように、Handlerを利用すると非同期で行われる 処理結果の通知を受け取ることが可能になります。
他にも、認証を使った接続やSambaサーバ上でのファイル操作はもちろん、
ローカルにあるファイルとのやり取り等、色々とできそうです。