2

Edit: i thought i had a problem with my implementation of the fragment that caused the videoView not to work, but it turned out that the implementation was correct and i just had a problem with the layout xml of the videoView. ill keep the code as an example of a correct implementation of a videoView inside a fragment using viewpager:)

this is my Fragment:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;

import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.TextView;
import android.widget.VideoView;

import uk.co.senab.photoview.PhotoView;
import uk.co.senab.photoview.PhotoViewAttacher;


public class ScreenSlidePageFragment extends Fragment {

    private Context context = null; //TODO MAKE SETTER
    private String fileName;
    private final String FILE_NAME = "FILE_name";

    /**
     * Factory method for this fragment class. Constructs a new fragment.
     */
    public static ScreenSlidePageFragment create(String fileName, Context context) {
        ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
        fragment.setFileName(fileName);
        fragment.setContext(context);
        return fragment;
    }

    public ScreenSlidePageFragment() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        fileName = getArguments().getString(FILE_NAME);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout containing a title and body text.
        ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.fragment_screen_slide_page, container, false);

        // Set the title view to show the page number.
        String name = this.fileName;
        if (name != null) {
            if (name.endsWith(".jpg")) {
                Bitmap myBitmap = BitmapFactory.decodeFile(name);
                ImageView view = (ImageView) rootView.findViewById(R.id.imageView);
                view.setImageBitmap(myBitmap);
                PhotoViewAttacher mAttacher = new PhotoViewAttacher(view);
            }
            if (name.endsWith(".mp4")) {
                final VideoView video = (VideoView) rootView.findViewById(R.id.videoView);

                video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        video.requestFocus();
                        video.start();
                    }
                });
                video.setVideoURI(Uri.parse(name));
//                Bitmap bitmap = ThumbnailUtils.createVideoThumbnail("/storage/sdcard0/Android/data/huji.ac.il.test/files/savedFiles/150401015447.mp4", MediaStore.Video.Thumbnails.MICRO_KIND);
//                ImageView view = (ImageView) rootView.findViewById(R.id.imageView);
//                view.setImageBitmap(bitmap);
            }

        }
        return rootView;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public void setContext(Context context) {
        this.context = context;
    }
}

this is the layout "fragment_screen_slide_page.xml":

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    android:layout_gravity="center"

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_margin="0dp"

        />

    <VideoView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/videoView"
        android:layout_gravity="center_horizontal" />


</LinearLayout>

here is the activity that usess the fragment:

public class ScreenSlideActivity extends FragmentActivity {


    private ViewPager mPager;
    private PagerAdapter mPagerAdapter;
    private ArrayList<String> fileNameList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View decorView = getWindow().getDecorView();
        // Hide the status bar.
        int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);

        setContentView(R.layout.activity_screen_slide);

        fileNameList=getImagesFromStorage();
        // Instantiate a ViewPager and a PagerAdapter.
        mPager = (ViewPager) findViewById(R.id.pager);
        mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(), fileNameList,this);
        mPager.setAdapter(mPagerAdapter);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public ArrayList<String> getImagesFromStorage()
    {
        ArrayList<String> fileNameList= new ArrayList<String>();
        File file= new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath()+ File.separator + "savedFiles");

        if (file.isDirectory())
        {
            File[] listOfFiles= file.listFiles();
            for (int i = 0; i <listOfFiles.length; i++)
            {

                fileNameList.add(listOfFiles[i].getAbsolutePath());
            }
        }
        return fileNameList;
    }

}

I tried turning on GPU Acceleration as some post suggested but it didn't work. I tried playing the video on the main activity instead on the fragment and it worked, so im gussing that the problem is with my fragment. any suggestions?

Edit:

the adapter:

public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    private ArrayList<String> fileNames;
    private Context context=null;


    public ScreenSlidePagerAdapter(FragmentManager fragmentManager, ArrayList<String> fileNameList,Context context) {
        super(fragmentManager);
        this.fileNames=fileNameList;
        this.context=context;
    }


    @Override
    public Fragment getItem(int position) {

        return ScreenSlidePageFragment.create(fileNames.get(position),this.context);
    }

    @Override
    public int getCount() {
        return fileNames.size();
    }
}
niryo
  • 1,275
  • 4
  • 15
  • 26
  • Did you inflate the Fragment in your MainActivity? – jyoonPro Apr 01 '15 at 14:12
  • no..my main activity is intenting to other activity like this: startActivity(new Intent(MainActivity.this, ScreenSlideActivity.class)); I eddit the question and add the code for ScreenSlideActivity.java. all this fragment stuff is new to me. where should i inflate the fragment? – niryo Apr 01 '15 at 14:19
  • Fragments are supposed to be something inside an Activity. So you don't start a Fragment like the way you do with an Activity. You call a FragmentTransaction... I'll write up an answer. Can you provide me the description of how this fragment is supposed to work? Like, how it starts, what it does? – jyoonPro Apr 01 '15 at 14:27
  • Btw, do i really need Fragments? I wanted to implement an image and video viewer just like the classic viewers when you see the photos/videos one by one and simply slide (left and right) to the next photo. after lots of reading i came across viewPager and it seems to do exactly what i want, and it doing so using Fragments...that why i end up using fragments. so, am i on the right path? sorry for the off question... – niryo Apr 01 '15 at 14:36
  • Ohh, so this is inside a ViewPager. Yes, you will need to use Fragments for performance. – jyoonPro Apr 01 '15 at 14:40
  • I think that if you want to show a "slide" of pictures and videos you should go with the view pager implementation as you seem to be going. The only thing i don't understand (as @jyoon asked) is how you are loading the Fragments... in this case you should load them inside the pager. If you don't want to use fragments, you can always use custom views, but view pager is now going to work, in that case you can use: custom views (instead of fragmets) + [twoway view library](https://github.com/lucasr/twoway-view) (instead of view pager) – mmark Apr 01 '15 at 14:42
  • Could we please see your MainActivity? – jyoonPro Apr 01 '15 at 14:43
  • yes...ill add the main activity and the pager adapter to the question – niryo Apr 01 '15 at 14:45
  • @urudroid, tnx for your reply. you and jyoon convinced me that im on the right way so il stick with the fragments...as i said- the images works fine...i hope that you guys could help me solve the video problem but if not i will just try to use thumbnails instead of actuall video and atach a button to start a new activity with the video or something like that... – niryo Apr 01 '15 at 14:58
  • @kundasaba when you set video.setVideoURI(Uri.parse(name)); are you setting the absolute path for the video file or only the name? it is confusing me. Also, instead of : MediaController mc= new MediaController(getActivity()); mc.setAnchorView(video); video.setMediaController(mc); video.requestFocus(); you should use: videovidew.setOnPreparedListener(new onPrepared(Mediaplayer mp){} The videoview has a mediaplayer itself so you don't need to create a new one – mmark Apr 01 '15 at 15:04
  • @urudroid im using the full path...and i also tried vide.setVideoPath instead of uri...still getting nothing. I really think it's someing with the fragment beacause as i said, i was able to play the video on the main activity without any problem. i will try your second suggestions maybe it will help – niryo Apr 01 '15 at 15:09

1 Answers1

5

You need to make sure you have set:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

in your AndroidManifest.xml

Also, i think you're not starting the video at all

In your VideoView initialisation you can access the MediaPlayer within the VideoView using:

VideoView video = (VideoView) rootView.findViewById(R.id.videoView);
video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    videoView.requestFocus();
                    videoView.start();
                }
  });
video.setVideoURI(Uri.parse(pathForTheFile));

EDIT: As it is a local video that your'e trying to play, you don't need to wait the MediaPlayer to be prepared, so this should work:

VideoView video = (VideoView) rootView.findViewById(R.id.videoView);               
video.setVideoURI(Uri.parse(pathForTheFile));
video.start();
video.requestFocus();

So, you wont need these lines:

MediaController mc=  new MediaController(getActivity());
                mc.setAnchorView(video);
                video.setMediaController(mc);
                video.requestFocus();

Let me know if it worked

mmark
  • 1,204
  • 12
  • 19
  • still doesn't wrok:( I have the permission and i changed those line you told me to change but still i can't get the video to work. is there anythong i can copy from the logcat that could help? – niryo Apr 01 '15 at 15:35
  • Yes, please copy any error, or general mediaplayer message. Please make sure alse that public void onPrepared(MediaPlayer mp) { videoView.requestFocus(); videoView.start(); } is called. Please check that a edited the answer and fixed the order of the lines – mmark Apr 01 '15 at 15:37
  • ok i eddited the fragment code in the question...soon ill add logcat – niryo Apr 01 '15 at 15:43
  • Look at the edit in the answer, that is working for me with a mp4 file stored in the sd card – mmark Apr 01 '15 at 15:46
  • i don't have such example but it i think the error is not because of you using ViewPager.. Can you share the fragment's xml file? – mmark Apr 01 '15 at 17:16
  • i just solve the problem...damn im so stupid. the problem was indeed in the fragment xml! i put the video view under the image view so the image took over the screen and because i didn't set it to anything it was just blank. for my defend, im very new to android. i thout that i didn't set the view it would not be visible. should i delete this question now, as it turned out to be not related at all to Fragments, just for humen error? – niryo Apr 01 '15 at 17:19
  • Maybe you can add an edit to your question so if anyone goes through a VideoView initialisation issue and came to this question, can know that the implementation you have is correct, but the view handling isn't ;) – mmark Apr 01 '15 at 17:40