私はビデオのURLを持っています。私はどんなプレーヤーでも再生することができます。またはVideoView
です。しかしここに私がやろうとしていることがあります。アクティビティがないときにビデオを再生する方法は?ビデオをフルスクリーンにする方法は?
RecyclerView
があり、各要素には動画のタイトルとサムネイルが含まれています。ユーザーがビデオをクリックすると、ポップアップウィンドウが表示されます。このポップアップウィンドウにはVideoView
(またはURLからビデオを再生できるもの)が含まれ、ビデオが再生されます。ユーザーはこのウィンドウをドラッグすることができます。そのトリックは、ユーザーが戻るボタンを押して現在のアクティビティを閉じると、ウィンドウが残り、ビデオの再生を続けるようにすることです。ビデオが再生されている間、ユーザーは他のアプリで何でもできますが、ビデオを含むウィンドウは上に残り、ビデオは引き続き再生されます。ユーザーはいつでもウィンドウ(またはウィンドウ内のボタン)を押すことができ、ビデオはフルスクリーンになります。ユーザーがフルスクリーンを再生することを決めた時点で、アプリのアクティビティはそこにないかもしれません。
何か、私は上記のように、私は、ユーザーがアプリのアクティビティを閉じたときにそこに残るビューでウィンドウを作成することができます
https://play.google.com/store/apps/details?id=com.djit.apps.stream&hl=en
このアプリに実装されています。この目的のために、私はこのライブラリ
https://github.com/pingpongboss/StandOut
を使用しますが、LIBのソースコードをチェックする場合は、StandOutWindow
は、ポップアップウィンドウを作成するService
であることがわかります。
私は実際にこのウィンドウでビデオを再生できます。ここに私のウィンドウのクラスです
public class FloatingWindow extends StandOutWindow {
private static final int WIDTH = 400;
private static final int HEIGHT = 361;
/*
I didn't think of a better way to set video url
therefore I made it static and set it with a static method
I know it is bad, but it works.
I will do it another way later
Now I have other issues
*/
private static String videoUrl = null;
public static void setVideoUrl(String videoUrl) {
FloatingWindow.videoUrl = videoUrl;
}
@Override
public String getAppName() {
return getApplicationContext().getResources().getString(R.string.app_name);
}
@Override
public int getAppIcon() {
return android.R.drawable.ic_menu_close_clear_cancel;
}
@Override
public void createAndAttachView(int id, FrameLayout frame) {
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.floating_window, frame, true);
/*
As you can see I didn't use MediaController for this videoView
VideoView works with it, except for device
On this one device MediaController crashed the app with BadTokenException: token null is not valid, is your activity running
*/
final VideoView videoView = (VideoView) view.findViewById(R.id.textureVideoView);
final ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.videoProgressBar);
final ScrollView description = (ScrollView) view.findViewById(R.id.videoDescription);
videoView.setVideoURI(Uri.parse(videoUrl));
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
/*
I don't want my video view to be visible until it is ready
Because while it is preparing it gets transparent
But I want a progress bar instead
Therefore initially set its dimensions to 1x1 and change the size when it's ready
*/
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.CENTER;
videoView.setLayoutParams(params);
progressBar.setVisibility(View.GONE);
}
});
/*
When the activity is not present VideoView crashes when clicked
To avoid crash I overrided setOnTouchListener method and return true from it
*/
videoView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
if (videoView.isPlaying()) {
videoView.pause();
} else {
videoView.start();
}
}
return true;
}
});
}
@Override
public StandOutLayoutParams getParams(int id, Window window) {
return new StandOutLayoutParams(id, WIDTH, HEIGHT,
StandOutLayoutParams.CENTER, StandOutLayoutParams.CENTER);
}
@Override
public int getFlags(int id) {
return super.getFlags(id)
| StandOutFlags.FLAG_BODY_MOVE_ENABLE
| StandOutFlags.FLAG_WINDOW_FOCUSABLE_DISABLE
| StandOutFlags.FLAG_DECORATION_SYSTEM
| StandOutFlags.FLAG_ADD_FUNCTIONALITY_DROP_DOWN_DISABLE
| StandOutFlags.FLAG_DECORATION_CLOSE_DISABLE;
}
@Override
public String getPersistentNotificationMessage(int id) {
return "Click here to close floating window";
}
@Override
public Intent getPersistentNotificationIntent(int id) {
return StandOutWindow.getCloseIntent(this, FloatingWindow.class, id);
}
}
上記のコードは動作しますが、いくつかの問題があります。
私は3つのデバイスとエミュレータでそれをテストしました。しかし、最初にクラッシュした装置があります。私は
MediaController
を取り除き、今ではほとんど動作します。ユーザーがウィンドウのサイズを変更すると、VideoView
のサイズが変わってしまいます。 Android互換性のためにコードが動作しないデバイスをテストする必要があるかもしれません。しかし、とにかく私が窓のあるプレーヤーをやっているのは間違っているかもしれないし、もっと良い方法を知っているかもしれない。私はそれを行う場合は、ビデオがあるまで
VideoView
のあるべきウィンドウ内の領域が透明になるので、私は、1×1にVideoView
のサイズを設定し、それを変更し、私はすぐに通常のサイズにすることはできませんする必要がありますロードされる。また、VideoView
をクリックして、システムにclickイベントを処理させることはできません。もし私がそれをすれば、私はBadTokenException: token null is not valid, is your activity running
になる。アクティビティが実行されていないため、クラッシュを防ぐためにclickイベントを自分で処理する必要があります。これらのハッキングは、私が間違っていると思うようにします。ビデオをフルスクリーンにする方法は考えられません。私が考えたのは、フルスクリーンのアクティビティを開始し、URLとビデオの位置を渡すことだけでした。たぶんこれが行く方法です。この場合、ユーザーはフルスクリーンボタンを押したときにビデオが再びロードされるのを待たなければなりません。さらに、フルスクリーンアクティビティが開始されたときにウィンドウがどのように動作するかはわかりません。
ビデオがアクティビティなしで再生されないように感じました。おそらく、すべてのタッチイベントを逃してアクティビティスタックに渡す目に見えないアクティビティが常に存在するような方法でこのウィンドウプレイヤーを作成する方法があります。そして、そのような活動はビデオ再生に使用することができます。
は、それが働いていた場合、私に教えてください。 – Contextioner