I'm trying to make a countdown timer screen on Android that will continue to count down if you back out of the app or go to different screens in the app or whatever. I'm running it as a Service but I'm still getting the problem of it starting over when I re-open the activity. Any help would be great. Here's my code.
Service Class
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
public class CountdownService extends Service{
public static final String
ACTION_LOCATION_BROADCAST = CountdownService.class.getName() + "LocationBroadcast";
#Override
public void onCreate() {
super.onCreate();
new CountDownTimer(360000, 60000) {
public void onTick(long millisUntilFinished) {
int timeLeftInt = (int) Math.ceil((double) millisUntilFinished / 60000); //Whole number of minutes left, ceiling
sendBroadcastMessage(timeLeftInt);
if(timeLeftInt == 5){
Notify("Not Done");
}
}
public void onFinish() {
sendBroadcastMessage(0);
Notify("done");
}
}.start();
}
private void sendBroadcastMessage(int timeSent) {
Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
intent.putExtra("timeSent", timeSent);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void Notify(String doneness){
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Map.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
if(doneness.equals("done")) {
Notification n = new Notification.Builder(this)
.setContentTitle("Time to leave!")
.setContentText("Your PrePark spot has expired, time to go home!")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(0, n);
}
else{
Notification n = new Notification.Builder(this)
.setContentTitle("Ya got 5 minutes left in your PrePark spot!")
.setContentText("Better get going soon here")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(0, n);
}
}
Main Activity
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.os.Bundle;
import android.widget.TextView;
public class Countdown extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_countdown);
LocalBroadcastManager.getInstance(this).registerReceiver(
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
TextView textView= findViewById(R.id.t1);
int timeLeft = intent.getIntExtra("timeSent", 0);
if(timeLeft>0) {
textView.setText("You have " + timeLeft + " minutes left");
}
else{
textView.setText("Y'all outta time, see ya again soon!");
}
}
}, new IntentFilter(CountdownService.ACTION_LOCATION_BROADCAST)
);
}
#Override
protected void onResume() {
super.onResume();
startService(new Intent(this, CountdownService.class));
}
#Override
protected void onPause() {
super.onPause();
stopService(new Intent(this, CountdownService.class));
}
}
XML for main activity
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerInParent="true"
android:textSize="32sp"
/>
</RelativeLayout>
Probably this happens because you're starting countdown service in onResume() and you're stopping the service in onPause()
And also in the onCreate() method of your service you're creating new instance from countdown timer.
Related
Here is my fully functional code in which when I press the button, the button gets disabled and the countdown timer gets started and whenever it gets over button gets enabled. My problem is that if I leave that activity the process resets.
My question is how that can be done in the background so even if I close the application the timer runs in the background?
package com.mycompany.myapp;
import android.app.*;
import android.os.*;
import android.widget.*;
import android.view.View.*;
import android.view.*;
public class MainActivity extends Activity {
Button btnCountdown;
TextView tvCountdown;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnCountdown = findViewById(R.id.btnCountdown);
tvCountdown = findViewById(R.id.tvCountdown);
btnCountdown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Timer();
btnCountdown.setEnabled(false);
}
});
}
private void Timer() {
new CountDownTimer(30*1000,1000) {
#Override
public void onTick(long millisUntilFinished) {
long second = (millisUntilFinished / 1000) % 60;
long minutes = (millisUntilFinished / (1000*60)) % 60;
tvCountdown.setText(minutes + ":" + second);
}
#Override
public void onFinish() {
tvCountdown.setText("Fin");
btnCountdown.setEnabled(true);
}
}.start();
}
}
Add to your AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
BroadcastReceiver.java
public class BroadcastReceiver extends AppCompatActivity {
TextView tvTimer, tvTimerRunningState, tvTimerFinishedState;
private static final String TAG = "CountdownTimer";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast_receiver);
}
public void handleStartTimer(View view) {
Intent intent = new Intent(this, BroadcastService.class);
intent.putExtra("inputExtra", "");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ContextCompat.startForegroundService(this, intent);
} else {
this.startService(intent);
}
Log.i(TAG, "timerStarted");
}
public void handleCancelTimer (View view) {
Intent intent = new Intent(this, BroadcastService.class);
stopService(intent);
}
/* CountDown */
final private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(BroadcastService.COUNTDOWN_BR));
Log.i(TAG, "Registered broadcast receiver");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
Log.i(TAG, "Unregistered broadcast receiver");
}
#Override
public void onStop() {
try {
unregisterReceiver(broadcastReceiver);
} catch (Exception e) {
// Receiver was probably already stopped in onPause()
}
super.onStop();
}
private void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
long millisUntilFinished = intent.getLongExtra("countdown", 0);
long seconds = (millisUntilFinished / 1000) % 60;
long minutes = (millisUntilFinished / (1000*60)) % 60;
long hours = (millisUntilFinished / (1000*60*60)) % 60;
String time = (hours + " : " + minutes + " : " + seconds);
tvTimer = findViewById(R.id.tvTimer);
tvTimer.setText(time);
boolean countdownTimerRunning = intent.getBooleanExtra("countdownTimerRunning", false);
tvTimerRunningState = findViewById(R.id.tvTimerRunningState);
if (countdownTimerRunning) {
tvTimerRunningState.setText("CountdownTimerRunning");
} else {
tvTimer.setText("0 : 0 : 0");
tvTimerRunningState.setText("CountdownTimerNotRunning");
}
boolean countdownTimerFinished = intent.getBooleanExtra("countdownTimerFinished", false);
tvTimerFinishedState = findViewById(R.id.tvTimerFinishedState);
if (countdownTimerFinished) {
tvTimerFinishedState.setText("Finished");
} else {
tvTimerFinishedState.setText("Unfinished");
}
}
}
activity_broadcast_receiver.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/btnStartJob"
android:onClick="handleStartTimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Timer" />
<Button
android:id="#+id/btnStopJob"
android:onClick="handleCancelTimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cancel Timer" />
<TextView
android:id="#+id/tvTimer"
android:text="0 : 0 : 0"
android:gravity="center"
android:textSize="30sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvTimerFinishedState"
android:gravity="center"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvTimerRunningState"
android:gravity="center"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
BroadcastService.java
public class BroadcastService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
private final static String TAG = "BroadcastService";
public static final String COUNTDOWN_BR = "your.package.name";
Intent bi = new Intent(COUNTDOWN_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Starting timer...");
cdt = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
bi.putExtra("countdown", millisUntilFinished);
bi.putExtra("countdownTimerRunning", true);
bi.putExtra("countdownTimerFinished", false);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
bi.putExtra("countdownTimerFinished", true);
sendBroadcast(bi);
stopForeground(true);
stopSelf();
}
}; cdt.start();
}
#Override
public void onDestroy() {
cdt.cancel();
Log.i(TAG, "Timer cancelled");
bi.putExtra("countdownTimerRunning", false);
sendBroadcast(bi);
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
/* Notification */
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, BroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
/* NotificationBuilder */
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
return START_NOT_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent arg0) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
I'm trying to update the timer in the notification in HH:MM:SS format. I have a Service class where the timer is incremented. I can only display the seconds in the notification. I have some trouble with displaying the time in the mentioned format.
This is MyService.java class
package com.alfen.timerservice;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
public class MyService extends Service {
private static final String TAG = "MyService";
private static final String CHANNEL_ID = "NotificationChannelID";
static int sec = 0;
Timer timer;
public MyService() {
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
startService(restartServiceIntent);
super.onTaskRemoved(rootIntent);
}
#Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
sec = intent.getIntExtra("sec", 0);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void run() {
Intent intent = new Intent();
intent.setAction("Timer");
sec++;
String ty = setTime(sec); //Also can I do this? I think this is throwing some exception
try{NotificationUpdate(sec,ty);}catch(Exception e){}
intent.putExtra("sec", sec);
sendBroadcast(intent);
}
}, 0, 1000);
// toast("MyService is running");
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
timer.cancel();
toast("Timer Stopped");
Intent intent = new Intent();
intent.putExtra("flag", false);
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void NotificationUpdate(Integer sec, String t) {
Intent notificationIntent = new Intent(this,MainActivity.class);
final PendingIntent pendingIntent = PendingIntent
.getActivity(this,0,notificationIntent,0);
Notification notification = new NotificationCompat.Builder(this,CHANNEL_ID)
.setContentTitle("Timer")
.setContentText(sec.toString()) //this is working fine
// .setContentText(t)
//When I try to do this the app crashes when the service is started
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentIntent(pendingIntent)
.build();
startForeground(1,notification);
NotificationChannel nc = new NotificationChannel(CHANNEL_ID,"Timer Notification"
,NotificationManager.IMPORTANCE_NONE);
NotificationManager nm = getSystemService(NotificationManager.class);
nm.createNotificationChannel(nc);
nm.notify(1,notification);
}
private String setTime(int sec) {
int hours = sec / 3600;
int mins = (sec%3600) /60;
int secs = sec % 60;
String t = String.format(Locale.getDefault(),"%02d:%02d:%02d",hours,mins,secs);
toast(t);
return t;
}
public void toast(String s){
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
}
}
Whenever I try to call the setTime() function inside onStartCommand the app keeps crashing
If I change the function like this (without passing the String argument) its working.
public void NotificationUpdate(Integer sec) {
Intent notificationIntent = new Intent(this,MainActivity.class);
final PendingIntent pendingIntent = PendingIntent
.getActivity(this,0,notificationIntent,0);
Notification notification = new NotificationCompat.Builder(this,CHANNEL_ID)
.setContentTitle("Timer")
.setContentText(sec.toString())
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentIntent(pendingIntent)
.build();
How do I solve this? Also how to do the same using a custom Notification layout using RemoteViews?
The simple trick is that update your notification data and call notification with different notification id when time is changed. Hope it will work.
I am trying to update a ProgressBar from a Service task. I implemented a BroadcastReceiver so that I can interact with the UI thread. I update the ProgressBar in the main activity, and receive the data from the MyService activity. The MyService activity executes an Async task and updates the intent that should be sent back in the OnProgressUpdate method.
Here is my code:
MainActivity:
package com.example.services;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.ProgressBar;
import static android.content.Intent.ACTION_ATTACH_DATA;
public class MainActivity extends AppCompatActivity {
private MyBroadRequestReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
receiver = new MyBroadRequestReceiver();
registerReceiver( receiver, filter);
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
//pb.setProgress();
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
public class MyBroadRequestReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
int progress = intent.getFlags();
pb.setProgress(progress);
}
}
}
MyService:
package com.example.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly();
try {
new DoBackgroundTask().execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (timer != null){
timer.cancel();
}
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}
private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
//Intent broadcastIntent = new Intent();
//broadcastIntent.setAction(Intent.ACTION_ATTACH_DATA);
//sendBroadcast(broadcastIntent);
publishProgress((int) (((i + 1) / (float) count) * 100));
}
return totalBytesDownloaded;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.example.services.MainActivity");
//broadcastIntent.putExtra("progress",progress);
broadcastIntent.setFlags(progress[0]);
sendBroadcast(broadcastIntent);
Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded-"+counter,
Toast.LENGTH_LONG).show();
}
protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
//stopSelf();
}
}
private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}
}
Please take a look at my onProgressUpdate and tell me if I am doing this correclty. My ProgressBar is not being updated at all.
Because you don't startService ononCreate() Method. Service will not run.
Firs of all this is not good solution to the problem your solving. Please go through Google Android docs Backgournd guide
I suggest you should switch to DownloadManager.
Your intent filter is defining to "ACTION_ATTACH_DATA"
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
So, send your broadcast like this:
Intent i = new Intent(ACTION_ATTACH_DATA);
sendBroadcast(i);
Also, don't forget to unregister the broadcast at onDestroy
I have created a background stream music playing service for one of my project. It's works correctly but when playing I got a call and the media didn't stopped like in other apps. Also when I answered the call music still played.
package mypackage;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;
import android.support.v7.app.NotificationCompat;
import android.widget.Toast;
import mypackage.R;
public class StreamPlayer extends Service implements OnCompletionListener {
MediaPlayer mediaPlayer;
Notification noti;
android.support.v4.app.NotificationCompat.Builder noticom;
NotificationManager notiman;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Toast.makeText(StreamPlayer.this, "Buffering", Toast.LENGTH_LONG).show();
}
});
try {
mediaPlayer.setDataSource("http://149.56.185.83:8138/stream");
mediaPlayer.prepare();
}catch (Exception ex){
}
mediaPlayer.setOnCompletionListener(this);
noticom = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setCategory(MEDIA_SESSION_SERVICE)
.setAutoCancel(true)
.setContentTitle("Sample Streamed Music Player")
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentText("Now Playing")
.setCategory(NotificationCompat.CATEGORY_EVENT);
notiman = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
Toast.makeText(StreamPlayer.this, "Now Playing", Toast.LENGTH_SHORT).show();
noti = noticom.build();
notiman.notify(2017,noti);
}
return START_STICKY;
}
public void onDestroy() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
noticom.setOngoing(false);
noticom.setContentText("Stopped");
Toast.makeText(StreamPlayer.this, "Stopped", Toast.LENGTH_SHORT).show();
noti = noticom.build();
notiman.notify(2017,noti);
}
mediaPlayer.release();
}
public void onCompletion(MediaPlayer _mediaPlayer) {
stopSelf();
}
}
Does any one know how to fix that?
First return it as Service.START_REDELIVER_INTENT;
Second call startForeground(int id, notificationFunction());
and this can be notificationFunction()
Notification notificationFunction(){
Notification.Builder mBuilder = new Notification.Builder(this);
/*customize notification*/
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
return mBuilder.build();
}
also for Music Player you need to check this
I found the solution.
Thanks for the support. :)
public class MyActivity extends Activity implements OnAudioFocusChangeListener {
private AudioManager mAudioManager;
#Override
public void onCreate(Bundle savedInstanceState) {
...
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
...
}
#Override
public void onDestroy(){
super.onDestroy();
...
mAudioManager.abandonAudioFocus(this);
...
}
#Override
public void onAudioFocusChange(int focusChange) {
if(focusChange<=0) {
//LOSS -> PAUSE
} else {
//GAIN -> PLAY
}
}
I created a simple service and now I am making a notification for this. I am writing a class for notification. After writing all code, three lines are underlined with red color one is this function getSystemService(ns); at line 14, second is this one getApplicationContext(); on line 20 and the third one is again same function as first one but on line 31 in cancelNotification() function. here is my complete code
package com.zafar.batterynotify;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
public class Notify {
private static final int NOTIFICATION_ID = 1;
public void initNotification() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "Service Started";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
notification.flags = Notification.FLAG_ONGOING_EVENT;
Context context = getApplicationContext();
CharSequence contentTitle = "Ongoing service";
CharSequence contentText = "This is service is ongoing";
Intent notificationIntent = new Intent(context, BatteryNotify.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
public void cancelNotification() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
mNotificationManager.cancel(NOTIFICATION_ID);
}
}
Edit Updated code
My service class
package com.zafar.batterynotify;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class BatteryService extends Service {
Notify notification = new Notify();
String ns = Context.NOTIFICATION_SERVICE;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
notification.initNotification(Context.NOTIFICATION_SERVICE);
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
public void onDestroy() {
super.onDestroy();
notification.cancelNotification(Context.NOTIFICATION_SERVICE);
Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
}
}
Notify class
package com.zafar.batterynotify;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
public class Notify {
private static final int NOTIFICATION_ID = 1;
public void initNotification(Context actContext) {
//String ns = Context.NOTIFICATION_SERVICE;
//Context context = actContext.getApplicationContext();
NotificationManager mNotificationManager = actContext.getSystemService(ns);
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "Service Started";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
notification.flags = Notification.FLAG_ONGOING_EVENT;
Context context = actContext.getApplicationContext();
CharSequence contentTitle = "Ongoing service";
CharSequence contentText = "This is service is ongoing";
Intent notificationIntent = new Intent(context, BatteryNotify.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
public void cancelNotification(Context actContext) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = actContext.getSystemService(ns);
mNotificationManager.cancel(NOTIFICATION_ID);
}
}
don't try to use getApplicationContext(), instead create MyApplication class, inherited from the Application, then inside that class do the following:
public class MyApplication extends Application {
private static MyApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
.........
}
public static Context getContext() {
return instance;
}
After that, you may use MyApplication.getContext() anywhere if you need a context and don't have an Activity lying around.
Pass your context from calling Activity or service to your class and use it:
public void initNotification(Context actContext) {
//...
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = actContext.getSystemService(ns);
//...
}
public void cancelNotification(Context actContext) {
//...
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = actContext.getSystemService(ns);
//...
}