i'm trying to play music in my app using code below ,and it's work fine when i tested on (Android 8.0 ,7.0,5.0) but when i tested on Android 9.0 ,it doesn't worked,it seems like RadioService doesn't work it show me Somethig went wrong!! Toast so onPlayerError called
public void onPlayerError(ExoPlaybackException error) {
EventBus.getDefault().post(PlaybackStatus.ERROR);
}
MainActivity.java
#Subscribe
public void onEvent(String status) {
switch (status) {
case PlaybackStatus.LOADING:
progressloading.setVisibility(View.VISIBLE);
trigger.setVisibility(View.GONE);
break;
case PlaybackStatus.ERROR:
Toast.makeText(this, "Something went wrong!!", Toast.LENGTH_SHORT).show();
break;
}
if (status.equals(PlaybackStatus.PLAYING)) {
trigger.setVisibility(View.VISIBLE);
progressloading.setVisibility(View.GONE);
}
trigger.setImageResource(status.equals(PlaybackStatus.PLAYING)
? R.drawable.ic_pause_black
: R.drawable.ic_play_arrow_black);
}
, can anyone help me to get solution of this issue.
RadioService.java
#Override
public void onCreate() {
super.onCreate();
String strAppName = getResources().getString(R.string.app_name);
String strLiveBroadcast = getResources().getString(R.string.live_broadcast);
onGoingCall = false;
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
notificationManager = new MediaNotificationManager(this);
wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mcScPAmpLock");
mediaSession = new MediaSessionCompat(this, getClass().getSimpleName());
transportControls = mediaSession.getController().getTransportControls();
mediaSession.setActive(true);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "...")
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, strAppName)
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, strLiveBroadcast)
.build());
mediaSession.setCallback(mediasSessionCallback);
handler = new Handler();
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
AdaptiveTrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
DefaultTrackSelector trackSelector = new DefaultTrackSelector(trackSelectionFactory);
exoPlayer = ExoPlayerFactory.newSimpleInstance(getApplicationContext(), trackSelector, new CustomLoadControl());
exoPlayer.addListener(this);
registerReceiver(becomingNoisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
status = PlaybackStatus.IDLE;
}//END ON CREATE
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
if (TextUtils.isEmpty(action)) return START_NOT_STICKY;
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
stop();
return START_NOT_STICKY;
}
if (action != null) {
if (action.equalsIgnoreCase(ACTION_PLAY)) {
transportControls.play();
} else if (action.equalsIgnoreCase(ACTION_PAUSE)) {
transportControls.pause();
} else if (action.equalsIgnoreCase(ACTION_STOP)) {
transportControls.stop();
}
}
return START_NOT_STICKY;
}
#Override
public boolean onUnbind(Intent intent) {
serviceInUse = false;
if (status.equals(PlaybackStatus.IDLE))
stopSelf();
return super.onUnbind(intent);
}
#Override
public void onRebind(final Intent intent) {
serviceInUse = true;
}
#Override
public void onDestroy() {
pause();
exoPlayer.release();
exoPlayer.removeListener(this);
notificationManager.cancelNotify();
mediaSession.release();
unregisterReceiver(becomingNoisyReceiver);
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
serviceInUse = true;
return iBinder;
}
#Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
exoPlayer.setPlayWhenReady(true);
exoPlayer.setVolume(1.0f);
break;
case AudioManager.AUDIOFOCUS_GAIN:
exoPlayer.setVolume(0.8f);
resume();
break;
case AudioManager.AUDIOFOCUS_LOSS:
stop();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
if (isPlaying()) pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
if (isPlaying())
exoPlayer.setVolume(0.1f);
break;
}
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
status = PlaybackStatus.LOADING;
break;
case Player.STATE_ENDED:
status = PlaybackStatus.STOPPED;
break;
case Player.STATE_IDLE:
status = PlaybackStatus.IDLE;
break;
case Player.STATE_READY:
status = playWhenReady ? PlaybackStatus.PLAYING : PlaybackStatus.PAUSED;
break;
default:
status = PlaybackStatus.IDLE;
break;
}
if (!status.equals(PlaybackStatus.IDLE)) {
final Uri uri = Uri.parse("http://radio.plaza.one/mp3");
OnNewMetadataListener listener = new OnNewMetadataListener() {
#Override
public void onNewHeaders(String stringUri, List<String> name, List<String> desc, List<String> br, List<String> genre, List<String> info) {
}
#Override
public void onNewStreamTitle(String stringUri, final String streamTitle) {
MainActivity.songinfo.setText(streamTitle);
if (Build.VERSION.SDK_INT >= 21)
notificationManager.startNotify(getApplicationContext(), status, streamTitle);
}
};
AudiostreamMetadataManager.getInstance()
.setUri(uri)
.setOnNewMetadataListener(listener)
.setUserAgent(UserAgent.WINDOWS_MEDIA_PLAYER)
.start();
}
EventBus.getDefault().post(status);
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
EventBus.getDefault().post(PlaybackStatus.ERROR);
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
public void play(String streamUrl) {
this.streamUrl = streamUrl;
if (wifiLock != null && !wifiLock.isHeld()) {
wifiLock.acquire();
}
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, getClass().getSimpleName()), bandwidthMeter);
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
ExtractorMediaSource mediaSource = new ExtractorMediaSource(Uri.parse(streamUrl), dataSourceFactory, extractorsFactory, handler, null);
exoPlayer.prepare(mediaSource);
exoPlayer.setPlayWhenReady(true);
}
public void resume() {
if (streamUrl != null)
play(streamUrl);
}
public void pause() {
exoPlayer.setPlayWhenReady(false);
audioManager.abandonAudioFocus(this);
wifiLockRelease();
}
public void stop() {
exoPlayer.stop();
audioManager.abandonAudioFocus(this);
wifiLockRelease();
}
public void playOrPause(String url) {
if (streamUrl != null && streamUrl.equals(url)) {
if (!isPlaying()) {
play(streamUrl);
} else {
pause();
}
} else {
if (isPlaying()) {
pause();
}
play(url);
}
}
public String getStatus() {
return status;
}
public MediaSessionCompat getMediaSession() {
return mediaSession;
}
public boolean isPlaying() {
return this.status.equals(PlaybackStatus.PLAYING);
}
private void wifiLockRelease() {
if (wifiLock != null && wifiLock.isHeld()) {
wifiLock.release();
}
}
public int getCurrentPosition() {
return (int) exoPlayer.getCurrentPosition();
}
}
MediaNotificationManager.java
public class MediaNotificationManager {
private static final int NOTIFICATION_ID = 555;
private RadioService service;
private NotificationManagerCompat notificationManager;
private Resources resources;
MediaNotificationManager(RadioService service) {
this.service = service;
this.resources = service.getResources();
notificationManager = NotificationManagerCompat.from(service);
}
void startNotify(Context context, String playbackStatus, String title) {
String titlesonge;
String artist;
try {
titlesonge = StringUtils.substringBefore(title, " - ");
artist = StringUtils.substringAfter(title, " - ");
} catch (Exception e) {
titlesonge = title.substring(0, title.indexOf(" - "));
artist = title.substring(title.lastIndexOf(" - ") - 1);
}
int icon = R.drawable.ic_pause_white;
Intent playbackAction = new Intent(service, RadioService.class);
playbackAction.setAction(RadioService.ACTION_PAUSE);
PendingIntent action = PendingIntent.getService(service, 1, playbackAction, 0);
if (playbackStatus.equals(PlaybackStatus.PAUSED)) {
icon = R.drawable.ic_play_white;
playbackAction.setAction(RadioService.ACTION_PLAY);
action = PendingIntent.getService(service, 2, playbackAction, 0);
}
Intent stopIntent = new Intent(service, RadioService.class);
stopIntent.setAction(RadioService.ACTION_STOP);
PendingIntent stopAction = PendingIntent.getService(service, 3, stopIntent, 0);
Intent intent = new Intent(service, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP |
Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(service, 0, intent, 0);
notificationManager.cancel(NOTIFICATION_ID);
String PRIMARY_CHANNEL = "PRIMARY_CHANNEL_ID";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager manager = (NotificationManager) service.getSystemService(Context.NOTIFICATION_SERVICE);
String PRIMARY_CHANNEL_NAME = "PRIMARY";
NotificationChannel channel = new NotificationChannel(PRIMARY_CHANNEL, PRIMARY_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(service, PRIMARY_CHANNEL)
.setAutoCancel(false)
.setContentTitle(titlesonge)
.setContentText(artist)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.largeicon))
.setContentIntent(pendingIntent)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.smallwidth)
.setColor(ContextCompat.getColor(context, R.color.colorneeded))
.addAction(icon, "pause", action)
.addAction(R.drawable.ic_stop_white, "stop", stopAction)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
.setMediaSession(service.getMediaSession().getSessionToken())
.setShowActionsInCompactView(0, 1)
.setShowCancelButton(true)
.setCancelButtonIntent(stopAction));
service.startForeground(NOTIFICATION_ID, builder.build());
}
void cancelNotify() {
service.stopForeground(true);
notificationManager.cancel(NOTIFICATION_ID);
}
}
RadioManager.java
public class RadioManager {
#SuppressLint("StaticFieldLeak")
private static RadioManager instance = null;
private static RadioService service;
private Context context;
private boolean serviceBound;
public RadioManager(Context context) {
this.context = context;
serviceBound = false;
}
public static RadioManager with(Context context) {
if (instance == null)
instance = new RadioManager(context);
return instance;
}
public static RadioService getService() {
return service;
}
public void playOrPause(String streamUrl) {
service.playOrPause(streamUrl);
}
public boolean isPlaying() {
if (service != null) {
return service.isPlaying();
}
return false;
}
public int getCurrentPosition() {
if (service != null) {
return service.getCurrentPosition();
}
return 0;
}
public void bind() {
Intent intent = new Intent(context, RadioService.class);
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
if (service != null)
EventBus.getDefault().post(service.getStatus());
}
public void unbind() {
context.unbindService(serviceConnection);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
RadioService.LocalBinder rl = (RadioService.LocalBinder) binder;
service = rl.getService();
}
public void onServiceDisconnected(ComponentName arg0) {
serviceBound = false;
}
};
}
Manifest.xml
<service
android:name=".RadioTools.RadioService"
android:exported="true"
android:stopWithTask="true" />
Since Android 9 ,the link with Http no longer supported,i just added S to my link so instead of
http://mylink.com/mp3
i added s :
https://mylink.com/mp3
And everything worked fine
Related
I have almost a week figuring out how should I have one instance of exoplayer in background.
I want to use this instance in a playerview and in notification as well. Problem I am facing now, the player plays well, after a time it pauses (to release resource I guess), but when i click play it plays again, when i click other oudio, I get two audio playing at same time.
Here are my codes.
------------------------ BACKGROUND SERVICE --------------------------------------
public class BackgroundPlayingService extends Service {
public static PlayerNotificationManager playerNotificationManager;
public static ExoPlayer exoPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (this.exoPlayer == null){
createPlayer();
}
/////////////////THIS WAS ADDED LATER
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
exoPlayer.pause();
exoPlayer = null;
playerNotificationManager.setPlayer(null);
}
private void createPlayer(){
exoPlayer = new ExoPlayer.Builder(this).build();
MediaItem mediaItem;
try {
mediaItem = MediaItem.fromUri(Uri.parse(DataUtility.playingUrl));
}catch (Exception e){
mediaItem = MediaItem.fromUri(Uri.parse("https://server13.mp3quran.net/husr/062.mp3"));
}
exoPlayer.setMediaItem(mediaItem);
exoPlayer.prepare();
exoPlayer.addListener(new Player.Listener() {
#Override
public void onPlaybackStateChanged(int playbackState) {
Player.Listener.super.onPlaybackStateChanged(playbackState);
try {
if (ThePlayingActivity.dialog.isShowing()){
ThePlayingActivity.dialog.dismiss();}
}catch (Exception ignore){
}
if (playbackState==Player.STATE_READY){
try {
ThePlayingActivity.downloadBtn.setVisibility(View.VISIBLE);
showNotification();
}catch (Exception ignore){
}
}
if (playbackState == Player.STATE_BUFFERING) {
try {
ThePlayingActivity.myProgress.setVisibility(View.VISIBLE);
}catch (Exception e){
}
} else {
try {
ThePlayingActivity.myProgress.setVisibility(View.GONE);
}catch (Exception e){
}
}
}
#Override
public void onIsLoadingChanged(boolean isLoading) {
Player.Listener.super.onIsLoadingChanged(isLoading);
}
#Override
public void onPlayerError(PlaybackException error) {
Player.Listener.super.onPlayerError(error);
try {
if (ThePlayingActivity.dialog.isShowing()){
ThePlayingActivity.dialog.dismiss();
}
playerNotificationManager.setPlayer(null);
}catch (Exception ignore){
}
}
});
exoPlayer.play();
try {
ThePlayingActivity.myPlayerView.setPlayer(exoPlayer);
}catch (Exception e){
Log.d("background", "createPlayer: set player to view"+e.getLocalizedMessage());
}
}
public static void setNewPlayeData(){
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(DataUtility.playingUrl));
exoPlayer.setMediaItem(mediaItem);
exoPlayer.prepare();
ThePlayingActivity.myPlayerView.setPlayer(exoPlayer);
try {
ThePlayingActivity.myPlayerView.setPlayer(exoPlayer);
}catch (Exception e){
Log.d("background", "createPlayer: set player to view"+e.getLocalizedMessage());
}
}
public void showNotification() {
playerNotificationManager = new PlayerNotificationManager.Builder(this, 151,
this.getResources().getString(R.string.app_name))
.setChannelNameResourceId(R.string.app_name)
.setChannelImportance(IMPORTANCE_HIGH)
.setMediaDescriptionAdapter(new PlayerNotificationManager.MediaDescriptionAdapter() {
#Override
public CharSequence getCurrentContentTitle(Player player) {
return player.getCurrentMediaItem().mediaMetadata.displayTitle;
}
#Nullable
#Override
public PendingIntent createCurrentContentIntent(Player player) {
return null;
}
#Nullable
#Override
public CharSequence getCurrentContentText(Player player) {
return Objects.requireNonNull(player.getCurrentMediaItem()).mediaMetadata.artist;
}
#Nullable
#Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
return null;
}
}).setNotificationListener(new PlayerNotificationManager.NotificationListener() {
#Override
public void onNotificationCancelled(int notificationId, boolean dismissedByUser) {
}
#Override
public void onNotificationPosted(int notificationId, Notification notification, boolean ongoing) {
PlayerNotificationManager.NotificationListener.super.onNotificationPosted(notificationId, notification, ongoing);
}
})
.build();
playerNotificationManager.setUseStopAction(false);
try {
playerNotificationManager.setPlayer(exoPlayer);
}catch (Exception e){
}
}
}
-----------------------HERE IS THE ACTIVITY WITH PLAYER ----------------------------------
public class ThePlayingActivity extends AppCompatActivity {
private static final int PERMISION_STORAGE_CODE = 100;
private ProgressBar downloadingProgress;
public static ProgressBar myProgress;
public static Dialog dialog;
private ConstraintLayout layoutForSnack;
long downloadId;
private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
String myurl;
public static PlayerControlView myPlayerView;
private TextView currentPlaying, downloadingTv;
public static Button downloadBtn;
private String thePlayingSura;
private final BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
if (downloadId == id){
downloadingProgress.setVisibility(View.GONE);
downloadingTv.setVisibility(View.GONE);
downloadBtn.setText("DOWNLOADED");
downloadBtn.setBackgroundColor(Color.TRANSPARENT);
downloadBtn.setTextColor(Color.BLACK);
downloadBtn.setClickable(false);
Toast.makeText(context, "DOWNLOAD COMPLETED", Toast.LENGTH_SHORT).show();
}
}
};
#SuppressLint("SetTextI18n")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_the_playing);
myPlayerView = findViewById(R.id.playerView);
Intent dataIntent = getIntent();
myurl = dataIntent.getStringExtra("theUrl");
if (BackgroundPlayingService.exoPlayer == null){
startService();}else{
BackgroundPlayingService.setNewPlayeData();
myPlayerView.setPlayer(BackgroundPlayingService.exoPlayer);
}
keepActivityAlive();
registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
downloadingProgress = findViewById(R.id.downloadProgress);
downloadingTv = findViewById(R.id.downloadingWaitTv);
currentPlaying = findViewById(R.id.currentPlaying);
downloadBtn = findViewById(R.id.downloadbtn);
downloadBtn.setVisibility(View.GONE);
myProgress = findViewById(R.id.progressBar2);
myProgress.setVisibility(View.GONE);
layoutForSnack = findViewById(R.id.constraintLayout);
downloadingProgress.setVisibility(View.GONE);
downloadingTv.setVisibility(View.GONE);
thePlayingSura = dataIntent.getStringExtra("sendSuraName");
currentPlaying.setText(thePlayingSura+" - " + DataUtility.theKariName);
/////////////end of ids
showLoadingDialog();
/////////////////download
downloadBtn.setOnClickListener(view -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
//todo ask permission
String permissions[] = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions,PERMISION_STORAGE_CODE);
}else{
downloadStaffs();
}
}else {
//TODO DOWNLOAD
downloadStaffs();
}
});
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
}
#Override
public void onBackPressed() {
super.onBackPressed();
//todo fire service (may be)
}
private void showLoadingDialog() {
dialog = new Dialog(ThePlayingActivity.this);
dialog.setContentView(R.layout.dialog_loading_quran);
dialog.setCancelable(false);
dialog.show();
}
private void showSnackBar() {
Snackbar snackbar = Snackbar.make(layoutForSnack, "THERE WAS ON ERROR, CHECK YOUR INTERNET CONNECTION", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("RETRY", view -> {
});
snackbar.setActionTextColor(Color.YELLOW);
snackbar.show();
}
#Override
protected void onStop() {
super.onStop();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case PERMISION_STORAGE_CODE:{
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
// we have permission
//todo Download
downloadStaffs();
}else{
Toast.makeText(ThePlayingActivity.this , "PERMISSION DENIED... CAN NOT DOWNLOAD", Toast.LENGTH_SHORT).show();
}
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(onDownloadComplete);
try {
if (wakeLock.isHeld()){
wakeLock.release();}
}catch (Exception ignore){
}
}
private void downloadStaffs(){
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DataUtility.playingUrl));
request.setDescription("Download File");
request.setTitle(thePlayingSura);
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, thePlayingSura+" - "+ DataUtility.theKariName+".mp3");
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
this.downloadId = downloadId;
final ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.downloadProgress);
downloadingTv.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
#SuppressLint("Range")
#Override
public void run() {
boolean downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadId);
Cursor cursor = manager.query(q);
cursor.moveToFirst();
#SuppressLint("Range") int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
#SuppressLint("Range") int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
}
final double dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressBar.setProgress((int) dl_progress);
}
});
Log.d("MESSAGES", statusMessage(cursor));
cursor.close();
}
}
}).start();
}
#SuppressLint("Range")
private String statusMessage(Cursor c) {
String msg = "???";
switch (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
case DownloadManager.STATUS_FAILED:
msg = "Download failed!";
break;
case DownloadManager.STATUS_PAUSED:
msg = "Download paused!";
break;
case DownloadManager.STATUS_PENDING:
msg = "Download pending!";
break;
case DownloadManager.STATUS_RUNNING:
msg = "Download in progress!";
break;
case DownloadManager.STATUS_SUCCESSFUL:
msg = "Download complete!";
break;
default:
msg = "Download is nowhere in sight";
break;
}
return (msg);
}
}
private void keepActivityAlive(){
powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"QuranAudio:WakeLock");
}
private void startService(){
Intent i = new Intent(this, BackgroundPlayingService.class);
startService(i);
}
}
I figured it out.
I had to keep most of my business inside in onStartCommand
public class BackgroundPlayingService extends Service {
public static final String TAG = "bck_service";
public static ExoPlayer player;
public static PlayerNotificationManager playerNotificationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String url = DataUtility.playingUrl;
if (url==null){
url = "https://server8.mp3quran.net/afs/Rewayat-AlDorai-A-n-Al-Kisa-ai/025.mp3";
}
if (player == null){
player = createPlayerIfNull();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(url));
player.setMediaItem(mediaItem);
player.prepare();
player.addListener(new Player.Listener() {
#Override
public void onEvents(Player player, Player.Events events) {
}
#Override
public void onPlaybackStateChanged(int playbackState) {
Player.Listener.super.onPlaybackStateChanged(playbackState);
try {
if (ThePlayingActivity.dialog.isShowing()){
ThePlayingActivity.dialog.dismiss();}
}catch (Exception ignore){
}
if (playbackState==Player.STATE_READY){
try {
ThePlayingActivity.downloadBtn.setVisibility(View.VISIBLE);
showNotification();
}catch (Exception ignore){
}
}
if (playbackState == Player.STATE_BUFFERING) {
try {
ThePlayingActivity.myProgress.setVisibility(View.VISIBLE);
}catch (Exception e){
}
} else {
try {
ThePlayingActivity.myProgress.setVisibility(View.GONE);
}catch (Exception e){
}
}
}
#Override
public void onIsLoadingChanged(boolean isLoading) {
Player.Listener.super.onIsLoadingChanged(isLoading);
}
#Override
public void onPlayerError(PlaybackException error) {
Player.Listener.super.onPlayerError(error);
try {
if (ThePlayingActivity.dialog.isShowing()){
ThePlayingActivity.dialog.dismiss();}
}catch (Exception ignore){
}
}
});
player.play();
try {
ThePlayingActivity.myPlayerView.setPlayer(player);
}catch (Exception ignore){}
}
//notification
createNotificationChannel();
Intent i = new Intent(this,BackgroundPlayingService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i,0);
Notification notification = new NotificationCompat.Builder(this,"myChannelId")
.setContentTitle("QURAN IS PLAYING")
.setContentText("This means that Qur-an app is open. You can close it from app exit menu")
.setSmallIcon(androidx.core.R.drawable.notification_icon_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1,notification);
return START_STICKY;
}
public ExoPlayer createPlayerIfNull() {
if (player == null) {
player = new ExoPlayer.Builder(BackgroundPlayingService.this).build();
ThePlayingActivity.myProgress.setVisibility(View.VISIBLE);
try {
ThePlayingActivity.dialog.show();
}catch (Exception e){
Log.d(TAG, "createPlayerIfNull: ");
}
}
return player;
}
private void createNotificationChannel(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
NotificationChannel channel = new NotificationChannel("myChannelId","qur-anAudiChannel", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
player = null;
stopForeground(true);
}
public void showNotification() {
playerNotificationManager = new PlayerNotificationManager.Builder(this, 151,
this.getResources().getString(R.string.app_name))
.setChannelNameResourceId(R.string.app_name)
.setChannelImportance(IMPORTANCE_HIGH)
.setMediaDescriptionAdapter(new PlayerNotificationManager.MediaDescriptionAdapter() {
#Override
public CharSequence getCurrentContentTitle(Player player) {
return player.getCurrentMediaItem().mediaMetadata.displayTitle;
}
#Nullable
#Override
public PendingIntent createCurrentContentIntent(Player player) {
return null;
}
#Nullable
#Override
public CharSequence getCurrentContentText(Player player) {
return Objects.requireNonNull(player.getCurrentMediaItem()).mediaMetadata.artist;
}
#Nullable
#Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
return null;
}
}).setNotificationListener(new PlayerNotificationManager.NotificationListener() {
#Override
public void onNotificationCancelled(int notificationId, boolean dismissedByUser) {
}
#Override
public void onNotificationPosted(int notificationId, Notification notification, boolean ongoing) {
PlayerNotificationManager.NotificationListener.super.onNotificationPosted(notificationId, notification, ongoing);
}
})
.build();
playerNotificationManager.setUseStopAction(false);
try {
playerNotificationManager.setPlayer(player);
}catch (Exception e){
}}
}
-------------------- player view activity ------------------------------------
public class ThePlayingActivity extends AppCompatActivity {
private static final int PERMISION_STORAGE_CODE = 100;
private ProgressBar downloadingProgress;
public static ProgressBar myProgress;
public static Dialog dialog;
private ConstraintLayout layoutForSnack;
long downloadId;
private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
String myurl;
public static PlayerControlView myPlayerView;
private TextView currentPlaying, downloadingTv;
public static Button downloadBtn;
private String thePlayingSura;
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (downloadId == id) {
downloadingProgress.setVisibility(View.GONE);
downloadingTv.setVisibility(View.GONE);
downloadBtn.setText("DOWNLOADED");
downloadBtn.setBackgroundColor(Color.TRANSPARENT);
downloadBtn.setTextColor(Color.BLACK);
downloadBtn.setClickable(false);
Toast.makeText(context, "DOWNLOAD COMPLETED", Toast.LENGTH_SHORT).show();
}
}
};
#SuppressLint("StaticFieldLeak")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_the_playing);
myPlayerView = findViewById(R.id.playerView);
Intent dataIntent = getIntent();
myurl = dataIntent.getStringExtra("theUrl");
Intent backgroundPlayIntent = new Intent(ThePlayingActivity.this,BackgroundPlayingService.class);
try {
stopService(backgroundPlayIntent);
}catch (Exception e){}
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
startForegroundService(backgroundPlayIntent);
}else{
startService(backgroundPlayIntent);
}
keepActivityAlive();
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
downloadingProgress = findViewById(R.id.downloadProgress);
downloadingTv = findViewById(R.id.downloadingWaitTv);
currentPlaying = findViewById(R.id.currentPlaying);
downloadBtn = findViewById(R.id.downloadbtn);
downloadBtn.setVisibility(View.GONE);
myProgress = findViewById(R.id.progressBar2);
myProgress.setVisibility(View.VISIBLE);
layoutForSnack = findViewById(R.id.constraintLayout);
downloadingProgress.setVisibility(View.GONE);
downloadingTv.setVisibility(View.GONE);
thePlayingSura = dataIntent.getStringExtra("sendSuraName");
currentPlaying.setText(thePlayingSura + " - " + DataUtility.theKariName);
/////////////end of ids
showLoadingDialog();
/////////////////download
downloadBtn.setOnClickListener(view -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
String permissions[] = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, PERMISION_STORAGE_CODE);
} else {
downloadStaffs();
}
} else {
downloadStaffs();
}
});
}
private void showLoadingDialog() {
dialog = new Dialog(ThePlayingActivity.this);
dialog.setContentView(R.layout.dialog_loading_quran);
dialog.setCancelable(false);
dialog.show();
}
public void showSnackBar() {
Snackbar snackbar = Snackbar.make(layoutForSnack, "THERE WAS ON ERROR, CHECK YOUR INTERNET CONNECTION", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("RETRY", view -> {
//todo retry player
});
snackbar.setActionTextColor(Color.YELLOW);
snackbar.show();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISION_STORAGE_CODE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// we have permission
downloadStaffs();
} else {
Toast.makeText(ThePlayingActivity.this, "PERMISSION DENIED... CAN NOT DOWNLOAD", Toast.LENGTH_SHORT).show();
}
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(onDownloadComplete);
try {
if (wakeLock.isHeld()) {
wakeLock.release();
}
} catch (Exception ignore) {
}
}
private void downloadStaffs() {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DataUtility.playingUrl));
request.setDescription("Download File");
request.setTitle(thePlayingSura);
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, thePlayingSura + " - " + DataUtility.theKariName + ".mp3");
final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
final long downloadId = manager.enqueue(request);
this.downloadId = downloadId;
final ProgressBar mProgressBar = (ProgressBar) findViewById(R.id.downloadProgress);
downloadingTv.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
#SuppressLint("Range")
#Override
public void run() {
boolean downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadId);
Cursor cursor = manager.query(q);
cursor.moveToFirst();
#SuppressLint("Range") int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
#SuppressLint("Range") int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
}
final double dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressBar.setProgress((int) dl_progress);
}
});
Log.d("MESSAGES", statusMessage(cursor));
cursor.close();
}
}
}).start();
}
#SuppressLint("Range")
private String statusMessage(Cursor c) {
String msg = "???";
switch (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
case DownloadManager.STATUS_FAILED:
msg = "Download failed!";
break;
case DownloadManager.STATUS_PAUSED:
msg = "Download paused!";
break;
case DownloadManager.STATUS_PENDING:
msg = "Download pending!";
break;
case DownloadManager.STATUS_RUNNING:
msg = "Download in progress!";
break;
case DownloadManager.STATUS_SUCCESSFUL:
msg = "Download complete!";
break;
default:
msg = "Download is nowhere in sight";
break;
}
return (msg);
}
private void keepActivityAlive() {
powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "QuranAudio:WakeLock");
}
private void startService() {
Intent i = new Intent(this, BackgroundPlayingService.class);
startService(i);
}}
--------------------- extra --------------------------------------
I also had to create other service to remove notification when the
user kill app by clearing app from recent apps.
here is it
MyAppService extends Service {
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Intent i = new Intent(MyAppService.this,BackgroundPlayingService.class);
try {
BackgroundPlayingService.playerNotificationManager.setPlayer(null);
stopService(i);
}catch (Exception ignore){}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}}
-------------------- WARNING ----------------------------------
I don't take this as a best approach, but it gave me a quick solution while waiting for a better approach.
I will pot the app link here when it's available in playstore.
I want to startService only once when I log in into my app and stop this service when I close app or log out. I want my service work for 2 min and for this I use a Handler.
This is my service:
public class Sendrer extends Service {
public static boolean running = false;
private Timer timer = new Timer();
private SendPhotoTask asyncSender;
private Context context;
private SharedPreferences sp;
private SharedPreferences.Editor editor;
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
sp = getSharedPreferences("pfref", Activity.MODE_PRIVATE);
editor = sp.edit();
Gson gson = new Gson();
List<File> productFromShared = new ArrayList<>();
SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("TAG", Context.MODE_PRIVATE);
String jsonPreferences = sharedPref.getString("TAG", "");
Type type = new TypeToken<List<File>>() {
}.getType();
productFromShared = gson.fromJson(jsonPreferences, type);
MainActivity.photoListSend = null;
MainActivity.photoListSend = new ArrayList<>();
if (productFromShared != null)
MainActivity.photoListSend.addAll(productFromShared);
Log.e("tworzenie serwisu ", "tworzenie");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Dziełanie serwisu ", "Dziełanie");
if (!running) {
running = true;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
asyncSender = new SendPhotoTask();
asyncSender.execute();
}
}, 1000 * 60 * 2);
}
return START_STICKY;
}
#Override
public void onDestroy() {
if (running) {
timer.cancel();
asyncSender = new SendPhotoTask();
asyncSender.cancel(true);
running = false;
}
Log.e("service ", "nie działa");
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
class SendPhotoTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
running = true;
if (MainActivity.photoListSend != null) {
if (!MainActivity.photoListSend.isEmpty())
if (NetworkUtil.isNetworkAvailable(context)) {
if (MainActivity.photoListSend.size() > 0) {
MainActivity.isSend = true;
running = true;
InputStream responseInputStream = null;
Log.e("start wysłania ", "start");
try {
if (MainActivity.photoListSend.get(0).isFile()) {
responseInputStream = HttpConnectionsUtil.sendPhotoRequest(getApplicationContext(), true, MainActivity.photoListSend.get(0).getName());
if (responseInputStream != null) {
String input = convertStreamToString(responseInputStream);
if (input.equals("empty"))
return "BAD";
else {
try {
int tt = ResponseParser.getType(input);
Log.e("TaG", tt + " ");
if (tt == 0) {
return null;
} else if (tt == -1) {
return null;
}
} catch (UnknownAnswerName e) {
e.printStackTrace();
return null;
}
}
}
} else {
return "BAD";
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
// Log.e("Wysyłanie zdjęcia ", convertStreamToString(responseInputStream));
if (responseInputStream != null)
return convertStreamToString(responseInputStream);
}
}
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (NetworkUtil.isNetworkAvailable(context)) {
if (sp.getBoolean("workOffLine", false)) {
editor.putBoolean("workOffLine", false);
editor.commit();
isConnect.setVisibility(View.VISIBLE);
imgIsSend.setVisibility(View.VISIBLE);
imgIsNet.setVisibility(View.GONE);
}
}
if (s != null) {
if (!MainActivity.photoListSend.isEmpty()) {
if (MainActivity.photoListSend.size() > 0) {
File file = MainActivity.photoListSend.get(0);
if (file.exists())
file.delete();
MainActivity.photoListSend.remove(0);
Gson gson = new Gson();
String jsonCurProduct;
synchronized (context) {
jsonCurProduct = gson.toJson(MainActivity.photoListSend);
}
SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("TAG", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("TAG", jsonCurProduct);
editor.apply();
File imagesFolder = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
assert imagesFolder != null;
}
}
}
if (s == null) {
MainActivity.isSend = false;
}
if (!MainActivity.photoListSend.isEmpty()) {
if (NetworkUtil.isNetworkAvailable(context)) {
if (MainActivity.photoListSend.size() > 0) {
asyncSender = new SendPhotoTask();
asyncSender.execute();
Log.e("Wysyłanie kolejnego ", "zdjecia");
} else {
context.stopService(new Intent(context, Sendrer.class));
asyncSender.cancel(true);
context.startService(new Intent(context, Sendrer.class));
}
} else {
context.stopService(new Intent(context, Sendrer.class));
asyncSender.cancel(true);
context.startService(new Intent(context, Sendrer.class));
}
} else {
MainActivity.isSend = false;
context.stopService(new Intent(context, Sendrer.class));
asyncSender.cancel(true);
context.startService(new Intent(context, Sendrer.class));
}
running = false;
}
}
}
Sometimes I start a service multiple times... And I want to that service works every 5 minutes
Refer this link for more help
https://developer.android.com/guide/components/services.html
I think you are sending photo inside service than you should use IntentService instead of Service. IntentService will be destroyed after your task finish.
In service onStartCommand() call every time when you start service and if you dont want to run your service longer than return START_NOT_STICKY
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
If Your task is completed than call inside onDestroy() method stopSelf().
stopSelf method stop your service.
#Override
public void onDestroy() {
super.onDestroy();
stopSelf();
}
I am trying to create a service after the application is killed and wait for the mobile to connect to wifi after that finish the task and stop the service, it works fine when I send the task while the app is not killed but after I kill the app the service wont quit
I've got three classes, the main class where I start the service
public class MainActivity extends AppCompatActivity {
//----------------------USER FIELDS -------------------->
Spinner Category;
EditText Description;
EditText Address;
EditText Date;
EditText Time;
EditText Name;
EditText Email;
EditText Phone;
//-----------------------CONSTANTS---------------------->
private static final int NUM_PAGES = 5;
private static final int CAMERA_VALUE = 301;
//----------------------IMAGE DIRECTORY----------------->
String root;
String imageFolderPath;
String imageName;
Uri fileUri;
ArrayList<Uri> fileUris = new ArrayList<>();
ArrayList<String> filepaths;
ArrayList<String> photoPaths;
List<String> Images = new ArrayList<>();
//----------------------FRAGMENTS----------------------->
SplashFragment splashFragment = new SplashFragment();
DescFragment descFragment = new DescFragment();
InfoFragment infoFragment = new InfoFragment();
ChooserFragment chooserFragment = new ChooserFragment();
SuccessFragment successFragment = new SuccessFragment();
//-------------------DATABASE HANDLER------------------->
DatabaseHandler db = new DatabaseHandler(this);
//---------------------DIALOGS-------------------------->
Dialog infoDialog;
Dialog languageDialog;
//-----------------SHARED PREFS------------------------->
SharedPreferences prefs = null;
//--------------IMAGEVIEW PREVIEWS---------------------->
ArrayList<ImageView> img = new ArrayList<>();
//-----------------COUNTERS----------------------------->
private static int image_counter = 0;
//----------VIEWPAGER AND VIEWPAGER ADAPTER------------->
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
TextInputLayout description_layout;
TextInputLayout spinner_layout;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//-------------CHECK FOR PERMISSIONS---------------->
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 0);
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
findViewById(R.id.mainLayout).requestFocus();
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
prefs = getSharedPreferences("co.milingona.socialactivist", MODE_PRIVATE);
selectLanguge(prefs.getString("language","sq"), false);
if(prefs.getBoolean("firstTimeRunning",true))
{
createShortcut();
prefs.edit().putBoolean("firstTimeRunning",false).commit();
}
}
#Override
protected void onResume()
{
super.onResume();
}
private void restartActivity()
{
Intent intent = getIntent();
finish();
startActivity(intent);
}
private void selectLanguge(String language, boolean restart)
{
prefs.edit().putString("language", language).commit();
String languageToLoad = language; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.setLocale(locale);
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
if( restart == true ) {
restartActivity();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
super.onBackPressed();
}
else if(mPager.getCurrentItem() == 4)
{
restartActivity();
} else {
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
public void splash_raporto(View view)
{
mPager.setCurrentItem(mPager.getCurrentItem() + 1);
}
public void desc_prev(View view)
{
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
public void desc_next(View view)
{
description_layout= (TextInputLayout) findViewById(R.id.description_layout);
spinner_layout= (TextInputLayout) findViewById(R.id.spinner_layout);
boolean continuePager = true;
Category = (Spinner)findViewById(R.id.category);
Description = (EditText)findViewById(R.id.description);
if(Description.getText().toString().trim().length() == 0)
{
description_layout.setError(getText(R.string.description));
continuePager=false;
} else {
description_layout.setErrorEnabled(false);
}
if(Category.getSelectedItem().toString().trim() == "Zgjidhni Kategorinë")
{
spinner_layout.setError(getText(R.string.category));
continuePager=false;
}
if(continuePager == true)
{
mPager.setCurrentItem(mPager.getCurrentItem()+1);
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
public void info_prev(View view)
{
mPager.setCurrentItem(mPager.getCurrentItem()-1);
}
public void info_next(View view)
{
Address = (EditText)findViewById(R.id.address);
this.Date = (EditText)findViewById(R.id.date);
Time = (EditText)findViewById(R.id.time);
Name = (EditText)findViewById(R.id.name);
Email = (EditText)findViewById(R.id.email);
Phone = (EditText)findViewById(R.id.phone);
if(Email.getText().toString().trim().length()!=0)
{
if(isValidEmail(Email.getText().toString()))
{
mPager.setCurrentItem(mPager.getCurrentItem()+1);
}
else{
Email.setBackground(getResources().getDrawable(R.drawable.border_bottom_red));
}
}
else {
mPager.setCurrentItem(mPager.getCurrentItem() + 1);
Email.setBackground(getResources().getDrawable(R.drawable.border_bottom_white));
}
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
public void choose_dergo(View view)
{
mPager.setCurrentItem(mPager.getCurrentItem()+1);
for (Uri uri: fileUris) {
Images.add(uri.toString());
}
db.addReport(new Report(Category.getSelectedItem().toString(),Description.getText().toString(),"Mitrovice", Address.getText().toString(),this.Date.getText().toString() + " " + Time.getText().toString(), Name.getText().toString(), Email.getText().toString(), Phone.getText().toString(), Images.toArray(new String[Images.size()])));
if(CheckConnectivityService.running==false)
{
Intent stickyService=new Intent(this, CheckConnectivityService.class);
startService(stickyService);
CheckConnectivityService.running=true;
}
}
public void camera_intent(View view)
{
if(image_counter<5)
{
root = Environment.getExternalStorageDirectory()
+ "/SocialAcitivist";
imageFolderPath = root + "/Images";
File imagesFolder = new File(imageFolderPath);
imagesFolder.mkdirs();
Date d = new Date();
CharSequence s = DateFormat.format("hh-mm-ss", d.getTime());
imageName = "img-" + s + ".jpg";
File image = new File(imageFolderPath, imageName);
fileUri = Uri.fromFile(image);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takePictureIntent, CAMERA_VALUE);
}
else{
Toast.makeText(this,"First delete some pictures below",Toast.LENGTH_SHORT).show();
}
}
public void gallery_intent(View view)
{
FilePickerBuilder.getInstance().setMaxCount(5-image_counter)
.setSelectedFiles(filepaths)
.setActivityTheme(R.style.AppTheme)
.pickPhoto(this);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == CAMERA_VALUE) {
fileUris.add(fileUri);
image_counter++;
}
if (requestCode == FilePickerConst.REQUEST_CODE_PHOTO && resultCode == RESULT_OK && data != null)
{
photoPaths = new ArrayList<>();
photoPaths.addAll(data.getStringArrayListExtra(FilePickerConst.KEY_SELECTED_PHOTOS));
for (String photopath : photoPaths)
{
fileUris.add(Uri.fromFile(new File(photopath)));
image_counter++;
}
}
img.add(0, (ImageView)findViewById(R.id.prev1));
img.add(1, (ImageView)findViewById(R.id.prev2));
img.add(2, (ImageView)findViewById(R.id.prev3));
img.add(3, (ImageView)findViewById(R.id.prev4));
img.add(4, (ImageView)findViewById(R.id.prev5));
int img_counter=0;
for(Uri uri:fileUris)
{
img.get(img_counter).setImageURI(uri);
img_counter++;
}
}
public void showTimePickerDialog(View v)
{
DialogFragment newFragment = new TimePickerFragment();
newFragment.show(getSupportFragmentManager(), "timePicker");
}
public void showDatePickerDialog(View v)
{
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getSupportFragmentManager(), "datePicker");
}
public void OpenInformation(MenuItem item)
{
infoDialog=new Dialog(this,R.style.AppTheme_Dark);
infoDialog.setContentView(R.layout.infromation_layout);
infoDialog.show();
}
public void close_info_dialog(View view)
{
infoDialog.dismiss();
}
public void OpenLanguages(MenuItem item)
{
languageDialog=new Dialog(this, R.style.AppTheme_Dark_Dialog);
languageDialog.setContentView(R.layout.language_layout);
languageDialog.show();
}
public void ChangeLanguage(View view)
{
switch (view.getId())
{
case R.id.sq:
if( prefs.getString("language","en").equalsIgnoreCase("en"))
{
selectLanguge("sq", true);
}
break;
case R.id.en:
if( prefs.getString("language","sq").equalsIgnoreCase("sq"))
{
selectLanguge("en", true);
}
break;
}
languageDialog.dismiss();
}
public void removeItem(View view)
{
int img_counter=0;
try{
switch (view.getId())
{
case R.id.prev1:
fileUris.remove(0);
for(Uri uri:fileUris)
{
img.get(img_counter).setImageURI(uri);
img_counter++;
}
img.get(img_counter).setImageURI(null);
break;
case R.id.prev2:
fileUris.remove(1);
for(Uri uri:fileUris)
{
img.get(img_counter).setImageURI(uri);
img_counter++;
}
img.get(img_counter).setImageURI(null);
break;
case R.id.prev3:
fileUris.remove(2);
for(Uri uri:fileUris)
{
img.get(img_counter).setImageURI(uri);
img_counter++;
}
img.get(img_counter).setImageURI(null);
break;
case R.id.prev4:
fileUris.remove(3);
for(Uri uri:fileUris)
{
img.get(img_counter).setImageURI(uri);
img_counter++;
}
img.get(img_counter).setImageURI(null);
break;
case R.id.prev5:
fileUris.remove(4);
for(Uri uri:fileUris)
{
img.get(img_counter).setImageURI(uri);
img_counter++;
}
img.get(img_counter).setImageURI(null);
break;
}
image_counter--;
}
catch(Exception e){}
}
public void openURL(View view) {
String url;
switch (view.getId())
{
case R.id.facebook: url="https://www.facebook.com";
break;
case R.id.twitter: url="https://www.twitter.com";
break;
case R.id.wordpress: url="https://www.facebook.com";
break;
default: url="https://www.facebook.com";
break;
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
public static class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener
{
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
return new TimePickerDialog(getActivity(), R.style.AppTheme_Dark_Dialog, this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute)
{
EditText editTime=(EditText)getActivity().findViewById(R.id.time);
editTime.setText(hourOfDay+":"+minute);
}
}
public static class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener
{
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(getActivity(), R.style.AppTheme_Dark_Dialog, this, year, month, day);
dialog.getDatePicker().setMaxDate(new Date().getTime());
return dialog;
}
public void onDateSet(DatePicker view, int year, int month, int day)
{
EditText editDate=(EditText)getActivity().findViewById(R.id.date);
editDate.setText(year+"-"+month+"-"+day);
}
}
private boolean isValidEmail(String email)
{
String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*#"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
Pattern pattern = Pattern.compile(EMAIL_PATTERN);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
switch (position)
{
case 0: return splashFragment;
case 1: return descFragment;
case 2: return infoFragment;
case 3: return chooserFragment;
case 4: return successFragment;
default: return splashFragment;
}
}
#Override
public int getCount()
{
return NUM_PAGES;
}
}
private void createShortcut()
{
final Intent shortcutIntent = new Intent(this, MainActivity.class);
final Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name));
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher));
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
sendBroadcast(intent);
}
}
then I got the service class
public final class CheckConnectivityService extends IntentService {
Context context = this;
NetworkConnectivityCheck networkConnectivityCheck = new NetworkConnectivityCheck();
public Thread backgroundThread;
public static boolean running = false;
public static boolean stop = false;
public static Intent _intent;
public CheckConnectivityService() {
super("S");
}
#Override
protected void onHandleIntent(Intent intent) {
_intent=intent;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
_intent=intent;
networkConnectivityCheck.register(context);
this.backgroundThread.start();
running = false;
return START_STICKY;
}
#Override
public void onDestroy() {
networkConnectivityCheck.unregister(context);
backgroundThread.interrupt();
}
#Override
public void onCreate() {
this.backgroundThread = new Thread(myTask);
}
private Runnable myTask = new Runnable() {
public void run() {
while (running == true) {
if (stop == true) {
stop = false;
stopSelf();
}
}
}
};
}
and my third class where I check if internet is available if yes upload the form and make the service stop
public class NetworkConnectivityCheck {
public boolean internetAvailable = false;
private BroadcastReceiver networkChangeReceiver;
List<Report> reports;
NetworkConnectivityCheck(){
this.networkChangeReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
int networkState = NetworkUtil.getConnectionStatus(context);
DatabaseHandler db=new DatabaseHandler(context);
if(networkState == NetworkUtil.NOT_CONNECTED){
internetAvailable = false;
} else if(networkState == NetworkUtil.MOBILE){
internetAvailable = true;
//MainActivity.tvStatus.setText("ONLINE"); // you do something here.
} else if(networkState == NetworkUtil.WIFI){
internetAvailable = true;
if(db.getReportsCount()!=0){
reports=db.getAllReports();
for(Report report : reports){
Upload upload=new Upload(report);
Thread doInBackground = new Thread(upload);
doInBackground.start();
}
db.deleteAll();
CheckConnectivityService.running=true;
CheckConnectivityService.stop=true;
}
}
}
};
}
public void register(Context context)
{
context.registerReceiver(networkChangeReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
public void unregister(Context context)
{
context.unregisterReceiver(networkChangeReceiver);
}
public class Upload implements Runnable
{
Report report;
public Upload(Report _report)
{
report=_report;
}
#Override
public void run() {
try {
MediaType MEDIA_TYPE_JPEG = MediaType.parse("image/jpeg");
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build();
MultipartBody.Builder mRequestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
mRequestBody.addFormDataPart("category", report.getCategory());
mRequestBody.addFormDataPart("description", report.getDescription());
mRequestBody.addFormDataPart("city", report.getCity());
mRequestBody.addFormDataPart("address", report.getAddress());
mRequestBody.addFormDataPart("datetime", report.getDateTime());
mRequestBody.addFormDataPart("name", report.getName());
mRequestBody.addFormDataPart("email", report.getEmail());
mRequestBody.addFormDataPart("phone", report.getPhone());
if(report.getImages()[0].trim().length()!=0) {
ArrayList<Uri> fileUris = new ArrayList<>();
for (String uri : report.getImages())
{
fileUris.add(Uri.parse(uri));
}
for (Uri FileUri : fileUris)
{
File file = new File(FileUri.getPath());
RequestBody imageBody = RequestBody.create(MEDIA_TYPE_JPEG, file);
mRequestBody.addFormDataPart("images[]", FileUri.getLastPathSegment(), imageBody);
}
}
RequestBody requestBody = mRequestBody.build();
Request request = new Request.Builder()
.addHeader("Content-Type","text/json; Charset=UTF-8")
.header("Authorization", "Basic bWlsaW5nb25hOlN0")
.url("http://LINK.com")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
} catch (Exception e)
{
e.printStackTrace();
}
Thread.currentThread().interrupt();
return;
}
}
}
and here is the NetworkUtil class in case u want to understand it more
public class NetworkUtil
{
public static final int NOT_CONNECTED = 0;
public static final int WIFI = 1;
public static final int MOBILE = 2;
public static int getConnectionStatus(Context context)
{
ConnectivityManager connectivityManager =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null)
{
if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI)
{
return WIFI;
}
if(networkInfo.getType() == ConnectivityManager.TYPE_MOBILE)
{
return MOBILE;
}
}
return NOT_CONNECTED;
}
}
Somehow you can just register a BroadcastReceiver which shall get the intent for connectivity. No need to implement such logic.
Use below filters in your app Receiver:
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
<action android:name="android.net.wifi.STATE_CHANGE"/>
</intent-filter>
Follow the post below:
BroadcastReceiver when wifi or 3g network state changed
Hope it helps..
You can use an intent service to upload your data, which will be invoked from a dedicated network change broadcast receiver and probably even on click of a submit button as well.
The service will look something like:
public class UploadService extends IntentService {
#Override
protected void onHandleIntent(Intent workIntent) {
int networkState = NetworkUtil.getConnectionStatus(context);
DatabaseHandler db=new DatabaseHandler(context);
if(networkState == NetworkUtil.NOT_CONNECTED){
internetAvailable = false;
} else if(networkState == NetworkUtil.MOBILE){
internetAvailable = true;
//MainActivity.tvStatus.setText("ONLINE"); // you do something here.
} else if(networkState == NetworkUtil.WIFI){
internetAvailable = true;
if(db.getReportsCount()!=0){
reports=db.getAllReports();
for(Report report : reports){
Upload upload=new Upload(report);
Thread doInBackground = new Thread(upload);
doInBackground.start();
}
db.deleteAll();
}
}
}
public class Upload implements Runnable {
Report report;
public Upload(Report _report)
{
report=_report;
}
#Override
public void run() {
try {
MediaType MEDIA_TYPE_JPEG = MediaType.parse("image/jpeg");
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build();
MultipartBody.Builder mRequestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
mRequestBody.addFormDataPart("category", report.getCategory());
mRequestBody.addFormDataPart("description", report.getDescription());
mRequestBody.addFormDataPart("city", report.getCity());
mRequestBody.addFormDataPart("address", report.getAddress());
mRequestBody.addFormDataPart("datetime", report.getDateTime());
mRequestBody.addFormDataPart("name", report.getName());
mRequestBody.addFormDataPart("email", report.getEmail());
mRequestBody.addFormDataPart("phone", report.getPhone());
if(report.getImages()[0].trim().length()!=0) {
ArrayList<Uri> fileUris = new ArrayList<>();
for (String uri : report.getImages())
{
fileUris.add(Uri.parse(uri));
}
for (Uri FileUri : fileUris)
{
File file = new File(FileUri.getPath());
RequestBody imageBody = RequestBody.create(MEDIA_TYPE_JPEG, file);
mRequestBody.addFormDataPart("images[]", FileUri.getLastPathSegment(), imageBody);
}
}
RequestBody requestBody = mRequestBody.build();
Request request = new Request.Builder()
.addHeader("Content-Type","text/json; Charset=UTF-8")
.header("Authorization", "Basic bWlsaW5nb25hOlN0")
.url("http://LINK.com")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
} catch (Exception e)
{
e.printStackTrace();
}
Thread.currentThread().interrupt();
return;
}
}
}
You can refer this official document here: Creating a background service
I want to build an Music-App and my Musicplayer should only stop, if the User touchs on Stop in the notification.
The Music should not stop if the User closes the App (if possible, also if the User cleans the App-History)!
I'm playing music with a Service:
public class MusicService extends Service
implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener,
AudioManager.OnAudioFocusChangeListener {
//region Variables
private MediaPlayer mediaPlayer;
private Song[] sSongs;
private int iSongPosition;
private PlayMode playMode;
private static final int NOTIFY_ID = 1;
private final IBinder musicBinder = new MusicBinder();
private AudioManager audioManager;
private Handler handler;
public ServiceInterface serviceInterface;
private Notification notification;
//endregion
//region Service-Methods
#Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
iSongPosition = 0;
playMode = PlayMode.PASS;
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
int iAudioReqResult = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (iAudioReqResult != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
new AlertDialog.Builder(this)
.setTitle("Sorry.")
.setMessage("Musixs wasn't able to gain the AudioStream garanted!")
.setCancelable(false)
.show();
}
handler = new Handler();
serviceInterface = new ServiceInterface() {
#Override
public void MP_PlayPause() {
if (isPlaying()) {
pause();
}
else {
start();
}
}
#Override
public void MP_PlayPrev() {
playPrev();
}
#Override
public void MP_PlayNext() {
playNext();
}
#Override
public boolean MP_isPlaying() {
return isPlaying();
}
#Override
public int MP_getDuration() {
return getDuration();
}
#Override
public int MP_getCurrentPosition() {
return getCurrentPosition();
}
#Override
public Song MP_getActualSong() {
return getActualSong();
}
#Override
public void MP_seekTo(int pos) {
seekTo(pos);
}
};
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return musicBinder;
}
#Override
public boolean onUnbind(Intent intent) {
mediaPlayer.stop();
mediaPlayer.release();
return super.onUnbind(intent);
}
#Override
public void onCompletion(MediaPlayer mp) {
mp.reset();
if (playMode == PlayMode.REPEAT_SINGLE) {
playSong(iSongPosition);
return;
}
if (playMode == PlayMode.SHUFFLE) {
iSongPosition = new Random().nextInt(sSongs.length);
playSong(iSongPosition);
return;
}
iSongPosition++;
if (iSongPosition == sSongs.length) {
if (playMode == PlayMode.REPEAT_ALL) {
iSongPosition = 0;
playSong(iSongPosition);
}
else {
mp.stop();
mp.release();
}
}
else {
playSong(iSongPosition);
}
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
Intent notIntent = new Intent(getApplicationContext(), PlayActivity.class);
notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent notPendignIntent = PendingIntent.getActivity(getApplicationContext(), 0, notIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PlayActivity.setServiceInterface(serviceInterface);
Notification.Builder nBuilder = new Notification.Builder(this);
nBuilder.setContentIntent(notPendignIntent)
.setSmallIcon(android.R.drawable.ic_media_play)
.setTicker(getActualSong().getTitle())
.setOngoing(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(getActualSong().getTitle());
notification = nBuilder.build();
startForeground(NOTIFY_ID, notification);
}
#Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
}
#Override
public void onAudioFocusChange(int focusChange) {
audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
//endregion
//region Methods
public void setSongs(Song[] songs) {
sSongs = songs;
}
public void setPlayMode(PlayMode mode) {
playMode = mode;
}
public void playSong(int index) {
mediaPlayer.reset();
iSongPosition = index;
Song playSong = sSongs[iSongPosition];
long playSongID = playSong.getID();
Uri trackUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, playSongID);
try {
mediaPlayer.setDataSource(getApplicationContext(), trackUri);
}
catch (IOException ioe) {
ioe.printStackTrace();
}
mediaPlayer.prepareAsync();
}
public void playNext() {
iSongPosition++;
if (iSongPosition == sSongs.length) {
iSongPosition = 0;
}
playSong(iSongPosition);
}
public void playPrev() {
iSongPosition--;
if (iSongPosition < 0) {
iSongPosition = sSongs.length - 1;
}
playSong(iSongPosition);
}
public Song getActualSong() {
return sSongs[iSongPosition];
}
public int getActualSongPosition() {
return iSongPosition;
}
public PlayMode getPlayMode() {
return playMode;
}
//region MediaController-Methods
public void start() {
mediaPlayer.start();
startForeground(NOTIFY_ID, notification);
}
public void pause() {
mediaPlayer.pause();
stopForeground(true);
}
public int getDuration() {
return mediaPlayer.getDuration();
}
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
public void seekTo(int pos) {
mediaPlayer.seekTo(pos);
}
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
public int getBufferPercentage() {
return (mediaPlayer.getCurrentPosition() * 100) / mediaPlayer.getDuration();
}
public boolean canPause() {
return mediaPlayer.isPlaying();
}
public boolean canSeekBackward() {
return mediaPlayer.getCurrentPosition() != 0;
}
public boolean canSeekForward() {
return mediaPlayer.getCurrentPosition() == mediaPlayer.getDuration();
}
//endregion
//endregion
public class MusicBinder extends Binder {
public MusicService getService() {
return MusicService.this;
}
}
And my Service is started in MainActivity:
#Override
protected void onStart() {
super.onStart();
if (playIntent == null) {
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicServiceConn, BIND_AUTO_CREATE);
startService(playIntent);
}
}
My ServiceConnection:
musicServiceConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder musicBinder = (MusicService.MusicBinder) service;
musicService = musicBinder.getService();
bMusicServiceConnected = true;
musicService.setSongs(sSongs);
}
#Override
public void onServiceDisconnected(ComponentName name) {
bMusicServiceConnected = false;
}
};
Actually, my MediaPlayer stops, if I close the app (clear App-History) or press the Back-Button.
The full code:
https://github.com/guger/Musixs
I hope you can help me!
Thanks!
You need to override onStartCommand in the service and return START_STICKY.
From what I can tell, the Uri.parse in my code is causing my MediaPlayer to fail on audio files with special characters in the filename, like "#" and others. I cannot figure out how to resolve this issue. I want to be able to use special characters in my filenames. Here is the code that I think is causing the issue:
public void playAudio(int media) {
try {
switch (media) {
case LOCAL_AUDIO:
/**
* TODO: Set the path variable to a local audio file path.
*/
if (path == "") {
// Tell the user to provide an audio file URL.
Toast
.makeText(
MediaPlayerDemo_Audio.mp,
"Please edit MediaPlayer_Audio Activity, "
+ "and set the path variable to your audio file path."
+ " Your audio file must be stored on sdcard.",
Toast.LENGTH_LONG).show();
}
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setLooping(sound_loop);
mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path));
mMediaPlayer.prepare();
resetTimer();
startTimer();
mMediaPlayer.start();
Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
sendBroadcast(intent);
break;
case RESOURCES_AUDIO:
/**
* TODO: Upload a audio file to res/raw folder and provide
* its resid in MediaPlayer.create() method.
*/
// mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
//mMediaPlayer.start();
}
//tx.setText(path);
} catch (Exception e) {
//Log.e(TAG, "error: " + e.getMessage(), e);
}
}
I am using MediaPlayerDemo_Audio.java to play sounds. As you can see from the above code, the mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path)); is calling the code to retrieve the file and media player, I think. I am not too skilled with android code yet. Here is the code for MediaPlayerDemo_Audio.java:
public class MediaPlayerDemo_Audio extends Activity {
public static String path;
private String fname;
private static Intent PlayerIntent;
public static String STOPED = "stoped";
public static String PLAY_START = "play_start";
public static String PAUSED = "paused";
public static String UPDATE_SEEKBAR = "update_seekbar";
public static boolean is_loop = false;
private static final int LOCAL_AUDIO=0;
private Button play_pause, stop;
private SeekBar seek_bar;
public static MediaPlayerDemo_Audio mp;
private AudioPlayerService mPlayerService;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.media_player_layout);
//getWindow().setTitle("SoundPlayer");
//getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
// android.R.drawable.ic_media_play);
play_pause = (Button)findViewById(R.id.play_pause);
play_pause.setOnClickListener(play_pause_clk);
stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(stop_clk);
seek_bar = (SeekBar)findViewById(R.id.seekBar1);
seek_bar.setMax(100);
seek_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
if (mPlayerService!=null) {
int seek_pos = (int) ((double)mPlayerService.getduration()*seekBar.getProgress()/100);
mPlayerService.seek(seek_pos);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
play_pause.setText("Pause");
stop.setText("Stop");
//int idx = path.lastIndexOf("/");
//fname = path.substring(idx+1);
//tx.setText(path);
IntentFilter filter = new IntentFilter();
filter.addAction(STOPED);
filter.addAction(PAUSED);
filter.addAction(PLAY_START);
filter.addAction(UPDATE_SEEKBAR);
registerReceiver(mPlayerReceiver, filter);
PlayerIntent = new Intent(MediaPlayerDemo_Audio.this, AudioPlayerService.class);
if (AudioPlayerService.path=="") AudioPlayerService.path=path;
AudioPlayerService.sound_loop = is_loop;
startService(PlayerIntent);
bindService(PlayerIntent, mConnection, 0);
if (mPlayerService!=null && mPlayerService.is_pause==true) play_pause.setText("Play");
mp = MediaPlayerDemo_Audio.this;
}
private BroadcastReceiver mPlayerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String act = intent.getAction();
if (act.equalsIgnoreCase(UPDATE_SEEKBAR)){
int val = intent.getIntExtra("seek_pos", 0);
seek_bar.setProgress(val);
TextView counter = (TextView) findViewById(R.id.time_view);
counter.setText(DateUtils.formatElapsedTime((long) (intent.getLongExtra("time", 0)/16.666)));
//tx.setText(fname);
}
else if (act.equalsIgnoreCase(STOPED)) {
play_pause.setText("Play");
seek_bar.setProgress(0);
stopService(PlayerIntent);
unbindService(mConnection);
mPlayerService = null;
TextView counter = (TextView) findViewById(R.id.time_view);
counter.setText(DateUtils.formatElapsedTime(0));
}
else if (act.equalsIgnoreCase(PLAY_START)){
play_pause.setText("Pause");
}
else if (act.equalsIgnoreCase(PAUSED)){
play_pause.setText("Play");
}
}
};
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
mPlayerService = ((AudioPlayerService.LocalBinder)arg1).getService();
if (mPlayerService.is_pause==true) {
play_pause.setText("Play");
seek_bar.setProgress(mPlayerService.seek_pos);
}
if (mPlayerService.mTime!=0) {
TextView counter = (TextView) findViewById(R.id.time_view);
counter.setText(DateUtils.formatElapsedTime((long) (mPlayerService.mTime/16.666)));
}
if (path.equalsIgnoreCase(AudioPlayerService.path)==false){
AudioPlayerService.path = path;
mPlayerService.restart();
}
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
mPlayerService = null;
}
};
private OnClickListener play_pause_clk = new OnClickListener() {
#Override
public void onClick(View arg0) {
if (mPlayerService!=null)
mPlayerService.play_pause();
else{
AudioPlayerService.path=path;
startService(PlayerIntent);
bindService(PlayerIntent, mConnection, 0);
}
}
};
private OnClickListener stop_clk = new OnClickListener() {
#Override
public void onClick(View arg0) {
if (mPlayerService==null) return;
mPlayerService.Stop();
}
};
#Override
protected void onDestroy() {
super.onDestroy();
// TODO Auto-generated method stub
}
}
How can I fix this issue so files can be parsed with special characters and played correctly in MediaPlayer? Am I missing something?
Maybe it would help to show the entire code for my AudioPlayerService:
public class AudioPlayerService extends Service {
public MediaPlayer mMediaPlayer;
protected long mStart;
public long mTime;
public int seek_pos=0;
public static boolean sound_loop = false;
public boolean is_play, is_pause;
public static String path="";
private static final int LOCAL_AUDIO=0;
private static final int RESOURCES_AUDIO=1;
private int not_icon;
private Notification notification;
private NotificationManager nm;
private PendingIntent pendingIntent;
private Intent intent;
#SuppressWarnings("deprecation")
#Override
public void onCreate() {
playAudio(LOCAL_AUDIO);
mTime=0;
is_play = true;
is_pause = false;
CharSequence ticker = "Touch to return to app";
long now = System.currentTimeMillis();
not_icon = R.drawable.play_notification;
notification = new Notification(not_icon, ticker, now);
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Context context = getApplicationContext();
intent = new Intent(this, MediaPlayerDemo_Audio.class);
pendingIntent = PendingIntent.getActivity(context, 0,intent, 0);
PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
//INCOMING call
//do all necessary action to pause the audio
if (is_play==true && is_pause==false){
play_pause();
}
} else if(state == TelephonyManager.CALL_STATE_IDLE) {
//Not IN CALL
//do anything if the phone-state is idle
} else if(state == TelephonyManager.CALL_STATE_OFFHOOK) {
//A call is dialing, active or on hold
//do all necessary action to pause the audio
//do something here
if (is_play==true && is_pause==false){
play_pause();
}
}
super.onCallStateChanged(state, incomingNumber);
}
};//end PhoneStateListener
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
OnAudioFocusChangeListener myaudiochangelistener = new OnAudioFocusChangeListener(){
#Override
public void onAudioFocusChange(int arg0) {
//if (arg0 ==AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK){
if (is_play==true && is_pause==false){
play_pause();
}
//}
}
};
AudioManager amr = (AudioManager)getSystemService(AUDIO_SERVICE);
amr.requestAudioFocus(myaudiochangelistener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
}
#SuppressWarnings("deprecation")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Context context = getApplicationContext();
String title = "VoiceRecorder App";
CharSequence message = "Playing..";
notification.setLatestEventInfo(context, title, message,pendingIntent);
nm.notify(101, notification);
return START_STICKY;
}
public class LocalBinder extends Binder {
AudioPlayerService getService() {
return AudioPlayerService.this;
}
}
public void restart(){
mMediaPlayer.stop();
playAudio(LOCAL_AUDIO);
mTime=0;
is_play = true;
is_pause = false;
}
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
public void Stop()
{
mMediaPlayer.stop();
Intent intent1 = new Intent(MediaPlayerDemo_Audio.STOPED);
sendBroadcast(intent1);
resetTimer();
is_play=false;
is_pause=false;
}
public void play_pause()
{
if (is_play==false){
try {
mMediaPlayer.start();
startTimer();
is_play=true;
is_pause = false;
} catch (Exception e) {
//Log.e(TAG, "error: " + e.getMessage(), e);
}
Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
sendBroadcast(intent);
}
else{
mMediaPlayer.pause();
stopTimer();
Intent intent1 = new Intent(MediaPlayerDemo_Audio.PAUSED);
sendBroadcast(intent1);
is_play = false;
is_pause = true;
}
}
public int getduration()
{
return mMediaPlayer.getDuration();
}
public void seek(int seek_pos)
{
mMediaPlayer.seekTo(seek_pos);
mTime = seek_pos;
}
public void playAudio(int media) {
try {
switch (media) {
case LOCAL_AUDIO:
/**
* TODO: Set the path variable to a local audio file path.
*/
if (path == "") {
// Tell the user to provide an audio file URL.
Toast
.makeText(
MediaPlayerDemo_Audio.mp,
"Please edit MediaPlayer_Audio Activity, "
+ "and set the path variable to your audio file path."
+ " Your audio file must be stored on sdcard.",
Toast.LENGTH_LONG).show();
}
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setLooping(sound_loop);
mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path));
mMediaPlayer.prepare();
resetTimer();
startTimer();
mMediaPlayer.start();
Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
sendBroadcast(intent);
break;
case RESOURCES_AUDIO:
/**
* TODO: Upload a audio file to res/raw folder and provide
* its resid in MediaPlayer.create() method.
*/
// mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
//mMediaPlayer.start();
}
//tx.setText(path);
} catch (Exception e) {
//Log.e(TAG, "error: " + e.getMessage(), e);
}
}
#SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
long curTime = System.currentTimeMillis();
mTime += curTime-mStart;
mStart = curTime;
int pos = (int) ((double)mMediaPlayer.getCurrentPosition()*100/mMediaPlayer.getDuration());
seek_pos = pos;
Intent intent1 = new Intent(MediaPlayerDemo_Audio.UPDATE_SEEKBAR);
if (mMediaPlayer.isLooping()) intent1.putExtra("time", (long)mMediaPlayer.getCurrentPosition());
else intent1.putExtra("time", mTime);
intent1.putExtra("seek_pos", pos);
sendBroadcast(intent1);
if (mMediaPlayer.isPlaying()==false && mMediaPlayer.isLooping()==false){
mMediaPlayer.stop();
resetTimer();
Intent intent2 = new Intent(MediaPlayerDemo_Audio.STOPED);
sendBroadcast(intent2);
is_play=false;
}
if (mTime > 0) mHandler.sendEmptyMessageDelayed(0, 10);
};
};
private void startTimer() {
mStart = System.currentTimeMillis();
mHandler.removeMessages(0);
mHandler.sendEmptyMessage(0);
}
private void stopTimer() {
mHandler.removeMessages(0);
}
private void resetTimer() {
stopTimer();
mTime = 0;
}
#Override
public void onDestroy() {
super.onDestroy();
// TODO Auto-generated method stub
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
nm.cancel(101);
}
}
For local files, do not use Uri.parse(). Use Uri.fromFile(), passing in a File object pointing to the file in question. This should properly escape special characters like #.