Update source code with grid layout and channel management
Major changes: - Add ChannelAdapter for grid display functionality - Add ChannelRepository for data management - Add PlayerActivity for dedicated video playback - Add StreamChannel model for channel representation - Update MainActivity to support grid layout - Update activity_main.xml with grid UI components - Add channel item layouts and drawables - Update AndroidManifest.xml with new activity - Update build.gradle dependencies This implements the requested "grilla arreglada" functionality with proper channel grid display and management. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
203
app/src/main/java/com/streamplayer/PlayerActivity.java
Normal file
203
app/src/main/java/com/streamplayer/PlayerActivity.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package com.streamplayer;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.StrictMode;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.PlaybackException;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.ui.PlayerView;
|
||||
|
||||
public class PlayerActivity extends AppCompatActivity {
|
||||
|
||||
public static final String EXTRA_CHANNEL_NAME = "extra_channel_name";
|
||||
public static final String EXTRA_CHANNEL_URL = "extra_channel_url";
|
||||
|
||||
private PlayerView playerView;
|
||||
private ProgressBar loadingIndicator;
|
||||
private TextView errorMessage;
|
||||
private TextView channelLabel;
|
||||
private Button closeButton;
|
||||
private View playerToolbar;
|
||||
|
||||
private ExoPlayer player;
|
||||
private String channelName;
|
||||
private String channelUrl;
|
||||
private boolean overlayVisible = true;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
StrictMode.setThreadPolicy(
|
||||
new StrictMode.ThreadPolicy.Builder().permitAll().build()
|
||||
);
|
||||
|
||||
setContentView(R.layout.activity_player);
|
||||
|
||||
Intent intent = getIntent();
|
||||
if (intent == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
channelName = intent.getStringExtra(EXTRA_CHANNEL_NAME);
|
||||
channelUrl = intent.getStringExtra(EXTRA_CHANNEL_URL);
|
||||
|
||||
if (channelName == null || channelUrl == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
initViews();
|
||||
channelLabel.setText(channelName);
|
||||
|
||||
DNSSetter.configureDNSToGoogle(this);
|
||||
loadChannel();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
playerView = findViewById(R.id.player_view);
|
||||
loadingIndicator = findViewById(R.id.loading_indicator);
|
||||
errorMessage = findViewById(R.id.error_message);
|
||||
channelLabel = findViewById(R.id.player_channel_label);
|
||||
closeButton = findViewById(R.id.close_button);
|
||||
playerToolbar = findViewById(R.id.player_toolbar);
|
||||
|
||||
closeButton.setOnClickListener(v -> finish());
|
||||
playerView.setOnClickListener(v -> toggleOverlay());
|
||||
}
|
||||
|
||||
private void loadChannel() {
|
||||
showLoading(true);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
String resolvedUrl = StreamUrlResolver.resolve(channelUrl);
|
||||
runOnUiThread(() -> startPlayback(resolvedUrl));
|
||||
} catch (Exception e) {
|
||||
runOnUiThread(() -> showError("Error al obtener stream: " + e.getMessage()));
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void startPlayback(String streamUrl) {
|
||||
try {
|
||||
releasePlayer();
|
||||
player = new ExoPlayer.Builder(this).build();
|
||||
playerView.setPlayer(player);
|
||||
|
||||
player.addListener(new Player.Listener() {
|
||||
@Override
|
||||
public void onPlaybackStateChanged(int playbackState) {
|
||||
if (playbackState == Player.STATE_READY) {
|
||||
showLoading(false);
|
||||
} else if (playbackState == Player.STATE_BUFFERING) {
|
||||
showLoading(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(PlaybackException error) {
|
||||
showError("Error al reproducir: " + error.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
MediaItem mediaItem = MediaItem.fromUri(streamUrl);
|
||||
player.setMediaItem(mediaItem);
|
||||
player.prepare();
|
||||
player.setPlayWhenReady(true);
|
||||
setOverlayVisible(false);
|
||||
|
||||
} catch (Exception e) {
|
||||
showError("Error al inicializar reproductor: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void showLoading(boolean show) {
|
||||
loadingIndicator.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
errorMessage.setVisibility(View.GONE);
|
||||
playerView.setVisibility(show ? View.GONE : View.VISIBLE);
|
||||
if (show) {
|
||||
setOverlayVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void showError(String message) {
|
||||
loadingIndicator.setVisibility(View.GONE);
|
||||
playerView.setVisibility(View.GONE);
|
||||
errorMessage.setVisibility(View.VISIBLE);
|
||||
errorMessage.setText(message);
|
||||
setOverlayVisible(true);
|
||||
}
|
||||
|
||||
private void releasePlayer() {
|
||||
if (player != null) {
|
||||
player.release();
|
||||
player = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
if (player != null) {
|
||||
playerView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (player != null) {
|
||||
playerView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (player != null) {
|
||||
playerView.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (player != null) {
|
||||
playerView.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
releasePlayer();
|
||||
}
|
||||
|
||||
private void toggleOverlay() {
|
||||
setOverlayVisible(!overlayVisible);
|
||||
}
|
||||
|
||||
private void setOverlayVisible(boolean visible) {
|
||||
overlayVisible = visible;
|
||||
playerToolbar.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (!overlayVisible) {
|
||||
setOverlayVisible(true);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user