我知道在SO中有很多关于这个错误的问题,但我的问题是不同的。我正在尝试在videoview中播放sdcard的视频。 VideoView使用serivce在WindowManager上运行。因此,该应用程序可以在任何应用程序之上播放视频。每件事都有效,我可以播放视频。但是我的手机中存在损坏的文件,并未在其他任何视频播放器中播放。它会说错误读取文件。但是当我用我的应用程序打开该视频文件时,现在服务运行然后出现问题,APP正在崩溃。我无法解决问题,以至于Toast错误读取视频文件。我试过
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(getBaseContext(), "Error reading file", Toast.LENGTH_SHORT).show();
return false;
}
});
没用。
CODE:
public class VideoWindow extends Service {
private WindowManager windowManager;
private RelativeLayout relativeLayout;
WindowManager.LayoutParams params;
private GestureDetectorCompat gestureDetectorCompat;
private View mLayout;
DisplayMetrics metrics;
private boolean didFling;
private int[] clickLocation = new int[2];
private static final String LOG_TAG = "Floaty";
private float ratioY = 0;
private float oldWidth = 0;
private float oldX = 0;
private boolean confChange = false;
private VideoView videoView;
private ProgressBar progressBar;
private int position = 0;
private String videoUrl;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("OnStartCommandStarted", "true");
metrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(metrics);
confChange = intent.getExtras().getBoolean("confchange");
oldX = intent.getExtras().getFloat("oldX");
ratioY = intent.getExtras().getFloat("ratioY");
oldWidth = intent.getExtras().getFloat("oldWidth");
videoUrl = intent.getExtras().getString("videourl");
position = intent.getExtras().getInt("position");
windowManager.removeView(mLayout);
if (confChange) {
confChange = false;
Log.d("Configure change","true");
if (oldX < (oldWidth / 2)) {
params.x = 0;
} else {
params.x = metrics.widthPixels;
}
params.y = (int) (metrics.heightPixels * ratioY);
} else {
params.x = metrics.widthPixels;
params.y = 0;
}
windowManager.addView(mLayout,params);
playVideo();
return START_NOT_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Log.d("OnCreate Started", "true");
gestureDetectorCompat = new GestureDetectorCompat(this,new Gesture());
LayoutInflater layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mLayout=layoutInflater.inflate(R.layout.smallwindow, null);
relativeLayout = (RelativeLayout)mLayout.findViewById(R.id.body);
videoView = (VideoView)mLayout.findViewById(R.id.videoview);
progressBar = (ProgressBar)mLayout.findViewById(R.id.videoloadprogress);
progressBar.setVisibility(View.VISIBLE);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
metrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(metrics);
params= new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP| Gravity.START;
Log.d("Configure", String.valueOf(confChange));
relativeLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetectorCompat.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
relativeLayout.setAlpha(1.0f);
if (!didFling) {
Log.d(LOG_TAG, "ACTION_UP");
int newX = params.x;
if (newX > (metrics.widthPixels / 2)) {
params.x = metrics.widthPixels;
} else {
params.x = 0;
}
windowManager.updateViewLayout(mLayout, params);
}
}
return true;
}
});
windowManager.addView(mLayout, params);
}
private void playVideo(){
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(getBaseContext(), "Error reading file", Toast.LENGTH_SHORT).show();
return false;
}
});
try{
Log.d("videoUrl",videoUrl);
videoView.setVideoURI(Uri.parse(videoUrl));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e){
Toast.makeText(this,"Error reading file",Toast.LENGTH_SHORT).show();
Log.e("Error", e.getMessage());
e.printStackTrace();
}
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.seekTo(position);
progressBar.setVisibility(View.INVISIBLE);
if (position == 0) {
videoView.start();
} else if(position>0) {
videoView.start();
videoView.seekTo(position);
position=0;
}else{
videoView.pause();
}
}
});
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE || newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
int[] location = new int[2];
mLayout.getLocationOnScreen(location);
oldWidth = metrics.widthPixels;
oldX = location[0];
ratioY = (float) (location[1]) / (float) metrics.heightPixels;
this.stopService(new Intent(this, VideoWindow.class));
confChange=true;
Intent intent = new Intent(this, VideoWindow.class);
intent.putExtra("confchange",confChange);
intent.putExtra("oldX",oldX);
intent.putExtra("ratioY",ratioY);
intent.putExtra("oldWidth",oldWidth);
intent.putExtra("clickLocation",clickLocation);
intent.putExtra("videourl",videoUrl);
intent.putExtra("position",videoView.getCurrentPosition());
this.startService(intent);
Log.d("OnConfigurationChanged","true");
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private class Gesture extends GestureDetector.SimpleOnGestureListener {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onDown(MotionEvent event) {
Log.d(LOG_TAG, "onDown");
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
didFling = false;
return false;
}
@Override
public void onShowPress(MotionEvent e) {
Log.d(LOG_TAG, "onShowPress");
relativeLayout.setAlpha(0.9f);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (relativeLayout.getVisibility() == View.VISIBLE) {
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
mLayout.setBackgroundColor(Color.argb(0, 0, 0, 0));
}
params.x = (initialX + (int) ((e2.getRawX() - initialTouchX)));
params.y = (initialY + (int) ((e2.getRawY() - initialTouchY)));
windowManager.updateViewLayout(mLayout, params);
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.d(LOG_TAG, "onSingleTapConfirmed");
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d(LOG_TAG, "onFling");
didFling = true;
int newX = params.x;
if (newX > (metrics.widthPixels / 2))
params.x = metrics.widthPixels;
else
params.x = 0;
windowManager.updateViewLayout(mLayout, params);
return false;
}
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
stopService(new Intent(getApplicationContext(), VideoWindow.class));
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mLayout != null){
windowManager.removeView(mLayout);
}
}
}
堆栈跟踪:
10-11 19:18:29.911 6268-6302/com.ficean.floatingvideoplayer I/OpenGLRenderer: Initialized EGL, version 1.4
10-11 19:18:29.922 6268-6302/com.ficean.floatingvideoplayer D/OpenGLRenderer: Enabling debug mode 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: PartialUpdate status: Disabled
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Left Align: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Width Align: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Top Align: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Height Align: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Min ROI Width: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Min ROI Height: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Needs ROI Merge: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Dynamic Fps: Disabled
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Min Panel fps: 0
10-11 19:18:29.927 6268-6302/com.ficean.floatingvideoplayer I/qdutils: Max Panel fps: 0
10-11 19:18:32.696 6268-6546/com.ficean.floatingvideoplayer D/skia: --- SkImageDecoder::Factory returned null
10-11 19:18:32.696 6268-6546/com.ficean.floatingvideoplayer D/skia: --- SkImageDecoder::Factory returned null
10-11 19:18:32.759 6268-6546/com.ficean.floatingvideoplayer E/MediaMetadataRetrieverJNI: getFrameAtTime: videoFrame is a NULL pointer
10-11 19:18:34.624 6268-6735/com.ficean.floatingvideoplayer I/ListingVideos: query count=9
10-11 19:18:34.624 6268-6735/com.ficean.floatingvideoplayer D/videos: /storage/emulated/0/Movies/Onamalu Telugu Full Movie HD - Rajendra Prasad _ Kalyani _ Kranthi Madhav_HIGH-mc.mp4
10-11 19:18:34.673 6268-6268/com.ficean.floatingvideoplayer D/Loaded: true
10-11 19:18:34.685 6268-6759/com.ficean.floatingvideoplayer D/skia: --- SkImageDecoder::Factory returned null
10-11 19:18:34.686 6268-6759/com.ficean.floatingvideoplayer D/skia: --- SkImageDecoder::Factory returned null
10-11 19:18:34.719 6268-6759/com.ficean.floatingvideoplayer E/MediaMetadataRetrieverJNI: getFrameAtTime: videoFrame is a NULL pointer
10-11 19:18:38.832 6268-6268/com.ficean.floatingvideoplayer D/OnCreate Started: true
10-11 19:18:38.868 6268-6268/com.ficean.floatingvideoplayer D/Configure: false
10-11 19:18:38.878 6268-6268/com.ficean.floatingvideoplayer D/OnStartCommandStarted: true
10-11 19:18:38.902 6268-6268/com.ficean.floatingvideoplayer D/videoUrl: /storage/emulated/0/Movies/Onamalu Telugu Full Movie HD - Rajendra Prasad _ Kalyani _ Kranthi Madhav_HIGH-mc.mp4
10-11 19:18:38.971 6268-6268/com.ficean.floatingvideoplayer D/MediaPlayer: Couldn't open file on client side, trying server side
10-11 19:18:39.022 6268-6289/com.ficean.floatingvideoplayer E/MediaPlayer: error (1, -2147483648)
10-11 19:18:39.056 6268-6268/com.ficean.floatingvideoplayer E/MediaPlayer: Error (1,-2147483648)
10-11 19:18:39.056 6268-6268/com.ficean.floatingvideoplayer D/VideoView: Error: 1,-2147483648
10-11 19:18:39.140 6268-6268/com.ficean.floatingvideoplayer D/AndroidRuntime: Shutting down VM
10-11 19:18:39.141 6268-6268/com.ficean.floatingvideoplayer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ficean.floatingvideoplayer, PID: 6268
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:583)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.app.Dialog.show(Dialog.java:298)
at android.app.AlertDialog$Builder.show(AlertDialog.java:993)
at android.widget.VideoView$5.onError(VideoView.java:537)
at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2592)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:702)