我正在尝试为我的用户提供使用外部或内部存储的功能。我正在显示图像和视频(科学性质)。将媒体存储在SD卡上时,一切都很好。但是当我在内部存储媒体时,只会显示图像。无论我尝试什么,我在尝试加载和显示存储在applicationcontext.getFilesDir()下的媒体时都会遇到各种错误。
将视频内容设置为此类文件有诀窍吗?
ContentResolver可以帮助我吗?
在相关的说明中,假设存在外部存储是否被视为不良形式?
提前致谢,
西特
下面是一个失败的版本“无法播放视频。抱歉,此视频无法播放”。但我有许多其他失败模式。我可以将内部视频复制到临时存储(外部)并播放它,因此这个复制到内部确实创建了一个有效的电影。它只在我尝试直接从内部存储器播放时失败。
videoFile = new File(this.getFilesDir() + File.separator + "test.mp4");
InputStream data = res.openRawResource(R.raw.moviegood);
try {
OutputStream myOutputStream = new FileOutputStream(videoFile);
byte[] buffer = new byte[8192];
int length;
while ( (length = data.read(buffer)) > 0 ) {
myOutputStream.write(buffer);
}
//Close the streams
myOutputStream.flush();
myOutputStream.close();
data.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vview.setKeepScreenOn(true);
vview.setVideoPath(videoFile.getAbsolutePath());
vview.start();
答案 0 :(得分:25)
MediaPlayer要求正在播放的文件具有世界可读的权限。您可以在adb shell中使用以下命令查看文件的权限:
ls -al /data/data/com.mypackage/myfile
您可能会看到“-rw ------”,这意味着只有所有者(您的应用,而不是MediaPlayer)具有读/写权限。
注意:您的手机必须是root用户才能使用ls命令而不指定文件(在内部存储器中)。
如果您的手机是root用户,则可以使用以下命令在adb shell中添加全局读取权限:
chmod o+r /data/data/com.mypackage/myfile
如果您需要以编程方式修改这些权限(需要root电话!),您可以在应用代码中使用以下命令:
Runtime.getRuntime().exec("chmod o+r /data/data/com.mypackage/myfile");
这基本上是一个linux命令。有关chmod的更多信息,请参阅https://help.ubuntu.com/community/FilePermissions。
编辑:找到另一种简单的方法here(对没有root电话的人有用)。由于应用程序拥有该文件,因此它可以创建文件描述符并将其传递给mediaPlayer.setDataSource():
FileInputStream fileInputStream = new FileInputStream("/data/data/com.mypackage/myfile");
mediaPlayer.setDataSource(fileInputStream.getFD());
此方法完全避免了权限问题。
答案 1 :(得分:2)
您可以使用:
videoView.setVideoURI(Uri.parse(file.getAbsolutePath()));
如果文件是世界可读的
或者您可以使用内容提供商
答案 2 :(得分:1)
我发布了自定义的VideoView实现there。
VideoView实现具有setVideoFD(FileDescriptor fd)
方法并解决了这个问题。
答案 3 :(得分:1)
我遇到了同样问题的这个帖子,我正在将我的视频从网络下载到内部存储,当保存时可以指定RW模式,即从PRIVATE
更改为{{1 }}
WORLD_READABLE
答案 4 :(得分:1)
public class AndroidVideoViewExample extends Activity {
private VideoView myVideoView;
private int position = 0;
private ProgressDialog progressDialog;
private MediaController mediaControls;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the main layout of the activity
setContentView(R.layout.activity_main);
//set the media controller buttons
if (mediaControls == null) {
mediaControls = new MediaController(AndroidVideoViewExample.this);
}
//initialize the VideoView
myVideoView = (VideoView) findViewById(R.id.video_view);
// create a progress bar while the video file is loading
progressDialog = new ProgressDialog(AndroidVideoViewExample.this);
// set a title for the progress bar
progressDialog.setTitle("JavaCodeGeeks Android Video View Example");
// set a message for the progress bar
progressDialog.setMessage("Loading...");
//set the progress bar not cancelable on users' touch
progressDialog.setCancelable(false);
// show the progress bar
progressDialog.show();
try {
//set the media controller in the VideoView
myVideoView.setMediaController(mediaControls);
//set the uri of the video to be played
myVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.kitkat));
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
myVideoView.requestFocus();
//we also set an setOnPreparedListener in order to know when the video file is ready for playback
myVideoView.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mediaPlayer) {
// close the progress bar and play the video
progressDialog.dismiss();
//if we have a position on savedInstanceState, the video playback should start from here
myVideoView.seekTo(position);
if (position == 0) {
myVideoView.start();
} else {
//if we come from a resumed activity, video playback will be paused
myVideoView.pause();
}
}
});
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
//we use onSaveInstanceState in order to store the video playback position for orientation change
savedInstanceState.putInt("Position", myVideoView.getCurrentPosition());
myVideoView.pause();
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//we use onRestoreInstanceState in order to play the video playback from the stored position
position = savedInstanceState.getInt("Position");
myVideoView.seekTo(position);
}
}
答案 5 :(得分:0)
你不能直接播放它。
您需要实现ContentProvider,然后将定义的Uri传递给setVideoUri(uri)方法。