Windowsの共有フォルダをAndroid端末から参照する方法
Android端末からWindowsの共有フォルダを参照する方法を調べたので、実装方法をメモ。
JCIFSのダウンロード
どうやらJCIFSというライブラリを使えば、AndroidからWindowsの共有フォルダを参照できる様子。
Windowsのファイル共有サービスで利用されているSMBを拡張し、Windows以外のOSやアプリで
利用できるようにしたものがCIFSだそうな。
で、Javaから利用できるようにしたものがJCIFSだとかなんとか…。
それはさておき、JCIFSのライブラリを以下からダウンロードします。
https://jcifs.samba.org/
jcifs-1.3.18.zipをダウンロードしたら展開し、jcifs-1.3.18.jarをAndroidのlibフォルダに配置します。
パーミッションの変更
AndroidManifest.xmlにパーミッションの設定を追加します。
追加する内容は以下の通り。
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ADD_SYSTEM_SERVICE"/>
実装
以下、実装のサンプル。
ボタンを押したら共有フォルダにアクセスして、そこにあるファイルの数を取得するだけのプログラムです。
public class MainActivity extends AppCompatActivity { private AccessTask task; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView txtView = (TextView)findViewById(R.id.textView); task = new AccessTask(txtView); Button accessbtn = (Button)findViewById(R.id.button); accessbtn.setOnClickListener(AccessListener); } private View.OnClickListener AccessListener = new View.OnClickListener() { public void onClick(View v) { task.execute(1); } }; }
以下のプログラム内のhost、user、pswd、共有フォルダ名("/share/"の箇所)は適宜読み替えてください。
import jcifs.smb.SmbFile; public class AccessTask extends AsyncTask<Integer, Integer, String> { private TextView textView; public AccessTask(TextView txtView) { super(); textView = txtView; } @Override protected String doInBackground(Integer... value) { SmbFile dir; String host = "host-name"; String user = "user"; String pswd = "password"; String str; try { String path = "smb://" + user + ":" + pswd + "@" + host + "/share/"; dir = new SmbFile(path); SmbFile[] files = dir.listFiles(); str = Integer.toString(files.length) + "個のファイルがあります。"; } catch(Exception e) { Log.e("Err", e.toString()); } return str; } @Override protected void onPostExecute(String param) { textView.setText(param); } }
ここで重要なのが以下の2点。
①パスの最後はスラッシュ"/"を付けること
②共有フォルダにアクセスする処理はメインスレッドではなく、別スレッドで行うこと。
②についてですが、Android3.0以降でこのような動作になったらしく、
メインスレッドでアクセスしようものなら、もれなくNetworkOnMainThreadExceptionが付いてきます。
最初コレに気づかずに3時間くらい悩んだよ…。