¿Puede un videoview reproducir un video almacenado en el almacenamiento interno?

Intento brindarles a mis usuarios la posibilidad de usar almacenamiento externo o interno. Estoy mostrando imágenes y videos (de naturaleza científica). Al almacenar los medios en la tarjeta SD, todo está bien. Pero cuando almaceno los medios internamente, solo se mostrarán las imágenes. No importa lo que bash, recibo varios errores cuando bash cargar y visualizar los medios almacenados bajo applicationcontext.getFilesDir ().

¿Hay algún truco para establecer el contenido de una videovista en dicho archivo?

¿Puede un ContentResolver ayudarme?

En una nota relacionada, ¿se considera mala forma suponer que existe almacenamiento externo?

Gracias por adelantado,

Sid

Debajo hay una versión que falla con “No se puede reproducir el video. Lo siento, este video no se puede reproducir”. Pero tengo muchos otros modos de falla. Puedo copiar el video interno al almacenamiento temporal (externo) y reproducirlo, por lo que esta copia en interno sí crea una película válida. Solo falla cuando bash reproducirlo directamente desde el almacenamiento interno.

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(); 

MediaPlayer requiere que el archivo que se está reproduciendo tenga permisos legibles por todo el mundo. Puede ver los permisos del archivo con el siguiente comando en adb shell:

 ls -al /data/data/com.mypackage/myfile 

Probablemente verá “-rw ——“, lo que significa que solo el propietario (su aplicación, no MediaPlayer) tiene permisos de lectura / escritura.

Nota: Su teléfono debe estar rooteado para poder usar el comando ls sin especificar el archivo (en la memoria interna).

Si su teléfono está rooteado, puede agregar permisos de lectura mundial en adb shell con el siguiente comando:

 chmod o+r /data/data/com.mypackage/myfile 

Si necesita modificar estos permisos mediante progtwigción (¡requiere un teléfono rooteado!), Puede usar el siguiente comando en el código de su aplicación:

 Runtime.getRuntime().exec("chmod o+r /data/data/com.mypackage/myfile"); 

Que es básicamente un comando de Linux. Consulte https://help.ubuntu.com/community/FilePermissions para obtener más información sobre chmod.

EDITAR: Encontré otro enfoque simple aquí (útil para aquellos sin teléfonos rooteados). Como la aplicación posee el archivo, puede crear un descriptor de archivo y pasarlo a mediaPlayer.setDataSource ():

 FileInputStream fileInputStream = new FileInputStream("/data/data/com.mypackage/myfile"); mediaPlayer.setDataSource(fileInputStream.getFD()); 

Este enfoque evita por completo el problema del permiso.

Puedes usar:

 videoView.setVideoURI(Uri.parse(file.getAbsolutePath())); 

si el archivo es legible en todo el mundo

O puede usar un proveedor de contenido

Publiqué una implementación de VideoView personalizada allí .

La implementación VideoView tiene el setVideoFD(FileDescriptor fd) y resuelve este problema.

Encontré este hilo con el mismo problema, estoy descargando mis videos de la web al almacenamiento interno, resulta que al guardar puedes especificar el modo RW, es decir, cambiar de PRIVATE a WORLD_READABLE

 URL url = new URL(_url); InputStream input = null; FileOutputStream output = null; try { String outputName = "video.mp4"; input = url.openConnection().getInputStream(); output = c.openFileOutput(outputName, Context.MODE_WORLD_READABLE); int read; byte[] data = new byte[5120]; //5MB byte array while ((read = input.read(data)) != -1) output.write(data, 0, read); return true; } finally { if (output != null) output.close(); if (input != null) input.close(); } } 

Para detalles, consulte este tutorial

 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); } } 

No puedes simplemente jugarlo directamente.

Debe implementar ContentProvider y pasar el método Uri definido a setVideoUri (uri).