1、本地docx文件解析
(1)引入依赖
implementation 'tm-extractors:tm-extractors:0.4'
(2)解析文件
private fun readDOCX(path: String?): String? {
var river = ""
try {
val zipFile = ZipFile(File(path))
val sharedStringXML: ZipEntry = zipFile.getEntry("word/document.xml")
val inputStream: InputStream = zipFile.getInputStream(sharedStringXML)
val xmlParser = Xml.newPullParser()
xmlParser.setInput(inputStream, "utf-8")
var evtType = xmlParser.eventType
while (evtType != XmlPullParser.END_DOCUMENT) {
when (evtType) {
XmlPullParser.START_TAG -> {
val tag = xmlParser.name
println(tag)
if (tag.equals("t", ignoreCase = true)) {
river += xmlParser.nextText() + "\n"
}
}
XmlPullParser.END_TAG -> {}
else -> {}
}
evtType = xmlParser.next()
}
} catch (e: ZipException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
} catch (e: XmlPullParserException) {
e.printStackTrace()
}
if (river == null) {
river = "解析文件出现问题"
}
return river
}
2、本地xls文件解析
(1)需要引入jar包 jxl-2.6.9.jar
(2)解析文件
try {
val inputStream = assets.open("article.xls")
val book: Workbook = Workbook.getWorkbook(inputStream)
val sheets = book.sheets
val articleList = mutableListOf<PropositionArticle>()
launch(Dispatchers.IO, {
for (i in sheets.indices) {
val sheet = book.getSheet(i)
val article = PropositionArticle(sheet.name, sheet.getCell(0,0).contents)
articleList.add(article)
}
kv.encode(ARTICLE_TOTAL, sheets.size)
book.close()
inputStream.close()
AppDatabase.getInstance().propositionArticleDao().insertAllPropositionArticle(articleList)
}, {it.printStackTrace()})
}catch (e: Exception) {
e.printStackTrace()
}
3、音频播放时,设置进度条并同步播放进度
(1)布局文件上
<LinearLayout
android:id="@+id/lv_seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/iv_play"
android:layout_marginBottom="14dp">
<TextView
android:id="@+id/current_progress_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
tools:text="0:50"
android:textSize="12sp" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:background="@color/lucid_white_color"/>
<TextView
android:id="@+id/duration_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
tools:text="3:50"
android:textSize="12sp"/>
</LinearLayout>
(2)创建一个子线程及定时任务,用来同步进度条
private var update_progress_thread: Thread? = null
private var timer: Timer? = null
fun updateProgress() {
if (update_progress_thread != null && update_progress_thread!!.isAlive) update_progress_thread!!.destroy()
update_progress_thread = Thread {
timer = Timer()
val task: TimerTask = object : TimerTask() {
override fun run() {
if (musicPlayer != null && musicPlayer!!.isPlaying){
runOnUiThread{
binding.currentProgressText.text = musicPlayer?.currentPosition?.let { durationToString(it) }
musicPlayer?.currentPosition?.let { binding.seekBar.progress = it }
}
}
}
}
timer!!.schedule(task, 50, 1000)
}
update_progress_thread!!.start()
}
(3)seekbar设置初始值和设置监听
binding.seekBar.apply {
progress = 0
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
override fun onProgressChanged(
seekBar: SeekBar?,
progress: Int,
fromUser: Boolean
) {
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
musicPlayer?.pause()
binding.ivPlay.setImageResource(R.mipmap.ico_play)
isPlay = false
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
seekBar?.progress?.let { musicPlayer?.seekTo(it) }
binding.ivPlay.setImageResource(R.mipmap.ico_stop)
isPlay = true
musicPlayer?.start()
}
})
}
(4)在mediaplayer初始化时,调用上面的子线程方法
private var musicPlayer: MediaPlayer? = null
private fun playMediaPlayer(path: String) {
zLoadingDialog.show()
musicPlayer?.let {
it.stop()
it.release()
musicPlayer = null
}
musicPlayer = MediaPlayer()
musicPlayer?.setDataSource(path)
musicPlayer?.prepareAsync()
binding.currentProgressText.text = durationToString(0)
binding.seekBar.apply {
progress = 0
setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
override fun onProgressChanged(
seekBar: SeekBar?,
progress: Int,
fromUser: Boolean
) {
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
musicPlayer?.pause()
binding.ivPlay.setImageResource(R.mipmap.ico_play)
isPlay = false
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
seekBar?.progress?.let { musicPlayer?.seekTo(it) }
binding.ivPlay.setImageResource(R.mipmap.ico_stop)
isPlay = true
musicPlayer?.start()
}
})
}
musicPlayer?.setOnPreparedListener { mediaPlayer ->
zLoadingDialog.dismiss()
binding.durationText.text = durationToString(mediaPlayer.duration)
binding.seekBar.max = mediaPlayer.duration
mediaPlayer.start() // 准备好了再播放
binding.ivPlay.setImageResource(R.mipmap.ico_stop)
updateProgress()
}
musicPlayer?.setOnCompletionListener {
binding.ivPlay.setImageResource(R.mipmap.ico_play)
}
}
/**
* 把毫秒时长转换为类似03:50的String */
fun durationToString(duration: Int): String? {
val duration_second = duration / 1000 //单位转换为秒
val minute = duration_second / 60 //求得分钟数
val second = duration_second % 60 //求得不满一分钟的秒数
val sb = StringBuilder()
if (minute < 10) sb.append(0)
sb.append(minute)
sb.append(':')
if (second < 10) sb.append(0)
sb.append(second)
return sb.toString()
}