You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fragment中配置VideoView播放失败问题求助

解决VideoView无法播放网络视频的问题

问题症状

在Fragment的onViewCreated()中配置了VideoView,已添加网络权限,但播放时提示“无法播放此视频”。


核心原因及解决方案

1. Android 9+明文网络限制

从Android 9(API级别28)开始,系统默认禁止应用使用明文HTTP流量,你的视频链接为HTTP协议,需在AndroidManifest.xml的<application>标签中添加配置:

<application
    ...
    android:usesCleartextTraffic="true">

2. 为VideoView添加错误监听排查问题

添加错误监听可获取具体播放错误码,精准定位问题:

// 在视频配置代码中插入
videoview.setOnErrorListener { _, errorCode, extraCode ->
    Log.e("VideoPlayError", "错误码: $errorCode, 附加码: $extraCode")
    true
}

3. 正确关联MediaController

需将MediaController的锚点绑定到VideoView,确保控制器正常工作:

val mediaController = MediaController(context)
mediaController.setAnchorView(videoview) // 新增该行
videoview.setMediaController(mediaController)

4. 处理Fragment生命周期

Fragment切换时需管理VideoView的播放状态,避免异常:

override fun onPause() {
    super.onPause()
    videoview.pause()
}

override fun onResume() {
    super.onResume()
    if (!videoview.isPlaying) {
        videoview.start()
    }
}

override fun onDestroyView() {
    super.onDestroyView()
    videoview.stopPlayback() // 释放资源
}

修改后的完整Fragment代码

package com.service.bookitapp

import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.MediaController
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.coroutines.delay

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class HomeFragment : Fragment() {

    private var param1: String? = null
    private var param2: String? = null
    private lateinit var viewpager : ViewPager2

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_home, container, false)
        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val arrCategory = ArrayList<CategoryModel>()

        val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerCategory)
        arrCategory.add(CategoryModel(R.drawable.electrician,"Electrician"))
        arrCategory.add(CategoryModel(R.drawable.plumber,"Plumber"))
        arrCategory.add(CategoryModel(R.drawable.acservice,"AC Service"))
        arrCategory.add(CategoryModel(R.drawable.carpentry,"Carpentry"))
        arrCategory.add(CategoryModel(R.drawable.drop,"Pick up & Drop"))
        arrCategory.add(CategoryModel(R.drawable.painting,"Paint Service"))
        arrCategory.add(CategoryModel(R.drawable.waterfilter,"Water Filter"))
        arrCategory.add(CategoryModel(R.drawable.packer,"Pack and Move"))

        recyclerView.layoutManager = GridLayoutManager(context,4)
        val recyclerAdapter = context?.let { RecycleCategoryAdapter(it,arrCategory) }
        recyclerView.adapter = recyclerAdapter

        viewpager = view.findViewById(R.id.imageSlider)
        val imageList = listOf(R.drawable.slider1,R.drawable.slider2,R.drawable.slider3)
        val adapter = context?.let { ViewerPagerAdapter(it,imageList) }
        viewpager.adapter = adapter
        viewpager.autoScroll(lifecycleScope,3000)

        // 视频配置修改
        val mediaController = MediaController(context)
        mediaController.setAnchorView(videoview)
        val path : Uri = Uri.parse("http://videocdn.bodybuilding.com/video/mp4/62000/62792m.mp4")
        videoview.setMediaController(mediaController)
        videoview.setVideoURI(path)

        // 添加错误监听
        videoview.setOnErrorListener { _, what, extra ->
            Log.e("VideoError", "错误码: $what, 附加信息: $extra")
            Toast.makeText(context, "播放失败,错误码: $what", Toast.LENGTH_SHORT).show()
            true
        }

        videoview.requestFocus()
        videoview.start()
    }

    override fun onPause() {
        super.onPause()
        videoview.pause()
    }

    override fun onResume() {
        super.onResume()
        if (!videoview.isPlaying) {
            videoview.start()
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        videoview.stopPlayback()
    }
}

fun ViewPager2.autoScroll(lifecycleScope: LifecycleCoroutineScope, interval: Long){
    lifecycleScope.launchWhenResumed{
        scrollIndefinitely(interval)
    }
}

private suspend fun ViewPager2.scrollIndefinitely(interval: Long){
    delay(interval)
    val numberOfItems = adapter?.itemCount?:0
    val lastIndex = if(numberOfItems>0) numberOfItems - 1 else 0
    val nextItem = if(currentItem==lastIndex) 0 else currentItem + 1
    setCurrentItem(nextItem,true)
    scrollIndefinitely(interval)
}

补充检查项

  • 确认已添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
  • 测试视频链接是否可正常访问:在浏览器中打开链接,确认视频能正常播放
  • 检查视频格式是否被设备支持:VideoView支持MP4、3GP等常见格式,若格式不兼容需转码

内容的提问来源于stack exchange,提问作者Parish Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 05:31:17