KWEYT
@KWEYT

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Kotlin】AndroidスマホからWindows共有フォルダのアクセス時に異常終了

解決したいこと

【Kotlin】AndroidスマホからWindows共有フォルダのアクセスし、ディレクトリの存在チェック、ファイルの取得を実装したいと考えています。
いくつかのサイトを参考にしましたが、何度試してもSmbFile.IsDirectoryで異常終了してしまいます。Windows共有フォルダには別PCからはアクセスでき、フォルダも共有されていることは確認できています。原因が分からず、ご教授いただけないでしょうか。

発生している問題

SmbFile.isDirectoryのところでエラーになります。
try chacthでe.messageを確認すると nullとなっています。

参考サイト

https://teratail.com/questions/339608
https://rasumus.hatenablog.com/entry/2021/08/14/095050

(ソース)
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" />

build.gradle

implementation files('libs/jcifs-ng-2.1.6.jar')
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32'
implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.32'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1'
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15to18', version: '1.69'

MainActivity.kt

import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.app.R
import jcifs.config.PropertyConfiguration
import jcifs.context.BaseContext
import jcifs.smb.NtlmPasswordAuthenticator
import jcifs.smb.SmbFile
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Properties
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.*


class MainActivity: AppCompatActivity(), CoroutineScope{
    // coroutine準備
    val TAG: String = "MySMB"

    // coroutine準備
    private val job = Job()
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    // 終了時のcoroutineのキャンセル設定
    override fun onDestroy() {
        job.cancel()
        super.onDestroy()
    }

    var ip: String = "192.168.11.30"
    var userName: String = "Administrator"
    var password: String = "Password"
    val smbroot = "smb://" + ip + "/news/99999/"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)

        GlobalScope.launch (Dispatchers.Main) {
            connectSMB(userName, password, ip, smbroot)
            delay(1000L)
        }
    }


    // SMBサーバーに接続する関数
    suspend fun connectSMB(user: String, password: String, domain: String, smbroot: String): SmbFile {
        val tv:TextView = findViewById(R.id.tv_serverData)
        lateinit var smb: SmbFile

        coroutineScope {
            smb = async(Dispatchers.IO) {
                val prop = Properties()
                prop.setProperty("jcifs.smb.client.minVersion", "SMB202")
                prop.setProperty("jcifs.smb.client.maxVersion", "SMB300")
                val baseCxt = BaseContext(PropertyConfiguration(prop))
                val auth = baseCxt.withCredentials(NtlmPasswordAuthenticator(domain, user, password))
                SmbFile(smbroot, auth)
            }.await()

            tv.text = smb.path
            delay(1000L)


            try {
                if (smb.isDirectory()){  ←ここでエラー
                    tv.text = "ディレクトリです"
                    delay(1000L)
                }else{
                    if (smb.exists()){
                        tv.text = "ファイルです"
                        delay(1000L)
                    }else{
                        tv.text = "存在しません"
                        delay(1000L)
                    }
                }
            } catch (e: Exception) {
                tv.text = "error: " + e.message.toString()
            }

        }
        return smb
    }
}
0

1Answer

情報が少なすぎるけどパーミッションの設定が足りていないとか?
あとスマホ側になんらかのアプリを入れて接続出来ることは確認済みですよね?Windowsで確認されても解決にはならないです

1Like

Comments

  1. @KWEYT

    Questioner

    回答ありがとうございます。
    情報不足ですみません。
    >あとスマホ側になんらかのアプリを入れて接続出来ることは確認済みですよね?
    別のスマホアプリでからPCへ接続できることは確認済みです。

  2. 参考サイトへのリンク貼ったと思いますがそれは動作しますか?

    Kotlinで落ちる原因としては
    マニフェストの設定が足りていないまたはアクセス権限系
    メインスレッドで呼び出してはいけない命令
    と思いますのでマニフェストファイルを見直しましょう

    SMBとしてはWindows側が 2.0か3.0で動いていると思いますので
    バージョン違いによるエラーではないと思います

  3. @KWEYT

    Questioner

    ご連絡有難うございます。
    先程試してみましたが、参考サイトですと問題ありませんでした。
    マニフェストについても問題なさそうです。
    >>メインスレッドで呼び出してはいけない命令
    おそらく非同期のあたりが原因かと思っています。
    ソースがこちらにアップしたものよりも、他処理もありごちゃごちゃしていますので再度見直してみたいと思います。有難うございました。

Your answer might help someone💌