API Androida niestety nie dostarcza nam w standardzie żadnego mechanizmu umożliwiającego wybór pliku z systemu plików. W takim przypadku nie pozostaje nam nic innego jak zaimplementować to samemu lub skorzystać z gotowej biblioteki.
Postanowiłem bazować na file chooser’ze zaimplementowanym przez Rogera Keaysa. Jest on dostępny pod poniższym adresem: https://rogerkeays.com/simple-android-file-chooser.
Moja implementacja wygląda w następujący sposób:
class FileChooser(val activity: Activity, val fileListener: FileSelectedListener, val maxFileSize: Double) { private lazy val messageMaker = wire(classOf[MessageMaker]) private val parentDir = ".." private val mb = 1024.0 * 1024.0 private val dialog = new Dialog(activity) private val list = new ListView(activity) private var currentPath: File = _ list.setOnItemClickListener(new AdapterView.OnItemClickListener() { override def onItemClick(parent: AdapterView[_], view: View, position: Int, id: Long): Unit = { val fileChosen: String = list.getItemAtPosition(position).asInstanceOf[String] val chosenFile: File = getChosenFile(fileChosen) if (chosenFile.isDirectory) { refresh(chosenFile) } else { val sizeInMB: Double = chosenFile.length / mb if (sizeInMB > maxFileSize) { messageMaker.info("Selected file is too large") } else { if (fileListener != null) { fileListener.fileSelected(chosenFile) } dialog.dismiss() } } } }) dialog.setContentView(list) dialog.getWindow.setLayout(MATCH_PARENT, MATCH_PARENT) refresh(Environment.getExternalStorageDirectory) def showDialog() { dialog.show() } /** * Sort, filter and display the files for the given path. */ private def refresh(path: File) { this.currentPath = path if (path.exists) { val dirs: Array[File] = path.listFiles(new FileFilter() { def accept(file: File): Boolean = { file.isDirectory && file.canRead } }) val files: Array[File] = path.listFiles(new FileFilter() { def accept(file: File): Boolean = { !file.isDirectory && file.canRead } }) dirs.sortWith(_.getName > _.getName) files.sortWith(_.getName > _.getName) // convert to an array val i: Int = 0 var fileList = ArrayBuffer[String]() if (path.getParentFile != null) { fileList += parentDir } dirs.foreach(d => fileList += d.getName) files.foreach(f => fileList += f.getName) // refresh the user interface dialog.setTitle(currentPath.getPath) list.setAdapter(new ArrayAdapter(activity, android.R.layout.simple_list_item_1, fileList.toArray) { override def getView(pos: Int, view: View, parent: ViewGroup): View = { val superView = super.getView(pos, view, parent) superView.asInstanceOf[TextView].setSingleLine(true) superView } }) } } private def getChosenFile(fileChosen: String): File = { if (fileChosen == parentDir) { currentPath.getParentFile } else { new File(currentPath, fileChosen) } } }
trait FileSelectedListener { def fileSelected(file: File) }
Główną zmianą (oczywiście poza napisaniem tego w języku Scala) jest dodanie ograniczenia na maksymalną wielkość pliku. Po wyborze pliku, jeżeli jego rozmiar przekracza ustawiony maksymalny rozmiar to zostaje wyświetlony komunkat z informacją, a plik nie zostaje dodany.
Dodaj komentarz