这个问题有点难以解释,无论如何它在这里:
MainActivity.java
package espn.example.com.espn;
import android.app.ProgressDialog;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, FragmentMainList.OnFragmentInteractionListener, FragmentPlayVideo.OnFragmentInteractionListener{
static final String URL = "http://192.168.0.106:8080/Video/video.xml";
static final String KEY_VIDEO = "video";
static final String KEY_ID = "id";
static final String KEY_TITLE = "title";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";
static final String KEY_VIDEO_URL = "video_url";
private static final String TAG = "DEBUG";
private ProgressDialog pDialog;
ListView list;
LazyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
isStoragePermissionGranted();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.mainFrame, new FragmentMainList());
ft.commit();
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.mainFrame, new FragmentMainList());
ft.commit();
} else {
Toast.makeText(getApplicationContext(), "Storage Permission denied", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_videos) {
} else if (id == R.id.nav_settings) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
Log.v(TAG,"Permission is granted");
return true;
}
}
@Override
public void onFragmentInteraction(String uri) {
getSupportActionBar().setTitle(uri);
}
}
FragmentMainList.Java
package espn.example.com.espn;
import android.app.ProgressDialog;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link FragmentMainList.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link FragmentMainList#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentMainList extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private ProgressDialog pDialog;
static final String URL = "http://192.168.0.106:8080/Video/video.xml";
static final String KEY_VIDEO = "video";
static final String KEY_ID = "id";
static final String KEY_TITLE = "title";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";
static final String KEY_VIDEO_URL = "video_url";
private static final String TAG = "DEBUG";
LayoutInflater inflaters;
ListView list;
LazyAdapter adapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public FragmentMainList() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment FragmentMainList.
*/
// TODO: Rename and change types and number of parameters
public static FragmentMainList newInstance(String param1, String param2) {
FragmentMainList fragment = new FragmentMainList();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
inflaters = getActivity().getLayoutInflater();
new DownloadFileFromURL().execute(URL);
onButtonPressed("Main List");
return inflater.inflate(R.layout.fragment_main_list, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(String uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(String name);
}
private void populateListView() {
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard,"output.xml");
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {
Toast.makeText(getContext(), "Unable to Load Data", Toast.LENGTH_SHORT).show();
System.out.println("Unable to open output.xml");
}
final ArrayList<HashMap<String, String >> videos = new ArrayList<>();
XMLParser parser = new XMLParser();
Document doc = parser.getDomElement(text.toString()); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_VIDEO);
for (int i = 0; i < nl.getLength(); i++) {
final HashMap<String, String> map= new HashMap<>();
Element e = (Element) nl.item(i);
map.put(KEY_ID, parser.getValue(e, KEY_ID));
map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
map.put(KEY_VIDEO_URL, parser.getValue(e, KEY_VIDEO_URL));
videos.add(map);
}
list = getView().findViewById(R.id.list);
adapter=new LazyAdapter(FragmentMainList.this, videos, inflaters);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
FragmentPlayVideo playVideoFragment = new FragmentPlayVideo ();
Bundle args = new Bundle();
args.putString("YourKey", "YourValue");
FragmentTransaction ft = getFragmentManager().beginTransaction();
playVideoFragment.setArguments(args);
ft.replace(R.id.mainFrame, playVideoFragment);
ft.addToBackStack(null); // if written, this transaction will be added to backstack
ft.commit();
}
});
}
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
System.out.println("Starting download");
pDialog = new ProgressDialog(getContext());
pDialog.setMessage("Loading... Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected String doInBackground(String... f_url) {
int count;
try {
String root = Environment.getExternalStorageDirectory().toString();
System.out.println("Downloading");
URL url = new URL(f_url[0]);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
File SDCardRoot = Environment.getExternalStorageDirectory();
File file = new File(SDCardRoot, "output.xml");
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
int totalSize = urlConnection.getContentLength();
pDialog.setMax(totalSize);
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
}
fileOutput.close();
} catch (MalformedURLException e) {
e.printStackTrace();
return "failed";
} catch (IOException e) {
e.printStackTrace();
return "failed";
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
@Override
protected void onPostExecute(String status) {
System.out.println("Downloaded");
populateListView();
pDialog.dismiss();
}
}
}
FragmentPlayVideo.java
package espn.example.com.espn;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.MediaController;
import android.widget.VideoView;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link FragmentPlayVideo.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link FragmentPlayVideo#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentPlayVideo extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private MediaController mediaControls;
private VideoView videoView;
private View rootView;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public FragmentPlayVideo() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment FragmentPlayVideo.
*/
// TODO: Rename and change types and number of parameters
public static FragmentPlayVideo newInstance(String param1, String param2) {
FragmentPlayVideo fragment = new FragmentPlayVideo();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_play_video, container, false);
String value = getArguments().getString("YourKey");
System.out.println(value);
videoView = rootView.findViewById(R.id.videoview);
//String s = getIntent().getStringExtra("VIDEO_URL");
MediaController mediaController = new MediaController(getContext());
mediaController.setAnchorView(videoView);
//Uri video = Uri.parse(s);
videoView.setMediaController(mediaController);
//videoView.setVideoURI(Uri.parse(s));
videoView.start();
onButtonPressed("Video");
return inflater.inflate(R.layout.fragment_play_video, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(String uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(String uri);
}
}
ActivityMain.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
nav_header_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="80dp"
android:paddingTop="@dimen/nav_header_vertical_spacing"
app:srcCompat="@mipmap/espn2" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="ESPN"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elegantTextHeight="true"
android:text="On-Demand Streaming" />
</LinearLayout>
app_bar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="espn.example.com.espn.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="espn.example.com.espn.MainActivity"
tools:showIn="@layout/app_bar_main">
<!-- Note : This is the container Frame Layout for all the fragmetns-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainFrame">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
fragment_main_list.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="espn.example.com.espn.FragmentPlayVideo">
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
fragment_play_video.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="espn.example.com.espn.FragmentPlayVideo">
<VideoView
android:id="@+id/videoview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
如果您需要更多信息,请与我们联系。谢谢
答案 0 :(得分:0)
您没有将任何视频URI传递给VideoView
,这就是为什么它仍然是黑色的。
尝试对您的视频网址进行硬编码。
例如,
videoView.setMediaController(mediaController);
videoView.setVideoURI(Uri.parse("https://youtu.be/RkD_eAzSF7U"));
videoView.start();
关于DrawerLayout
的黑色背景,请检查@layout/nav_header_main
的代码,可能是其背景颜色为黑色。