Unacceptable certificate error in webrtc video chat application - java

I'm building video chat application using webrtc. when i started video call some error is coming. how to resolve that issue.
E/RoomRTCClient: Room connection error: HTTP POST to https://appr.tc/join/E52U8KA error: Unacceptable certificate: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB.
E/WSRTCClient: HTTP POST to https://appr.tc/join/E52U8KA error: Unacceptable certificate: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.UiThread;
import com.skillatwill.skillatwill.R;
import org.appspot.apprtc.AppRTCClient;
import org.appspot.apprtc.PeerConnectionClient;
import org.appspot.apprtc.WebSocketRTCClient;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator;
import org.webrtc.IceCandidate;
import org.webrtc.Logging;
import org.webrtc.RendererCommon.ScalingType;
import org.webrtc.SessionDescription;
import org.webrtc.StatsReport;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoFrame;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoSink;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
/**
* Activity for peer connection call setup, call waiting
* and call view.
*/
public class CallActivity extends Activity implements AppRTCClient.SignalingEvents,
PeerConnectionClient.PeerConnectionEvents {
private static final String TAG = "CallActivity";
private static final String APPRTC_URL = "https://appr.tc";
private static final String UPPER_ALPHA_DIGITS = "ACEFGHJKLMNPQRUVWXY123456789";
// Peer connection statistics callback period in ms.
private static final int STAT_CALLBACK_PERIOD = 1000;
private final ProxyRenderer remoteProxyRenderer = new ProxyRenderer();
private final ProxyVideoSink localProxyVideoSink = new ProxyVideoSink();
private final List<VideoRenderer.Callbacks> remoteRenderers = new ArrayList<>();
private PeerConnectionClient peerConnectionClient = null;
private AppRTCClient appRtcClient;
private AppRTCClient.SignalingParameters signalingParameters;
private SurfaceViewRenderer pipRenderer;
private SurfaceViewRenderer fullscreenRenderer;
private Toast logToast;
private boolean activityRunning;
private AppRTCClient.RoomConnectionParameters roomConnectionParameters;
private PeerConnectionClient.PeerConnectionParameters peerConnectionParameters;
private boolean iceConnected;
private boolean isError;
private long callStartedTimeMs = 0;
private boolean micEnabled = true;
private boolean isSwappedFeeds;
// Control buttons for limited UI
private ImageButton disconnectButton;
private ImageButton cameraSwitchButton;
private ImageButton toggleMuteButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
iceConnected = false;
signalingParameters = null;
// Create UI controls.
pipRenderer = findViewById(R.id.pip_video_view);
fullscreenRenderer = findViewById(R.id.fullscreen_video_view);
disconnectButton = findViewById(R.id.button_call_disconnect);
cameraSwitchButton = findViewById(R.id.button_call_switch_camera);
toggleMuteButton = findViewById(R.id.button_call_toggle_mic);
// Add buttons click events.
disconnectButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
onCallHangUp();
}
});
cameraSwitchButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onCameraSwitch();
}
});
toggleMuteButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
boolean enabled = onToggleMic();
toggleMuteButton.setAlpha(enabled ? 1.0f : 0.3f);
}
});
// Swap feeds on pip view click.
pipRenderer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setSwappedFeeds(!isSwappedFeeds);
}
});
remoteRenderers.add(remoteProxyRenderer);
// Create peer connection client.
peerConnectionClient = new PeerConnectionClient();
// Create video renderers.
pipRenderer.init(peerConnectionClient.getRenderContext(), null);
pipRenderer.setScalingType(ScalingType.SCALE_ASPECT_FIT);
fullscreenRenderer.init(peerConnectionClient.getRenderContext(), null);
fullscreenRenderer.setScalingType(ScalingType.SCALE_ASPECT_FILL);
pipRenderer.setZOrderMediaOverlay(true);
pipRenderer.setEnableHardwareScaler(true /* enabled */);
fullscreenRenderer.setEnableHardwareScaler(true /* enabled */);
// Start with local feed in fullscreen and swap it to the pip when the call is connected.
setSwappedFeeds(true /* isSwappedFeeds */);
// Generate a random room ID with 7 uppercase letters and digits
String randomRoomID = randomString(7, UPPER_ALPHA_DIGITS);
// Show the random room ID so that another client can join from https://appr.tc
TextView roomIdTextView = findViewById(R.id.roomID);
roomIdTextView.setText(getString(R.string.room_id_caption) + randomRoomID);
Log.d(TAG, getString(R.string.room_id_caption) + randomRoomID);
// Connect video call to the random room
connectVideoCall(randomRoomID);
}
// Create a random string
private String randomString(int length, String characterSet) {
StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
for (int i = 0; i < length; i++) {
int randomInt = new SecureRandom().nextInt(characterSet.length());
sb.append(characterSet.substring(randomInt, randomInt + 1));
}
return sb.toString();
}
// Join video call with randomly generated roomId
private void connectVideoCall(String roomId) {
Uri roomUri = Uri.parse(APPRTC_URL);
int videoWidth = 0;
int videoHeight = 0;
peerConnectionParameters =
new PeerConnectionClient.PeerConnectionParameters(true,
false,
false,
videoWidth,
videoHeight,
0,
Integer.parseInt(getString(R.string.pref_maxvideobitratevalue_default)),
getString(R.string.pref_videocodec_default),
true,
false,
Integer.parseInt(getString(R.string.pref_startaudiobitratevalue_default)),
getString(R.string.pref_audiocodec_default),
false,
false,
false,
false,
false,
false,
false,
false,
null);
// Create connection client. Use the standard WebSocketRTCClient.
// DirectRTCClient could be used for point-to-point connection
appRtcClient = new WebSocketRTCClient(this);
// Create connection parameters.
roomConnectionParameters =
new AppRTCClient.RoomConnectionParameters(
roomUri.toString(),
roomId,
false,
null);
peerConnectionClient.createPeerConnectionFactory(
getApplicationContext(), peerConnectionParameters, CallActivity.this);
startCall();
}
public void onCallHangUp() {
disconnect();
}
public void onCameraSwitch() {
if (peerConnectionClient != null) {
peerConnectionClient.switchCamera();
}
}
public boolean onToggleMic() {
if (peerConnectionClient != null) {
micEnabled = !micEnabled;
peerConnectionClient.setAudioEnabled(micEnabled);
}
return micEnabled;
}
private void startCall() {
if (appRtcClient == null) {
Log.e(TAG, "AppRTC client is not allocated for a call.");
return;
}
callStartedTimeMs = System.currentTimeMillis();
// Start room connection.
logAndToast(getString(R.string.connecting_to, roomConnectionParameters.roomUrl));
appRtcClient.connectToRoom(roomConnectionParameters);
}
#UiThread
private void callConnected() {
final long delta = System.currentTimeMillis() - callStartedTimeMs;
Log.i(TAG, "Call connected: delay=" + delta + "ms");
if (peerConnectionClient == null || isError) {
Log.w(TAG, "Call is connected in closed or error state");
return;
}
// Enable statistics callback.
peerConnectionClient.enableStatsEvents(true, STAT_CALLBACK_PERIOD);
setSwappedFeeds(false /* isSwappedFeeds */);
}
// Disconnect from remote resources, dispose of local resources, and exit.
private void disconnect() {
activityRunning = false;
remoteProxyRenderer.setTarget(null);
localProxyVideoSink.setTarget(null);
if (appRtcClient != null) {
appRtcClient.disconnectFromRoom();
appRtcClient = null;
}
if (pipRenderer != null) {
pipRenderer.release();
pipRenderer = null;
}
if (fullscreenRenderer != null) {
fullscreenRenderer.release();
fullscreenRenderer = null;
}
if (peerConnectionClient != null) {
peerConnectionClient.close();
peerConnectionClient = null;
}
if (iceConnected && !isError) {
setResult(RESULT_OK);
} else {
setResult(RESULT_CANCELED);
}
finish();
}
private void disconnectWithErrorMessage(final String errorMessage) {
if (!activityRunning) {
Log.e(TAG, "Critical error: " + errorMessage);
disconnect();
} else {
new AlertDialog.Builder(this)
.setTitle(getText(R.string.channel_error_title))
.setMessage(errorMessage)
.setCancelable(false)
.setNeutralButton(R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
disconnect();
}
})
.create()
.show();
}
}
// Log |msg| and Toast about it.
private void logAndToast(String msg) {
Log.d(TAG, msg);
if (logToast != null) {
logToast.cancel();
}
logToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
logToast.show();
}
private void reportError(final String description) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (!isError) {
isError = true;
disconnectWithErrorMessage(description);
}
}
});
}
// Create VideoCapturer
private VideoCapturer createVideoCapturer() {
final VideoCapturer videoCapturer;
Logging.d(TAG, "Creating capturer using camera2 API.");
videoCapturer = createCameraCapturer(new Camera2Enumerator(this));
if (videoCapturer == null) {
reportError("Failed to open camera");
return null;
}
return videoCapturer;
}
// Create VideoCapturer from camera
private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
final String[] deviceNames = enumerator.getDeviceNames();
// First, try to find front facing camera
Logging.d(TAG, "Looking for front facing cameras.");
for (String deviceName : deviceNames) {
if (enumerator.isFrontFacing(deviceName)) {
Logging.d(TAG, "Creating front facing camera capturer.");
VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
if (videoCapturer != null) {
return videoCapturer;
}
}
}
// Front facing camera not found, try something else
Logging.d(TAG, "Looking for other cameras.");
for (String deviceName : deviceNames) {
if (!enumerator.isFrontFacing(deviceName)) {
Logging.d(TAG, "Creating other camera capturer.");
VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
if (videoCapturer != null) {
return videoCapturer;
}
}
}
return null;
}
private void setSwappedFeeds(boolean isSwappedFeeds) {
Logging.d(TAG, "setSwappedFeeds: " + isSwappedFeeds);
this.isSwappedFeeds = isSwappedFeeds;
localProxyVideoSink.setTarget(isSwappedFeeds ? fullscreenRenderer : pipRenderer);
remoteProxyRenderer.setTarget(isSwappedFeeds ? pipRenderer : fullscreenRenderer);
fullscreenRenderer.setMirror(isSwappedFeeds);
pipRenderer.setMirror(!isSwappedFeeds);
}
// -----Implementation of AppRTCClient.AppRTCSignalingEvents ---------------
// All callbacks are invoked from websocket signaling looper thread and
// are routed to UI thread.
private void onConnectedToRoomInternal(final AppRTCClient.SignalingParameters params) {
final long delta = System.currentTimeMillis() - callStartedTimeMs;
signalingParameters = params;
logAndToast("Creating peer connection, delay=" + delta + "ms");
VideoCapturer videoCapturer = null;
if (peerConnectionParameters.videoCallEnabled) {
videoCapturer = createVideoCapturer();
}
peerConnectionClient.createPeerConnection(
localProxyVideoSink, remoteRenderers, videoCapturer, signalingParameters);
if (signalingParameters.initiator) {
logAndToast("Creating OFFER...");
// Create offer. Offer SDP will be sent to answering client in
// PeerConnectionEvents.onLocalDescription event.
peerConnectionClient.createOffer();
} else {
if (params.offerSdp != null) {
peerConnectionClient.setRemoteDescription(params.offerSdp);
logAndToast("Creating ANSWER...");
// Create answer. Answer SDP will be sent to offering client in
// PeerConnectionEvents.onLocalDescription event.
peerConnectionClient.createAnswer();
}
if (params.iceCandidates != null) {
// Add remote ICE candidates from room.
for (IceCandidate iceCandidate : params.iceCandidates) {
peerConnectionClient.addRemoteIceCandidate(iceCandidate);
}
}
}
}
#Override
public void onConnectedToRoom(final AppRTCClient.SignalingParameters params) {
runOnUiThread(new Runnable() {
#Override
public void run() {
onConnectedToRoomInternal(params);
}
});
}
#Override
public void onRemoteDescription(final SessionDescription sdp) {
final long delta = System.currentTimeMillis() - callStartedTimeMs;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (peerConnectionClient == null) {
Log.e(TAG, "Received remote SDP for non-initilized peer connection.");
return;
}
logAndToast("Received remote " + sdp.type + ", delay=" + delta + "ms");
peerConnectionClient.setRemoteDescription(sdp);
if (!signalingParameters.initiator) {
logAndToast("Creating ANSWER...");
// Create answer. Answer SDP will be sent to offering client in
// PeerConnectionEvents.onLocalDescription event.
peerConnectionClient.createAnswer();
}
}
});
}
#Override
public void onRemoteIceCandidate(final IceCandidate candidate) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (peerConnectionClient == null) {
Log.e(TAG, "Received ICE candidate for a non-initialized peer connection.");
return;
}
peerConnectionClient.addRemoteIceCandidate(candidate);
}
});
}
#Override
public void onRemoteIceCandidatesRemoved(final IceCandidate[] candidates) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (peerConnectionClient == null) {
Log.e(TAG, "Received ICE candidate removals for a non-initialized peer connection.");
return;
}
peerConnectionClient.removeRemoteIceCandidates(candidates);
}
});
}
#Override
public void onChannelClose() {
runOnUiThread(new Runnable() {
#Override
public void run() {
logAndToast("Remote end hung up; dropping PeerConnection");
disconnect();
}
});
}
#Override
public void onChannelError(final String description) {
reportError(description);
}
// -----Implementation of PeerConnectionClient.PeerConnectionEvents.---------
// Send local peer connection SDP and ICE candidates to remote party.
// All callbacks are invoked from peer connection client looper thread and
// are routed to UI thread.
#Override
public void onLocalDescription(final SessionDescription sdp) {
final long delta = System.currentTimeMillis() - callStartedTimeMs;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (appRtcClient != null) {
logAndToast("Sending " + sdp.type + ", delay=" + delta + "ms");
if (signalingParameters.initiator) {
appRtcClient.sendOfferSdp(sdp);
} else {
appRtcClient.sendAnswerSdp(sdp);
}
}
if (peerConnectionParameters.videoMaxBitrate > 0) {
Log.d(TAG, "Set video maximum bitrate: " + peerConnectionParameters.videoMaxBitrate);
peerConnectionClient.setVideoMaxBitrate(peerConnectionParameters.videoMaxBitrate);
}
}
});
}
#Override
public void onIceCandidate(final IceCandidate candidate) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (appRtcClient != null) {
appRtcClient.sendLocalIceCandidate(candidate);
}
}
});
}
#Override
public void onIceCandidatesRemoved(final IceCandidate[] candidates) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (appRtcClient != null) {
appRtcClient.sendLocalIceCandidateRemovals(candidates);
}
}
});
}
#Override
public void onIceConnected() {
final long delta = System.currentTimeMillis() - callStartedTimeMs;
runOnUiThread(new Runnable() {
#Override
public void run() {
logAndToast("ICE connected, delay=" + delta + "ms");
iceConnected = true;
callConnected();
}
});
}
#Override
public void onIceDisconnected() {
runOnUiThread(new Runnable() {
#Override
public void run() {
logAndToast("ICE disconnected");
iceConnected = false;
disconnect();
}
});
}
#Override
public void onPeerConnectionClosed() {
}
#Override
public void onPeerConnectionStatsReady(final StatsReport[] reports) {
}
#Override
public void onPeerConnectionError(final String description) {
reportError(description);
}
// Activity interfaces
#Override
public void onStop() {
super.onStop();
activityRunning = false;
if (peerConnectionClient != null) {
peerConnectionClient.stopVideoSource();
}
}
#Override
public void onStart() {
super.onStart();
activityRunning = true;
// Video is not paused for screencapture. See onPause.
if (peerConnectionClient != null) {
peerConnectionClient.startVideoSource();
}
}
#Override
protected void onDestroy() {
Thread.setDefaultUncaughtExceptionHandler(null);
disconnect();
if (logToast != null) {
logToast.cancel();
}
activityRunning = false;
super.onDestroy();
}
private static class ProxyRenderer implements VideoRenderer.Callbacks {
private VideoRenderer.Callbacks target;
#Override
synchronized public void renderFrame(VideoRenderer.I420Frame frame) {
if (target == null) {
Logging.d(TAG, "Dropping frame in proxy because target is null.");
VideoRenderer.renderFrameDone(frame);
return;
}
target.renderFrame(frame);
}
synchronized public void setTarget(VideoRenderer.Callbacks target) {
this.target = target;
}
}
private static class ProxyVideoSink implements VideoSink {
private VideoSink target;
#Override
synchronized public void onFrame(VideoFrame frame) {
if (target == null) {
Logging.d(TAG, "Dropping frame in proxy because target is null.");
return;
}
target.onFrame(frame);
}
synchronized public void setTarget(VideoSink target) {
this.target = target;
}
}
}

You are using a demo signaling server operated by an entity (Google) that does not consider this demo signaling server a production system. The certificate expired a week ago.
Run your own server, instructions can be found here: https://github.com/webrtc/apprtc

Related

How can we add referer in the exoplayer android java

I want to play this link but i m unable to play this link in my exoplayer
I will be able to play this link only when this referer will be added in the exoplayer but i m unable to add this referer. I dont know how can i add this referer to my exoplayer
Referer: http://nbajunkie.xyz/jp1/
https://reels2watch.com/hls/s1.m3u8
dataSourceFactory.getDefaultRequestProperties().set("Referer", "https://yourdomain.com");
I dont know how to add this referer in the header can someone help me about it or Anyone can do it for me ? Because i don’t know much about java kindly let me know how to solve this issue.
import static com.google.android.exoplayer2.util.Util.getUserAgent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.media.session.PlaybackStateCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.mediarouter.app.MediaRouteButton;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Util;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaLoadOptions;
import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.cast.framework.CastButtonFactory;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.cast.framework.CastSession;
import com.google.android.gms.cast.framework.CastState;
import com.google.android.gms.cast.framework.CastStateListener;
import com.google.android.gms.cast.framework.SessionManagerListener;
import com.google.android.gms.cast.framework.media.RemoteMediaClient;
import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.FirebaseFirestore;
import com.Myapp.hd.Steaming.R;
import com.Myapp.hd.Steaming.HelperClass;
import com.Myapp.hd.Steaming.BaseActivity;
import com.Myapp.hd.Steaming.Location;
import com.Myapp.hd.Steaming.sessionManager.SessionManager;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class Exo_Player extends BaseActivity {
private static final String TAG = "Exo_Player";
String url, userAgent;
boolean tokenEnable = false;
private InterstitialAd interstitial;
private PlayerView playerView;
private SimpleExoPlayer player;
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private DataSource.Factory mediaDataSourceFactory;
private Handler mainHandler;
private ProgressBar progressBar;
FirebaseFirestore db;
SessionManager sessionManager;
FirebaseFirestore firebaseFirestore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
//////////////////////////////////////////////////////
setContentView(R.layout.exo_player_ui);
castContext = CastContext.getSharedInstance(this);
initCast();
db = FirebaseFirestore.getInstance();
sessionManager = new SessionManager(this);
FirebaseApp.initializeApp(this);
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(Exo_Player.this, sessionManager.getBackads(), adRequest,
new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
interstitial = interstitialAd;
Log.i(TAG, "onAdLoaded");
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
// Handle the error
Log.i(TAG, loadAdError.getMessage());
interstitial = null;
}
});
progressBar = findViewById(R.id.progressBar);
processToken();
listenCast();
}
MediaRouteButton mediaRouteButton;
CastContext castContext;
RemoteMediaClient remoteMediaClient;
public boolean initCast() {
url = getIntent().getStringExtra(getString(R.string.url));
userAgent = getIntent().getStringExtra(getString(R.string.user_agent));
tokenEnable = getIntent().getBooleanExtra(getString(R.string.t_enable), false);
mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), mediaRouteButton);
if (castContext == null)
castContext = CastContext.getSharedInstance(this);
castContext.addCastStateListener(new CastStateListener() {
#Override
public void onCastStateChanged(int state) {
/*if (state == CastState.NO_DEVICES_AVAILABLE) {
// mediaRouteButton.setVisibility(View.GONE);
}
else if(state==CastState.CONNECTING) {
showToast("Connecting");
} else*/ if (state == CastState.CONNECTED) {
// showToast("Connected");
// castMetadata();
openCastPlayer();
}/* else if (mediaRouteButton.getVisibility() == View.GONE) {
mediaRouteButton.setVisibility(View.VISIBLE);
}*/
}
});
if (castContext.getCastState() == CastState.CONNECTED) {
openCastPlayer();
return true;
} else {
// showToast("not connected");
}
if (castContext.getCastState() != CastState.NO_DEVICES_AVAILABLE)
mediaRouteButton.setVisibility(View.VISIBLE);
return false;
}
private void registerListener() {
if (mCastContext != null) {
mCastContext.getSessionManager().addSessionManagerListener(
mSessionManagerListener, CastSession.class);
}
}
private void unRegisterListener() {
if (mCastContext != null) {
mCastContext.getSessionManager().removeSessionManagerListener(
mSessionManagerListener, CastSession.class);
}
}
private void showToast(String connecting) {
Toast.makeText(this, connecting, Toast.LENGTH_SHORT).show();
}
private void processToken() {
if (!HelperClass.isValid(url) || !tokenEnable) {
init("");
return;
}
HashMap<String, Object> hashMap = new HashMap<>();
enqueue(getLocInterface().getLoc(sessionManager.getToken(), hashMap), new CallBack<Location>() {
#Override
public void onComplete() {
super.onComplete();
}
#Override
public void onError(Throwable e) {
super.onError(e);
Toast.makeText(Exo_Player.this,
"Failed to process url", Toast.LENGTH_SHORT).show();
}
#Override
public void onNext(#NotNull Location location) {
super.onNext(location);
if (location.appendResult != null)
init(location.appendResult);
}
});
}
private void init(String s) {
url += s;
Log.e(TAG, "init: new url is " + url);
mediaDataSourceFactory = buildDataSourceFactory(true);
mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
RenderersFactory renderersFactory = new DefaultRenderersFactory(this);
// TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
// TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// TrackSelector trackSelector = new DefaultTrackSelector();
LoadControl loadControl = new DefaultLoadControl();
player = new SimpleExoPlayer.Builder(this, renderersFactory).setLoadControl(loadControl).build();
playerView = findViewById(R.id.exoPlayerView);
playerView.setPlayer(player);
playerView.setUseController(true);
playerView.requestFocus();
Uri uri = Uri.parse(url);
final MediaSource mediaSource = buildMediaSource(uri, null);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
player.addListener(new Player.Listener() {
#Override
public void onTracksChanged(#NotNull TrackGroupArray trackGroups, #NotNull TrackSelectionArray trackSelections) {
Log.d(TAG, "onTracksChanged: " + trackGroups.length);
}
#Override
public void onIsLoadingChanged(boolean isLoading) {
Log.d(TAG, "onLoadingChanged: " + isLoading);
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.d(TAG, "onPlayerStateChanged: " + playWhenReady);
if (playbackState == PlaybackStateCompat.STATE_PLAYING) {
progressBar.setVisibility(View.GONE);
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(#NotNull PlaybackException error) {
Log.e(TAG, "onPlayerError: ", error);
player.stop();
// errorDialog();
player.prepare(mediaSource);
player.setPlayWhenReady(true);
}
#Override
public void onPositionDiscontinuity(int reason) {
Log.d(TAG, "onPositionDiscontinuity: true");
}
#Override
public void onPlaybackParametersChanged(#NotNull PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
Log.d("INFO", "ActivityVideoPlayer");
}
private void pausePlayer() {
player.setPlayWhenReady(false);
player.getPlaybackState();
}
private void startPlayer() {
player.setPlayWhenReady(true);
player.getPlaybackState();
}
#Override
protected void onPause() {
super.onPause();
try {
unRegisterListener();
pausePlayer();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
/////////////////////////////////////////////
try {
registerListener();
if (HelperClass.vpn(this)) {
finish();
}
startPlayer();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.v(TAG, "onDestroy()...");
if (player != null)
player.release();
}
private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
int type = TextUtils.isEmpty(overrideExtension) ? Util.inferContentType(uri)
: Util.inferContentType("." + overrideExtension);
switch (type) {
case C.TYPE_SS:
return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory(mediaDataSourceFactory), buildDataSourceFactory(false)).createMediaSource(uri);
case C.TYPE_DASH:
return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(mediaDataSourceFactory), buildDataSourceFactory(false)).createMediaSource(uri);
case C.TYPE_HLS:
return new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
case C.TYPE_OTHER:
return new ProgressiveMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
default: {
throw new IllegalStateException("Unsupported type: " + type);
}
}
}
private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) {
return buildDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
}
public DataSource.Factory buildDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) {
return new DefaultDataSourceFactory(this, bandwidthMeter,
buildHttpDataSourceFactory(bandwidthMeter));
}
public HttpDataSource.Factory buildHttpDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) {
String s = "xxxxx";
if (userAgent != null && !userAgent.isEmpty()) {
s = userAgent;
}
return new DefaultHttpDataSourceFactory(getUserAgent2(this, s), bandwidthMeter);
}
public static String getUserAgent2(Context context, String applicationName) {
return applicationName
+ "";
}
#Override
public void onBackPressed() {
super.onBackPressed();
if (interstitial != null) {
interstitial.show(Exo_Player.this);
}
if (player != null)
player.stop();
}
// public void errorDialog() {
// new AlertDialog.Builder(this)
// .setIcon(android.R.drawable.ic_dialog_alert)
// .setTitle(getResources().getString(R.string.msg_oops))
// .setCancelable(false)
// .setMessage(getResources().getString(R.string.msg_failed))
// .setPositiveButton(getResources().getString(R.string.option_retry), new DialogInterface.OnClickListener() {
// #Override
// public void onClick(DialogInterface dialog, int which) {
// retryLoad();
// z }
//
// })
// .setNegativeButton(getResources().getString(R.string.option_no), new DialogInterface.OnClickListener() {
// #Override
// public void onClick(DialogInterface dialogInterface, int i) {
// finish();
// }
// })
// .show();
// }
// public void retryLoad() {
// Uri uri = Uri.parse(url);
// MediaSource mediaSource = buildMediaSource(uri, null);
// player.prepare(mediaSource);
// player.setPlayWhenReady(true);
// }
public void castplayer(String name, String link, String unique, String img) {
if (!isCastApiAvailable()) {
return;
}
Context context = this;
CastSession castSession = CastContext.getSharedInstance(context).getSessionManager()
.getCurrentCastSession();
if (castSession.isConnected()) {
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_GENERIC);
movieMetadata.putString(MediaMetadata.KEY_TITLE, name);
MediaInfo mediaInfo = new MediaInfo.Builder(link)
.setMetadata(movieMetadata)
.setEntity(unique)
.build();
final RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
if (remoteMediaClient == null) {
// Timber.tag(TAG).w("showQueuePopup(): null RemoteMediaClient");
return;
}
if (remoteMediaClient.isPlaying()) {
MediaInfo curMedia = remoteMediaClient.getMediaInfo();
if (curMedia != null && curMedia.getEntity().equals(unique)) {
return;
}
}
if (remoteMediaClient.isLoadingNextItem() || remoteMediaClient.isBuffering()) {
return;
}
// final QueueDataProvider provider = QueueDataProvider.getInstance(context);
// PopupMenu popup = new PopupMenu(context, binding.epLayout);
// popup.getMenuInflater().inflate(
// provider.isQueueDetached() || provider.getCount() == 0
// ? R.menu.detached_popup_add_to_queue
// : R.menu.popup_add_to_queue, popup.getMenu());
// PopupMenu.OnMenuItemClickListener clickListener = menuItem -> {
// QueueDataProvider provider1 = QueueDataProvider.getInstance(context);
// MediaQueueItem queueItem = new MediaQueueItem.Builder(mediaInfo).setAutoplay(
// false).setPreloadTime(2).build();
// MediaQueueItem[] newItemArray = new MediaQueueItem[]{queueItem};
// String toastMessage = null;
// if (provider1.isQueueDetached() && provider1.getCount() > 0) {
// if ((menuItem.getItemId() == R.id.action_play_now)
// || (menuItem.getItemId() == R.id.action_add_to_queue)) {
// MediaQueueItem[] items = Utils
// .rebuildQueueAndAppend(provider1.getItems(), queueItem);
// remoteMediaClient.queueLoad(items, provider1.getCount(),
// MediaStatus.REPEAT_MODE_REPEAT_OFF, null);
// } else {
// return false;
// }
// } else {
// if (provider1.getCount() == 0) {
// remoteMediaClient.queueLoad(newItemArray, 0,
// MediaStatus.REPEAT_MODE_REPEAT_OFF, null);
// } else {
// int currentId = provider1.getCurrentItemId();
//// if (menuItem.getItemId() == R.id.action_play_now) {
// remoteMediaClient.queueInsertAndPlayItem(queueItem, currentId, null);
remoteMediaClient.load(mediaInfo, new MediaLoadOptions.Builder().build());
// } else if (menuItem.getItemId() == R.id.action_play_next) {
// int currentPosition = provider1.getPositionByItemId(currentId);
// if (currentPosition == provider1.getCount() - 1) {
// //we are adding to the end of queue
// remoteMediaClient.queueAppendItem(queueItem, null);
// } else {
// int nextItemId = provider1.getItem(currentPosition + 1).getItemId();
// remoteMediaClient.queueInsertItems(newItemArray, nextItemId, null);
// }
// toastMessage = context.getString(
// R.string.queue_item_added_to_play_next);
// } else if (menuItem.getItemId() == R.id.action_add_to_queue) {
// remoteMediaClient.queueAppendItem(queueItem, null);
// toastMessage = context.getString(R.string.queue_item_added_to_queue);
// } else {
// return false;
// }
// }
// }
// if (menuItem.getItemId() == R.id.action_play_now) {
Intent intent = new Intent(context, ExpandedControlsActivity.class);
context.startActivity(intent);
// }
// if (!TextUtils.isEmpty(toastMessage)) {
// Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show();
// }
// return true;
// };
// popup.setOnMenuItemClickListener(clickListener);
// popup.show();
// }
} else {
Toast.makeText(context,
"Not Connected", Toast.LENGTH_SHORT).show();
}
}
private CastContext mCastContext;
private CastSession mCastSession;
private SessionManagerListener<CastSession> mSessionManagerListener;
private void listenCast() {
if (!isCastApiAvailable()) {
return;
}
setupCastListener();
mCastContext = CastContext.getSharedInstance(this);
mCastSession = mCastContext.getSessionManager().getCurrentCastSession();
}
private void setupCastListener() {
mSessionManagerListener = new SessionManagerListener<CastSession>() {
#Override
public void onSessionEnded(CastSession session, int error) {
onApplicationDisconnected();
mCastContext = null;
mCastSession = null;
}
#Override
public void onSessionResumed(CastSession session, boolean wasSuspended) {
onApplicationConnected(session);
}
#Override
public void onSessionResumeFailed(CastSession session, int error) {
onApplicationDisconnected();
}
#Override
public void onSessionStarted(CastSession session, String sessionId) {
onApplicationConnected(session);
}
#Override
public void onSessionStartFailed(CastSession session, int error) {
onApplicationDisconnected();
}
#Override
public void onSessionStarting(CastSession session) {
}
#Override
public void onSessionEnding(CastSession session) {
}
#Override
public void onSessionResuming(CastSession session, String sessionId) {
}
#Override
public void onSessionSuspended(CastSession session, int reason) {
}
private void onApplicationConnected(CastSession castSession) {
mCastSession = castSession;
openCastPlayer();
invalidateOptionsMenu();
}
private void onApplicationDisconnected() {
invalidateOptionsMenu();
}
};
}
private void openCastPlayer() {
castplayer(getString(R.string.app_name), url, url, url);
finish();
}
}
I remember that was changed with the newer updates at some point last year. Now you need to pass a map to setDefaultRequestProperties after building a HttpDataSource. Using a DefaultHttpDataSource.Factory should be enough if you are not considering using a custom one.

Android MIDI Threading InteruptedException - Aftertouch Messages

Trying to run MIDI on my Android app. I'm following the midisuite example to configure my app and it works fine with the exception of aftertouch. Whenever I try to trigger aftertouch, I run into a threading exception type
InteruptedException. How should I prevent this threading issue? My knowledge on multithreading isn't the best or else I would've figured this out already. All I can really tell right now is that the message is sending too fast and the thread hasn't woken up yet from its sleep call.
I followed the github repo with my code as follows:
MidiReceiver subclass:
#TargetApi(Build.VERSION_CODES.M)
public class MidiEngine extends MidiReceiver {
public AudioActivity activity;
private MidiEventScheduler eventScheduler;
private MidiFramer midiFramer;
private MidiReceiver midiReceiver = new MyReceiver();
private Thread mThread;
private boolean go;
private int mProgram;
public MidiEngine() {
this(new AudioActivity());
}
public MidiEngine(AudioActivity activity) {
this.activity = activity;
midiReceiver = new MyReceiver();
midiFramer = new MidiFramer(midiReceiver);
}
public AudioActivity getActivity() {
return this.activity;
}
/* This will be called when MIDI data arrives. */
#Override
public void onSend(byte[] data, int offset, int count, long timestamp)
throws IOException {
if (eventScheduler != null) {
if (!MidiConstants.isAllActiveSensing(data, offset, count)) {
eventScheduler.getReceiver().send(data, offset, count,
timestamp);
}
}
}
// Custom Listener to send to correct methods
private class MyReceiver extends MidiReceiver {
#Override
public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
byte command = (byte)(msg[0] & MidiConstants.STATUS_COMMAND_MASK);
int channel = (byte)(msg[0] & MidiConstants.STATUS_CHANNEL_MASK);
switch (command) {
case MidiConstants.STATUS_NOTE_ON:
activity.keyDown(i, msg[1], msg[2]);
break;
case MidiConstants.STATUS_NOTE_OFF:
activity.keyUp(channel, msg[1]);
break;
case MidiConstants.STATUS_POLYPHONIC_AFTERTOUCH:
activity.keyDown(channel, msg[1], msg[2]);
break;
case MidiConstants.STATUS_PITCH_BEND:
activity.pitchBendAction(channel, (msg[2] << 7) + msg[1]);
break;
case MidiConstants.STATUS_CONTROL_CHANGE:
activity.ccAction(channel, msg[1], msg[2]);
break;
case MidiConstants.STATUS_PROGRAM_CHANGE:
mProgram = msg[1];
break;
default:
break;
}
}
}
class MyRunnable implements Runnable {
#Override
public void run() {
do {
try {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
processMidiEvents();
}
catch (Exception e) {
Log.e("Java", "SynthEngine background thread exception.", e);
}
}
});
Thread.sleep(100);
}
catch (InterruptedException e) {
Log.e("Java", "Threading exception", e);
}
}
while (go);
}
}
/**
* #throws IOException
*
*/
private void processMidiEvents() throws IOException {
long now = System.nanoTime();
MidiEventScheduler.MidiEvent event = (MidiEventScheduler.MidiEvent) eventScheduler.getNextEvent(now);
while (event != null) {
midiFramer.send(event.data, 0, event.count, event.getTimestamp());
eventScheduler.addEventToPool(event);
event = (MidiEventScheduler.MidiEvent) eventScheduler.getNextEvent(now);
}
}
public void start() {
stop();
go = true;
mThread = new Thread(new MyRunnable());
mThread.setPriority(6);
eventScheduler = new MidiEventScheduler();
mThread.start();
}
public void stop() {
go = false;
if (mThread != null) {
try {
mThread.interrupt();
mThread.join(500);
}
catch (Exception e) {
}
mThread = null;
eventScheduler = null;
}
}
}
Stack Trace Error (line 154 refers to the Thread.sleep part in my custom Runnable class):
Java: Threading exception
java.lang.InterruptedException
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:1031)
at java.lang.Thread.sleep(Thread.java:985)
at com.rfoo.midiapp.communication.MidiEngineInput$MyRunnable.run(MidiEngineInput.java:154)
at java.lang.Thread.run(Thread.java:818)
Thanks!
EDIT: Thread start
Midi Device Service subclass (thread will start whenever a device has connected or disconnected).
#TargetApi(Build.VERSION_CODES.M)
public class MidiSynthDeviceService extends MidiDeviceService {
private static final String TAG = "MidiSynthDeviceService";
private boolean midiStarted = false;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
AudioActivity.midiEngine.stop();
super.onDestroy();
}
#Override
// Declare the receivers associated with your input ports.
public MidiReceiver[] onGetInputPortReceivers() {
return new MidiReceiver[] { AudioActivity.midiEngine };
}
/**
* This will get called when clients connect or disconnect.
* You can use it to turn on your synth only when needed.
*/
#Override
public void onDeviceStatusChanged(MidiDeviceStatus status) {
if (status.isInputPortOpen(0) && !midiStarted) {
AudioActivity.midiEngine.start();
midiStarted = true;
} else if (!status.isInputPortOpen(0) && midiStarted){
AudioActivity.midiEngine.stop();
midiStarted = false;
}
}
}
Activity class:
public class AudioActivity extends AppCompatActivity {
private Thread thread;
public static MidiEngine midiEngine;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Layout inits
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Setup MIDI:
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI)) {
Toast.makeText(this, "MIDI not supported!", Toast.LENGTH_LONG).show();
}
else {
midiEngine = new MidiEngine(this);
setupMidi();
}
// Setup audio thread:
if (thread == null) {
thread = new Thread() {
public void run() {
setPriority(Thread.MAX_PRIORITY);
// Runs an Open SL audio thread (C++)
// This generates a waveform.
// AudioEngine is a wrapper class connecting C++ to Java
AudioEngine.runProcess();
}
}
}
}
public void setupMidi() {
if (activity == null) activity = (AudioActivity) getContext();
mMidiManager = (MidiManager) activity.getSystemService(AudioActivity.MIDI_SERVICE);
if (mMidiManager == null) {
Toast.makeText(activity, "MidiManager is null!", Toast.LENGTH_LONG).show();
return;
}
// Get Device Info
MidiDeviceInfo deviceInfo = MidiTools.findDevice(mMidiManager, "RFOO", "AudioApp");
// MIDI Input
portIndex = 0;
inputPortSelector = new MidiOutputPortConnectionSelector(mMidiManager, activity, R.id
.inputListView, deviceInfo, portIndex);
inputPortSelector.setConnectedListener(new MyPortsConnectedListener());
midi_ch_input = 0;
midi_ch_output = 0;
}
// Bunch of UI code here....
}

Trying to develop an in Android, MediaPlayer plays two songs ath the same time

I'm new to Android app developing, and I've tried to program a very simple app: each time the headphone cable is inserted it will play a random song from the collection, and stop whenever the headphone cable is disconnected.
However, I now face a very strange problem: no matter what I do, the app plays always two songs at the same time.
It's very strange because I tried to synchronize everything but it didn't solve the issue...
Here follows my code. Thanks in advance for any help!
public class MainActivity extends AppCompatActivity {
private int countMusic;
private boolean headphones= false;
private HeadphonePlugReceiver receiver;
private HashMap<Integer, String> playing_title;
private RandomPlayer player;
Object lock = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playing_title = new HashMap<>();
scanAgain();
Button scanButton = (Button)findViewById(R.id.scan_again);
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
scanAgain();
}
});
updateStatus();
receiver = new HeadphonePlugReceiver();
registerReceiver(receiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
}
private void updateStatus() {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView statusTextView = (TextView)findViewById(R.id.status);
TextView titleTextView = (TextView)findViewById(R.id.title);
if (headphones) {
statusTextView.setText("Headphones connected!");
String txt = "";
for (Integer cd: playing_title.keySet()) {
txt += String.format("%d: %s ### ", cd, playing_title.get(cd).replace("_", " "));
}
titleTextView.setText(txt);
} else {
statusTextView.setText("Headphones not connected.");
titleTextView.setText("Music not playing");
}
}
});
}
private void addDebug(final String code) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView debugTextView = (TextView)findViewById(R.id.debug);
String dbg = String.format("%s \n %s", debugTextView.getText(), code);
debugTextView.setText(dbg);
}
});
}
private void addError(final String msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView errorTextView = (TextView)findViewById(R.id.error);
errorTextView.setText(msg);
}
});
}
private void startPlayer() {
if (player == null) {
player = new RandomPlayer(this);
player.start();
}
}
private void stopPlayer() {
if (player != null) {
player.interr();
player = null;
}
}
private void scanAgain() {
try {
TextView countTextView = (TextView)findViewById(R.id.count);
countTextView.setText("Scanning... ");
countMusic = scanMusic().getCount();
countTextView.setText(String.format("Music file found: %d", countMusic));
}
catch(Exception e) {
Log.e("problem", e.getMessage());
}
}
public Cursor scanMusic() {
ContentResolver cr = this.getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
String[] projection = {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.TITLE_KEY
};
Cursor cur = cr.query(uri, projection, selection, null, sortOrder);
return cur;
}
private class HeadphonePlugReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
synchronized (lock) {
int state = intent.getIntExtra("state", 0);
managePlayer(state);
// Log.e("state", String.format("state: %d", state));
}
}
private void managePlayer(int state) {
boolean n_headphones = (state != 0);
if (n_headphones == headphones)
return;
headphones = n_headphones;
if (headphones)
startPlayer();
else
stopPlayer();
}
}
private class RandomPlayer extends Thread implements MediaPlayer.OnCompletionListener {
private final MainActivity act;
private final Random r;
private final int code;
private MediaPlayer mp;
private boolean keep_going = true;
Object lock2 = new Object();
public RandomPlayer(MainActivity mainActivity) {
r = new Random(System.currentTimeMillis());
act = mainActivity;
code = r.nextInt(10000);
}
public void onCompletion(MediaPlayer arg0) {
playNext();
}
#Override
public void run() {
playNext();
while (keep_going) {
try {
sleep(100);
} catch (InterruptedException e) {
keep_going = false;
}
}
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
playing_title.remove(code);
updateStatus();
}
public void interr() {
keep_going = false;
}
private void playNext() {
synchronized (lock2) {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
//mp.setVolume(0.9f , 0.9f);
mp.setOnCompletionListener(this);
int chosen = r.nextInt(countMusic);
Cursor cur = scanMusic();
for (int i = 0; i < chosen; i++)
cur.moveToNext();
playing_title.put(code, cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.TITLE)));
try {
int a1 = cur.getColumnIndex(MediaStore.Audio.Media.DATA);
String a2 = cur.getString(a1);
mp.setDataSource(a2);
mp.prepare();
mp.start();
addDebug(a2);
} catch (Exception e) {
Log.e("Randomplayer", "exception", e);
addError(e.getMessage());
}
updateStatus();
}
}
}
}

How to enable next and prev button in medicontroller in android studio

I am following the this ExampleMediaController tutorial.
This is VideoControlView.java,
package com.otwar.deepak.video_styling;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.util.Formatter;
import java.util.Locale;
public class VideoControllerView extends FrameLayout {
private static final String TAG = "VideoControllerView";
private MediaPlayerControl mPlayer;
private Context mContext;
private ViewGroup mAnchor;
private View mRoot;
private ProgressBar mProgress;
private TextView mEndTime, mCurrentTime;
private boolean mShowing;
private boolean mDragging;
private static final int sDefaultTimeout = 3000;
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mUseFastForward;
private boolean mFromXml;
private boolean mListenersSet;
private OnClickListener mNextListener, mPrevListener;
StringBuilder mFormatBuilder;
Formatter mFormatter;
private ImageButton mPauseButton;
private ImageButton mFfwdButton;
private ImageButton mRewButton;
private ImageButton mNextButton;
private ImageButton mPrevButton;
private ImageButton mFullscreenButton;
private Handler mHandler = new MessageHandler(this);
public VideoControllerView(Context context, AttributeSet attrs) {
super(context, attrs);
mRoot = null;
mContext = context;
mUseFastForward = true;
mFromXml = true;
Log.i(TAG, TAG);
}
public VideoControllerView(Context context, boolean useFastForward) {
super(context);
mContext = context;
mUseFastForward = useFastForward;
Log.i(TAG, TAG);
}
public VideoControllerView(Context context) {
this(context, true);
Log.i(TAG, TAG);
}
#Override
public void onFinishInflate() {
if (mRoot != null)
initControllerView(mRoot);
}
public void setMediaPlayer(MediaPlayerControl player) {
mPlayer = player;
updatePausePlay();
updateFullScreen();
}
/**
* Set the view that acts as the anchor for the control view.
* This can for example be a VideoView, or your Activity's main view.
* #param view The view to which to anchor the controller when it is visible.
*/
public void setAnchorView(ViewGroup view) {
mAnchor = view;
LayoutParams frameParams = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
}
/**
* Create the view that holds the widgets that control playback.
* Derived classes can override this to create their own.
* #return The controller view.
* #hide This doesn't work as advertised
*/
protected View makeControllerView() {
LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRoot = inflate.inflate(R.layout.media_controller, null);
initControllerView(mRoot);
return mRoot;
}
private void initControllerView(View v) {
mPauseButton = (ImageButton) v.findViewById(R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
}
mFullscreenButton = (ImageButton) v.findViewById(R.id.fullscreen);
if (mFullscreenButton != null) {
mFullscreenButton.requestFocus();
mFullscreenButton.setOnClickListener(mFullscreenListener);
}
mFfwdButton = (ImageButton) v.findViewById(R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
if (!mFromXml) {
mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);
}
}
mRewButton = (ImageButton) v.findViewById(R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
if (!mFromXml) {
mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);
}
}
// By default these are hidden. They will be enabled when setPrevNextListeners() is called
mNextButton = (ImageButton) v.findViewById(R.id.next);
if (mNextButton != null && !mFromXml && !mListenersSet) {
mNextButton.setVisibility(View.GONE);
}
mPrevButton = (ImageButton) v.findViewById(R.id.prev);
if (mPrevButton != null && !mFromXml && !mListenersSet) {
mPrevButton.setVisibility(View.GONE);
}
mProgress = (ProgressBar) v.findViewById(R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mProgress;
seeker.setOnSeekBarChangeListener(mSeekListener);
}
mProgress.setMax(1000);
}
mEndTime = (TextView) v.findViewById(R.id.time);
mCurrentTime = (TextView) v.findViewById(R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
installPrevNextListeners();
}
/**
* Show the controller on screen. It will go away
* automatically after 3 seconds of inactivity.
*/
public void show() {
show(sDefaultTimeout);
}
/**
* Disable pause or seek buttons if the stream cannot be paused or seeked.
* This requires the control interface to be a MediaPlayerControlExt
*/
private void disableUnsupportedButtons() {
if (mPlayer == null) {
return;
}
try {
if (mPauseButton != null && !mPlayer.canPause()) {
mPauseButton.setEnabled(false);
}
if (mRewButton != null && !mPlayer.canSeekBackward()) {
mRewButton.setEnabled(false);
}
if (mFfwdButton != null && !mPlayer.canSeekForward()) {
mFfwdButton.setEnabled(false);
}
} catch (IncompatibleClassChangeError ex) {
// We were given an old version of the interface, that doesn't have
// the canPause/canSeekXYZ methods. This is OK, it just means we
// assume the media can be paused and seeked, and so we don't disable
// the buttons.
}
}
/**
* Show the controller on screen. It will go away
* automatically after 'timeout' milliseconds of inactivity.
* #param timeout The timeout in milliseconds. Use 0 to show
* the controller until hide() is called.
*/
public void show(int timeout) {
if (!mShowing && mAnchor != null) {
setProgress();
if (mPauseButton != null) {
mPauseButton.requestFocus();
}
disableUnsupportedButtons();
LayoutParams tlp = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM
);
mAnchor.addView(this, tlp);
mShowing = true;
}
updatePausePlay();
updateFullScreen();
// cause the progress bar to be updated even if mShowing
// was already true. This happens, for example, if we're
// paused with the progress bar showing the user hits play.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
Message msg = mHandler.obtainMessage(FADE_OUT);
if (timeout != 0) {
mHandler.removeMessages(FADE_OUT);
mHandler.sendMessageDelayed(msg, timeout);
}
}
public boolean isShowing() {
return mShowing;
}
/**
* Remove the controller from the screen.
*/
public void hide() {
if (mAnchor == null) {
return;
}
try {
mAnchor.removeView(this);
mHandler.removeMessages(SHOW_PROGRESS);
} catch (IllegalArgumentException ex) {
Log.w("MediaController", "already removed");
}
mShowing = false;
}
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
private int setProgress() {
if (mPlayer == null || mDragging) {
return 0;
}
int position = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
if (mProgress != null) {
if (duration > 0) {
// use long to avoid overflow
long pos = 1000L * position / duration;
mProgress.setProgress( (int) pos);
}
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
}
if (mEndTime != null)
mEndTime.setText(stringForTime(duration));
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime(position));
return position;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
show(sDefaultTimeout);
return true;
}
#Override
public boolean onTrackballEvent(MotionEvent ev) {
show(sDefaultTimeout);
return false;
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (mPlayer == null) {
return true;
}
int keyCode = event.getKeyCode();
final boolean uniqueDown = event.getRepeatCount() == 0
&& event.getAction() == KeyEvent.ACTION_DOWN;
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
|| keyCode == KeyEvent.KEYCODE_SPACE) {
if (uniqueDown) {
doPauseResume();
show(sDefaultTimeout);
if (mPauseButton != null) {
mPauseButton.requestFocus();
}
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
if (uniqueDown && !mPlayer.isPlaying()) {
mPlayer.start();
updatePausePlay();
show(sDefaultTimeout);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
|| keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
if (uniqueDown && mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
show(sDefaultTimeout);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
// don't show the controls for volume adjustment
return super.dispatchKeyEvent(event);
} else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
if (uniqueDown) {
hide();
}
return true;
}
show(sDefaultTimeout);
return super.dispatchKeyEvent(event);
}
private OnClickListener mPauseListener = new OnClickListener() {
public void onClick(View v) {
doPauseResume();
show(sDefaultTimeout);
}
};
private OnClickListener mFullscreenListener = new OnClickListener() {
public void onClick(View v) {
doToggleFullscreen();
show(sDefaultTimeout);
}
};
public void updatePausePlay() {
if (mRoot == null || mPauseButton == null || mPlayer == null) {
return;
}
if (mPlayer.isPlaying()) {
mPauseButton.setImageResource(R.drawable.ic_media_pause);
} else {
mPauseButton.setImageResource(R.drawable.ic_media_play);
}
}
public void updateFullScreen() {
if (mRoot == null || mFullscreenButton == null || mPlayer == null) {
return;
}
if (mPlayer.isFullScreen()) {
mFullscreenButton.setImageResource(R.drawable.ic_media_fullscreen_shrink);
}
else {
mFullscreenButton.setImageResource(R.drawable.ic_media_fullscreen_stretch);
}
}
private void doPauseResume() {
if (mPlayer == null) {
return;
}
if (mPlayer.isPlaying()) {
mPlayer.pause();
} else {
mPlayer.start();
}
updatePausePlay();
}
private void doToggleFullscreen() {
if (mPlayer == null) {
return;
}
mPlayer.toggleFullScreen();
}
// There are two scenarios that can trigger the seekbar listener to trigger:
//
// The first is the user using the touchpad to adjust the posititon of the
// seekbar's thumb. In this case onStartTrackingTouch is called followed by
// a number of onProgressChanged notifications, concluded by onStopTrackingTouch.
// We're setting the field "mDragging" to true for the duration of the dragging
// session to avoid jumps in the position in case of ongoing playback.
//
// The second scenario involves the user operating the scroll ball, in this
// case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notifications,
// we will simply apply the updated position without suspending regular updates.
private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
public void onStartTrackingTouch(SeekBar bar) {
show(3600000);
mDragging = true;
// By removing these pending progress messages we make sure
// that a) we won't update the progress while the user adjusts
// the seekbar and b) once the user is done dragging the thumb
// we will post one of these messages to the queue again and
// this ensures that there will be exactly one message queued up.
mHandler.removeMessages(SHOW_PROGRESS);
}
public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
if (mPlayer == null) {
return;
}
if (!fromuser) {
// We're not interested in programmatically generated changes to
// the progress bar's position.
return;
}
long duration = mPlayer.getDuration();
long newposition = (duration * progress) / 1000L;
mPlayer.seekTo( (int) newposition);
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime( (int) newposition));
}
public void onStopTrackingTouch(SeekBar bar) {
mDragging = false;
setProgress();
updatePausePlay();
show(sDefaultTimeout);
// Ensure that progress is properly updated in the future,
// the call to show() does not guarantee this because it is a
// no-op if we are already showing.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
}
};
#Override
public void setEnabled(boolean enabled) {
if (mPauseButton != null) {
mPauseButton.setEnabled(enabled);
}
if (mFfwdButton != null) {
mFfwdButton.setEnabled(enabled);
}
if (mRewButton != null) {
mRewButton.setEnabled(enabled);
}
if (mNextButton != null) {
mNextButton.setEnabled(enabled && mNextListener != null);
}
if (mPrevButton != null) {
mPrevButton.setEnabled(enabled && mPrevListener != null);
}
if (mProgress != null) {
mProgress.setEnabled(enabled);
}
disableUnsupportedButtons();
super.setEnabled(enabled);
}
private OnClickListener mRewListener = new OnClickListener() {
public void onClick(View v) {
if (mPlayer == null) {
return;
}
int pos = mPlayer.getCurrentPosition();
pos -= 5000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
}
};
private OnClickListener mFfwdListener = new OnClickListener() {
public void onClick(View v) {
if (mPlayer == null) {
return;
}
int pos = mPlayer.getCurrentPosition();
pos += 15000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
}
};
private void installPrevNextListeners() {
if (mNextButton != null) {
mNextButton.setOnClickListener(mNextListener);
mNextButton.setEnabled(mNextListener != null);
}
if (mPrevButton != null) {
mPrevButton.setOnClickListener(mPrevListener);
mPrevButton.setEnabled(mPrevListener != null);
}
}
public void setPrevNextListeners(OnClickListener next, OnClickListener prev) {
mNextListener = next;
mPrevListener = prev;
mListenersSet = true;
if (mRoot != null) {
installPrevNextListeners();
if (mNextButton != null && !mFromXml) {
mNextButton.setVisibility(View.VISIBLE);
}
if (mPrevButton != null && !mFromXml) {
mPrevButton.setVisibility(View.VISIBLE);
}
}
}
public interface MediaPlayerControl {
void start();
void pause();
int getDuration();
int getCurrentPosition();
void seekTo(int pos);
boolean isPlaying();
int getBufferPercentage();
boolean canPause();
boolean canSeekBackward();
boolean canSeekForward();
boolean isFullScreen();
void toggleFullScreen();
}
private static class MessageHandler extends Handler {
private final WeakReference<VideoControllerView> mView;
MessageHandler(VideoControllerView view) {
mView = new WeakReference<VideoControllerView>(view);
}
#Override
public void handleMessage(Message msg) {
VideoControllerView view = mView.get();
if (view == null || view.mPlayer == null) {
return;
}
int pos;
switch (msg.what) {
case FADE_OUT:
view.hide();
break;
case SHOW_PROGRESS:
pos = view.setProgress();
if (!view.mDragging && view.mShowing && view.mPlayer.isPlaying()) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
}
break;
}
}
}
}
My videoPlayerActivity.java
package com.otwar.deepak.video_styling;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;
import java.io.IOException;
public class VideoPlayerActivity extends Activity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, VideoControllerView.MediaPlayerControl {
SurfaceView videoSurface;
MediaPlayer player;
VideoControllerView controller;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_player);
videoSurface = (SurfaceView) findViewById(R.id.videoSurface);
SurfaceHolder videoHolder = videoSurface.getHolder();
videoHolder.addCallback(this);
player = new MediaPlayer();
controller = new VideoControllerView(this);
try {
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(this, Uri.parse("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"));
player.setOnPreparedListener(this);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
controller.show();
return false;
}
// Implement SurfaceHolder.Callback
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
player.prepareAsync();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
// End SurfaceHolder.Callback
// Implement MediaPlayer.OnPreparedListener
#Override
public void onPrepared(MediaPlayer mp) {
controller.setMediaPlayer(this);
controller.setAnchorView((FrameLayout) findViewById(R.id.videoSurfaceContainer));
player.start();
}
// End MediaPlayer.OnPreparedListener
// Implement VideoMediaController.MediaPlayerControl
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public int getCurrentPosition() {
return player.getCurrentPosition();
}
#Override
public int getDuration() {
return player.getDuration();
}
#Override
public boolean isPlaying() {
return player.isPlaying();
}
#Override
public void pause() {
player.pause();
}
#Override
public void seekTo(int i) {
player.seekTo(i);
}
#Override
public void start() {
player.start();
}
#Override
public boolean isFullScreen() {
return false;
}
#Override
public void toggleFullScreen() {
}
// End VideoMediaController.MediaPlayerControl
}

how to implement media player without blocking ui when implementing the media source from server?

the problem is simple, the media player is blocking the UI when implementing the source from remote server. i used a sync prepare for the initialize the media-player, but its block the UI when reset the media player.
here i written a code using thread, it helps a lot but need a clean solution.
public class QuranPlayerAct extends Activity implements DownloadMusicLstn,SeekBar.OnSeekBarChangeListener, OnClickListener,
MediaPlayer.OnPreparedListener, OnCompletionListener,
PlayerBtnClickedLstn, Runnable {
private static final int PLAY_FROM_LOCAL = 234;
private static final int PLAY_FROM_SERVER = 321;
private static final String TAG = "SongsListAct";
private static final int PAUSED = 756;
private static final int STARTED = 554;
private static final int STOPED = 386;
private static final int CLOSED = 453;
private TextView downloadEsplasedTV;
private RelativeLayout playerRetLay;
private ListView musicLst;
private ProgressBar dwnPrgV;
private ImageView playImgV;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
private MediaPlayer mp;
private Utilities utils;
private Handler handler;
private boolean stopDownload;
private RelativeLayout downloadRetLay;
private ArrayList<String> musicFiles;
private ImageButton closeImgV;
private TextView downloadTitle;
private long currentDuration;
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if (mPrepared) {
long totalDuration = mp.getDuration();
currentDuration = mp.getCurrentPosition();
songTotalDurationLabel.setText(""
+ utils.milliSecondsToTimer(totalDuration));
songCurrentDurationLabel.setText(""
+ utils.milliSecondsToTimer(currentDuration));
int progress = (int) (utils.getProgressPercentage(
currentDuration, totalDuration));
songProgressBar.setProgress(progress);
}
handler.postDelayed(this, 100);
}
};
private TextView downloadTotalTV;
private TextView downloadPercentageTV;
private ImageView stopImgV;
private ImageButton closeDownloadImgV;
private int fileSize;
private boolean mPrepared;
private ProgressBar songsLoadingPB;
private String url;
private String fName;
private boolean stopped;
private int plLoc;
private int track_no;
private int state;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_quran_player);
// setActionBar();
setActionBar2();
getRefs();
handler = new Handler();
initMediaPlayer();
playerRetLay.setVisibility(View.GONE);
// updateList();
createAppDirectory();
Thread t = new Thread(this);
t.start();
}
private void setActionBar2() {
final ActionBar bar = getActionBar();
bar.setDisplayShowHomeEnabled(false);
bar.setDisplayShowCustomEnabled(true);
bar.setDisplayShowTitleEnabled(false);
bar.setCustomView(R.layout.player_actionbar_lay);
}
/*
* private void setActionBar() { final ActionBar bar = getActionBar();
*
* bar.setDisplayShowHomeEnabled(false);
* bar.setDisplayShowCustomEnabled(true);
* bar.setDisplayShowTitleEnabled(false);
* bar.setCustomView(R.layout.player_actionbar_lay);
*
* TextView tv = (TextView) bar.getCustomView().findViewById(
* R.id.action_bar_title);
*
* try { tv.setTypeface(Typeface .createFromAsset(getAssets(),
* "DANUBE__.TTF")); } catch (Exception e) { e.printStackTrace(); } }
*/
#Override
public void onResume() {
super.onResume();
setVisiblilityToPlayerAndUI(false);
updateProgressBar();
if(state==CLOSED)playerRetLay.setVisibility(View.GONE);
}
#Override
public void onPause() {
super.onPause();
l("Activity paused");
stopDownload = true;
setVisiblilityToPlayerAndUI(false);
handler.removeCallbacks(mUpdateTimeTask);
if (mp != null)
switch (state) {
case STARTED:
mp.pause();
playImgV.setImageResource(R.drawable.play_img);
break;
}
}
private void getRefs() {
musicLst = (ListView) findViewById(R.id.musLst_lstV);
playerRetLay = (RelativeLayout) findViewById(R.id.musLst_player_retLay);
dwnPrgV = (ProgressBar) findViewById(R.id.musLst_down_progbarV);
downloadRetLay = (RelativeLayout) findViewById(R.id.musLst_dwn_retLay);
playImgV = (ImageView) findViewById(R.id.musLst_ply_btn);
songProgressBar = (SeekBar) findViewById(R.id.musLst_seek_bar);
songTitleLabel = (TextView) findViewById(R.id.musLst_mus_det_txt);
songCurrentDurationLabel = (TextView) findViewById(R.id.time_esplased_TV);
songTotalDurationLabel = (TextView) findViewById(R.id.total_time_TV);
closeImgV = (ImageButton) findViewById(R.id.musLst_close_btn);
downloadTitle = (TextView) findViewById(R.id.musLst_down_title_TV);
downloadEsplasedTV = (TextView) findViewById(R.id.time_esplased_TV22);
downloadTotalTV = (TextView) findViewById(R.id.total_time_TV2);
downloadPercentageTV = (TextView) findViewById(R.id.total_percentage);
stopImgV = (ImageView) findViewById(R.id.musLst_stop_btn);
closeDownloadImgV = (ImageButton) findViewById(R.id.close_down_btn);
songsLoadingPB = (ProgressBar) findViewById(R.id.songs_load_progressbar);
}
#Override
public void run() {
if (!isNetworkAvailable()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(QuranPlayerAct.this,
"No Internet Connection Available",
Toast.LENGTH_LONG).show();
}
});
return;
}
MusicAppUtils appUtils = new MusicAppUtils();
String jsn = appUtils
.getDataFromUrl(MusicAppCommons.HTTP_AIMANSANGAM_COM_LISTFILES_PHP);
if (jsn == null)
return;
jsn = jsn.replace(",]", "]");
musicFiles = appUtils.parseMusicFilesJson(jsn);
updateList();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager
.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private void createAppDirectory() {
if (MusicAppCommons
.checkFileExist(MusicAppCommons.AIMANSANGAM_MUSIC_DIR)) {
Log.i(TAG, "app directory already exist");
return;
}
File dir = new File(MusicAppCommons.AIMANSANGAM_MUSIC_DIR);
if (dir.mkdirs())
Log.i(TAG, "app directory created");
}
private void setVisiblilityToPlayerAndUI(boolean b) {
if (b) {
songsLoadingPB.setVisibility(View.VISIBLE);
downloadRetLay.setVisibility(View.VISIBLE);
// playerRetLay.setVisibility(View.VISIBLE);
} else {
songsLoadingPB.setVisibility(View.GONE);
downloadRetLay.setVisibility(View.GONE);
// playerRetLay.setVisibility(View.GONE);
}
}
private void initMediaPlayer() {
utils = new Utilities();
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
songProgressBar.setOnSeekBarChangeListener(this);
playImgV.setOnClickListener(this);
closeDownloadImgV.setOnClickListener(this);
closeImgV.setOnClickListener(this);
stopImgV.setOnClickListener(this);
}
private void resetTimeLabel() {
runOnUiThread(new Runnable() {
#Override
public void run() {
songTotalDurationLabel.setText("..");
songCurrentDurationLabel.setText("..");
}
});
}
public void updateProgressBar() {
handler.removeCallbacks(mUpdateTimeTask);
handler.postDelayed(mUpdateTimeTask, 100);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(mUpdateTimeTask);
if (mp != null)
mp.release();
}
public void updateList() {
l("called update list");
if (musicFiles == null)
return;
updateMusicListView(MusicLstAdapter.MUSIC_NOT_DOWNLOADING);
}
private void updateMusicListView(int state) {
final MusicLstAdapter lstAdapter = new MusicLstAdapter(this,
musicFiles, this, state, this);
runOnUiThread(new Runnable() {
#Override
public void run() {
musicLst.setAdapter(lstAdapter);
lstAdapter.notifyDataSetChanged();
}
});
}
#Override
public void onClick(View v) {
if (v == closeDownloadImgV) {
downloadRetLay.setVisibility(View.GONE);
stopDownload = true;
Toast.makeText(this, "Download canceled", Toast.LENGTH_SHORT)
.show();
} else if (v == playImgV) {
if (stopped)
new PlayerThread();
if (mp.isPlaying()) {
if (mp != null) {
state = PAUSED;
mp.pause();
l("pause");
playImgV.setImageResource(R.drawable.play_img);
}
} else {
if (mp != null) {
state = STARTED;
mp.start();
l("start");
playImgV.setImageResource(R.drawable.pause_img);
}
}
} else if (v == closeImgV) {
l("close clicked");
state = CLOSED;
playerRetLay.setVisibility(View.GONE);
handler.removeCallbacks(mUpdateTimeTask);
mp.stop();
mPrepared = false;
new Thread(new Runnable() {
#Override
public void run() {
mp.reset();
}
}).start();
} else if (v == stopImgV) {
l("stop clicked");
state = STOPED;
handler.removeCallbacks(mUpdateTimeTask);
mp.stop();
resetTimeLabel();
playImgV.setImageResource(R.drawable.play_img);
stopped = true;
mPrepared = false;
}
}
// --------************************************************************************
#Override
public void setSize(final int fileSize) {
handler.post(new Runnable() {
#Override
public void run() {
dwnPrgV.setMax(fileSize);
QuranPlayerAct.this.fileSize = fileSize;
float size = (float) fileSize / 1048576;
DecimalFormat format = new DecimalFormat("#.##");
downloadTotalTV.setText(format.format(size) + " MB");
downloadPercentageTV.setText("0 %");
}
});
}
#Override
public void onProgressUpdate(final long total) {
handler.post(new Runnable() {
#Override
public void run() {
dwnPrgV.setProgress((int) total);
float size = (float) total / 1048576;
DecimalFormat format = new DecimalFormat("#.##");
downloadEsplasedTV.setText(format.format(size) + " MB");
float l = total / (float) fileSize * 100;
int round = Math.round(l);
downloadPercentageTV.setText(round + " %");
}
});
}
#Override
public void finished() {
handler.post(new Runnable() {
#Override
public void run() {
downloadRetLay.setVisibility(View.GONE);
}
});
updateMusicListView(MusicLstAdapter.MUSIC_NOT_DOWNLOADING);
}
#Override
public void onDownloadSuccess(boolean success) {
if (success) {
} else {
}
}
#Override
public boolean isStopDownload() {
return stopDownload;
}
#Override
public void downloadStarted(final String fName) {
stopDownload = false;
handler.post(new Runnable() {
#Override
public void run() {
downloadTitle.setText(fName);
downloadRetLay.setVisibility(View.VISIBLE);
}
});
updateMusicListView(MusicLstAdapter.MUSIC_DOWNLOADING);
}
// ----------------*****************************************************************************
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromTouch) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
mp.seekTo(currentPosition);
updateProgressBar();
}
#Override
public void onPrepared(MediaPlayer mp) {
l("onprepared");
mPrepared = true;
mp.start();
state = STARTED;
playImgV.setImageResource(R.drawable.pause_img);
}
private void l(String str) {
Log.i(TAG, str);
}
// ---------------------***************************************************************************
private class PlayerThread extends Thread {
public PlayerThread() {
start();
}
#Override
public void run() {
try {
stopped = false;
mPrepared = false;
resetTimeLabel();
mp.reset();
mp.setDataSource(url);
if (plLoc == PLAY_FROM_SERVER) {
mp.prepareAsync();
mp.setOnPreparedListener(QuranPlayerAct.this);
updatePlayerImg(R.drawable.play_img);
} else {
mp.prepare();
mp.start();
mPrepared = true;
state = STARTED;
updatePlayerImg(R.drawable.pause_img);
}
updatePlayerUI();
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void updatePlayerUI() {
runOnUiThread(new Runnable() {
#Override
public void run() {
songTitleLabel.setText(fName);
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
}
});
}
}
private void updatePlayerImg(final int playImg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
playImgV.setImageResource(playImg);
}
});
}
// ------------------------------
#Override
public void onCompletion(MediaPlayer mp) {
track_no++;
if (track_no > musicFiles.size() - 1) {
track_no = 0;
}
playerRetLay.setVisibility(View.VISIBLE);
fName = musicFiles.get(track_no);
String filePath = MusicAppCommons.AIMANSANGAM_MUSIC_DIR + "/" + fName;
if (MusicAppCommons.checkFileExist(filePath)) {
url = filePath;
plLoc = PLAY_FROM_LOCAL;
} else {
url = MusicAppCommons.HTTP_AIMANSANGAM_COM_QURAN_FILES + fName;
url = url.replace(" ", "%20");
plLoc = PLAY_FROM_SERVER;
}
new PlayerThread();
}
#Override
public void clickedOnPlayBtn(int val) {
this.track_no = val;
l("song clicked");
playerRetLay.setVisibility(View.VISIBLE);
fName = musicFiles.get(val);
String filePath = MusicAppCommons.AIMANSANGAM_MUSIC_DIR + "/" + fName;
if (MusicAppCommons.checkFileExist(filePath)) {
url = filePath;
plLoc = PLAY_FROM_LOCAL;
} else {
url = MusicAppCommons.HTTP_AIMANSANGAM_COM_QURAN_FILES + fName;
url = url.replace(" ", "%20");
plLoc = PLAY_FROM_SERVER;
}
new PlayerThread();
}
}

Categories