I have call receiver , after first incoming call , ringtone playing as usual , but after second or more incoming calls sound does not stop playing.
here call receiver :-
public class IncomingCallReceiver extends BroadcastReceiver {
/**
* Processes the incoming call, answers it, and hands it over to the
* WalkieTalkieActivity.
*
* #param context The context under which the receiver is running.
* #param intent The intent being received.
*/
WalkieTalkieActivity wtActivity;
public SipAudioCall.Listener listener;
public SipAudioCall incomingCall = null;
public static Ringtone r;
public int state = 0;
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onReceive(Context context, Intent intent) {
wtActivity = (WalkieTalkieActivity) context;
try {
incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
if (incomingCall.getState() == 3) {
state = 1;
Log.e("BUTTON", "Incoming Call here" + wtActivity.manager);
wtActivity.updateStatus("INCOMING CALL " + incomingCall.getState());
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
r = RingtoneManager.getRingtone(context, uri);
audioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2, AudioManager.FLAG_PLAY_SOUND);
r.play();
wtActivity.setContentView(R.layout.incomig_call);
Log.e("peer profile", incomingCall.getPeerProfile().toString());
}
} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
}
}
}
}
I have static r , to stop r.play , on when call is end , but after calling again , I can hear two ringtones , and when I do end call , one ringtone stop play, but second continuous playing
I do not understand why please help me
If anyone will have same issue . you need just unregister receiver after end call or on reject . this.unregisterReceiver(yourReceiver);
Related
I am trying to develop a simple app which will record the user's activity (accelerometer values) on a txt or csv file.
My app consists of 2 java classes MainActivity and MyService. The MainActivity includes two buttons to start and stop the service and the required permissions. However, the onSensorChanged normally logs for the first 3 minutes after locking the phone (turning off the screen) and then stops logging. As soon as I open the screen the logd starts working again. Same behavior for the records in txt file. I found out that the app seems to be working excellent if I override the battery optimizations. However, I need the phone to also be working in doze mode to save some battery drain. Has anyone else had a similar issue?
Here is my Foreground Service:
public class MyService extends Service implements SensorEventListener {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
private static final String TAG = "MyService";
private Messenger messageHandler;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Context mContext;
private PowerManager.WakeLock wakeLock = null;
//private HandlerThread mSensorThread;
//private Handler mHandler;
#SuppressLint("MissingPermission")
#Override
public void onCreate() {
super.onCreate();
Log.v("shake service startup", "registering for shake");
mContext = getApplicationContext();
//mHandler = new Handler(mSensorThread.getLooper());
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Wakelock :: TAG");
// Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver
// code be called whenever the phone enters standby mode.
//IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
//registerReceiver(mReceiver, filter);
}
/*
// BroadcastReceiver for handling ACTION_SCREEN_OFF.
public BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Check action just to be on the safe side.
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.v("shake mediator screen off","trying re-registration");
// Unregisters the listener and registers it again.
mSensorManager.unregisterListener(MyService.this);
mSensorManager.registerListener(MyService.this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
}
}
};
*/
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
return START_STICKY;
//stopSelf();
//return START_NOT_STICKY;
}
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);
}
}
#Override
public void onDestroy() {
super.onDestroy();
if(mSensorManager != null){
//noinspection MissingPermission
mSensorManager.unregisterListener(MyService.this);
}
//unregisterReceiver(mReceiver);
try{
wakeLock.release();//always release before acquiring for safety just in case
}
catch(Exception e){
//probably already released
Log.e(TAG, e.getMessage());
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onSensorChanged(SensorEvent event) {
Log.d(TAG, "onSensorChanged: " + event.timestamp + " " + event.values[0] + " " + event.values[1] + " " + event.values[2]);
recordAccelValues(String.valueOf(event.timestamp), event.values[0] + " " + event.values[1] + " " + event.values[2]);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void recordAccelValues(String time, String accel_values) {
String record = time + " " + accel_values + "\n";
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
if (Build.VERSION.SDK_INT >= 23) {
File sdcard = Environment.getExternalStorageDirectory();
File dir = new File(sdcard.getAbsolutePath() + "/text/");
if(!dir.exists()) {
dir.mkdir();
}
File file = new File(dir, "dailyRecordsAccel.dat");
FileOutputStream os = null;
try {
os = new FileOutputStream(file, true);
os.write(record.getBytes());
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
As you can see in the code I tried several recommendations from other questions I found, like wakelock and Intent.ACTION_SCREEN_OFF but they didn't seem to work.
Accelerometer stops delivering samples when the screen is off on Droid/Nexus One even with a WakeLock
The only one way to keep alive your service it's to avoid battery optimization for your application. Which is possible within two ways below. Please note! In both cases you will keep device alive, which means that device will never sleep (enter doze states obviously). It's whole point of device sleep, to avoid pending work of background services like yours.
Using Android WakeLocks, For ex. below.
val wakeLock: PowerManager.WakeLock =
(getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager. FULL_WAKE_LOCK, "MyApp::MyWakelockTag").apply {
acquire()
}
}
Changing setting to avoid battery optimization for specific app. As you mentioned in your question.
It is normal behavior. Android delete all proceses to save power. If you want do a job then ask user to keep screen on, else you can use AlarmManager only to call a Service (Intent, Reciver) do "small job" and go to sleep again.
Hello friends i am creating mp3 player application my application is successfully build i want implement click event notification when user goes on background they control media from notification panel my notification also build successfully but problem is that how control music and change image on notification .addaction() when user click on pause the image change to play and when song is play image back change to pause and media player is also and i am also want get songs title, and artist here my code you can easily understand!
public void play(int songindex) {
song = songList.get(songindex);
try {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
Uri uri = Uri.parse("file:///" + song.getGetpath());
mediaPlayer = MediaPlayer.create(mContext, uri);
title.setText(song.getTitle());
artist.setText(song.getArtist());
notificationTitleText=title.getText();
notificationDescText=artist.getText();
handler = VisualizerDbmHandler.Factory.newVisualizerHandler(getApplicationContext(), mediaPlayer);
audioVisualization.linkTo(handler);
mediaPlayer.start();
seekBar.setProgress(0);
seekBar.setMax(100);
updateProgressBar();
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
play.setVisibility(View.GONE);
pause.setVisibility(View.VISIBLE);
play_main.setVisibility(View.GONE);
pause_main.setVisibility(View.VISIBLE);
Animation aniRotate = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.rotate);
rotate.startAnimation(aniRotate);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (checked) {
mediaPlayer.setLooping(true);
mediaPlayer.start();
} else if (isShuffle) {
// shuffle is on - play a random song
Random rand = new Random();
currentSongIndex = rand.nextInt((songList.size() - 1) - 0 + 1) + 0;
play(currentSongIndex);
} else {
// no repeat or shuffle ON - play next song
if (currentSongIndex < (songList.size() - 1)) {
play(currentSongIndex + 1);
currentSongIndex = currentSongIndex + 1;
} else {
// play first song
play(0);
currentSongIndex = 0;
}
}
}
});
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "" + e, Toast.LENGTH_SHORT).show();
}
}
public void shownotification(){
Bitmap largeImage = BitmapFactory.decodeResource(getResources(),R.drawable.dog);
Notification channel = new NotificationCompat.Builder(getApplicationContext(),CHANNEL_ID_1)
.setSmallIcon(R.drawable.ic_music)
.setContentTitle(notificationTitleText
)
.setContentText(notificationDescText)
.setLargeIcon(largeImage)
.addAction(R.drawable.ic_like,"like",null)
.addAction(R.drawable.ic_prev,"prev",null)
.addAction(R.drawable.ic_pause,"pause",null)
.addAction(R.drawable.ic_next,"next",null)
.addAction(R.drawable.ic_dislike,"dislike",null)
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle().
setShowActionsInCompactView(1,2,3))
.build();
mNotificationManagerCompat.notify(1,channel);
}
gettext()method is working fine but it work on first when any clicked event is happen if song play oncomplete and next song is not get text value
I am assuming that you are playing songs from an Activity but this will also work for a service.
Put this in your activity or service
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("com.mypackage.ACTION_PAUSE_MUSIC")){
//Do whatever you want. Ex. Pause
}
//Similarly this can be done for all actions
}};
Make your show notification method like this
public void shownotification(){
Bitmap largeImage = BitmapFactory.decodeResource(getResources(),R.drawable.dog);
Intent pauseIntent = new Intent("com.mypackage.ACTION_PAUSE_MUSIC");
PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 1, pauseIntent, 0);
// Similarly you can create an intent and pending intent pair for each action you want just change the string in intent constructor
Notification channel = new NotificationCompat.Builder(getApplicationContext(),CHANNEL_ID_1)
.setSmallIcon(R.drawable.ic_music)
.setContentTitle(notificationTitleText
)
.setContentText(notificationDescText)
.setLargeIcon(largeImage)
.addAction(R.drawable.ic_like,"like",null)
.addAction(R.drawable.ic_prev,"prev",null)
.addAction(R.drawable.ic_pause,"pause",pausePendingIntent) //like this attach every action with respective pending intent
.addAction(R.drawable.ic_next,"next",null)
.addAction(R.drawable.ic_dislike,"dislike",null)
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(1,2,3))
.build();
mNotificationManagerCompat.notify(1,channel);}
I want to add one more thing to #Kumar Manas answer
i.e We need to register reciever that is being created in activity.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("com.mypackage.ACTION_PAUSE_MUSIC")){
//Do whatever you want. Ex. Pause
}
//Similarly this can be done for all actions
}};
To register your Reciever add these lines in onCreate()
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("com.mypackage.ACTION_PAUSE_MUSIC");
registerReceiver(receiver,intentFilter);
Note: You can add as many actions you want
You may get your answer by following this tutorial "Android Music Player Controls on Lock Screen and Notifications"
I create an application that implements simple geolocation problem: once in, say, 20 minutes, it takes a LatLng coordinate.
For this purpose, from MainActivity, I initiate BroadcastReceiver to work. It instantiates LocationManager to find coordinates, which needs application context.
The problem is: due to memory reasons, Android OS can kill my MainActivity, so, BroadcastReceiver, firing next time, catches null pointer exception, referring to application's context.
Ideas:
I. I could restart the activity inside BroadcastReceiver like this:
#Override
public void onReceive(Context context, Intent intent) {
//start activity
Intent i = new Intent();
i.setClassName("com.test", "com.test.MainActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
but context is null due to killed Activity.
II. Maybe, the paradigm, presented in my solution, too cumbersome?
Maybe here is graceful solution, I even didn't think of?
Well, my code snippet:
public class MainActivity extends AppCompatActivity {
// ...
public void onStartSessionButtonClicked (View view) {
Intent alarmRecIntent = new Intent(this, AlarmReceiver.class);
PendingIntent mAlarmIntent = PendingIntent.getBroadcast(this, 0, alarmRecIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)this.getSystemService(ALARM_SERVICE);
alarmManager.cancel(mAlarmIntent);
alarmManager.setInexactRepeating(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
RConstants.locUpdateInterval,
mAlarmIntent
);
}
}
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive (Context context, Intent intent) {
Context mContext = context;
try {
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
throw new Exception("network provider is not enabled");
}
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDTS,
MIN_DIST_CHANGE_FOR_UPDTS,
locationListener
);
}
catch (Exception e) { /* catch codeblock */ }
}
I really confused myself supposing that context comes NULL to BroadcastReceiver's onReceive() method, when MainActivity is killed by Android OS. The other one pointer came NULL in my code, so it caused exception.
If you interested, please, check out the code snippet below for details:
public class AlarmReceiver extends BroadcastReceiver {
LocationManager mlocationManager = null;
private CountDownTimer cdTimer = null;
private Context mContext;
final private static long MIN_TIME_BW_UPDTS = 1000 * 1; // ms
final private static float MIN_DIST_CHANGE_FOR_UPDTS = 5.0f; // meters
#Override
public void onReceive (Context context, Intent intent) {
mContext = context; // < -- 1 -- >
try {
mlocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
if (!mlocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
throw new Exception("network provider is not enabled");
}
// < -- 2 -- >
cdTimer = new CountDownTimer(RConstants.locUpdateTimeoutUsed, RConstants.locUpdateTimeoutUsed) {
/// other required methods overridden here ...
#Override
public void onFinish() {
mlocationManager.removeUpdates(locationListener);
mlocationManager = null; // < -- 4 -- >
Log.d("ALARM", getCurrentDateTime() + ", timeout");
}
}.start();
mlocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDTS,
MIN_DIST_CHANGE_FOR_UPDTS,
locationListener
);
}
catch (Exception e) {
Log.d("ALARM", getCurrentDateTime() + ", exc: " + e.getMessage()); < -- 5 -- >
}
}
private LocationListener locationListener = new LocationListener() {
/// other required methods overridden here ...
#Override
public void onLocationChanged(Location location) {
cdTimer.cancel();
cdTimer = null;
mlocationManager.removeUpdates(locationListener); // < -- 6 -- >
mlocationManager = null;
String latLng = " {" + location.getLatitude() + ":" + location.getLongitude() + "}";
Log.d("ALARM", getCurrentDateTime() + latLng);
}
}
}
So, context (mark "< -- 1 -- >"), coming to onReceive is not null.
In note "< -- 2 -- >" I instantiate CountDownTimer with constant RConstants.locUpdateTimeoutUsed. The problem is, it defined and assigned outside of AlarmReceiver, so, when my Activity is killed, RConstants.locUpdateTimeoutUsed comes declared, but not defined. So, CountDownTimer constructs with (0, 0) values. That's why it's instance - cdTimer, fires onFinish() hardly being started. Here it cancels update for mLocationManager and sets it to NULL. But before mLocationManager completely stopped, method onLocationChanged manages to work, so, in line < -- 6 -- > caughts exception.
So I'm building an application locker for android.Ive written a service for my locker activity to launch as soon as a particular activity is detected on top on the android application stack.The list of applications to be locked are stored in a table in a database.For the most part my service works fine.But I'm facing some issues which i do not know how to overcome. Any help is greatfully accepted
I want to resolve the following issues.
1) When i press the back button i want my locker activity and The app which was being to locked to stop executing. In my case,the lockeractivity keeps on launching again and again when i press the back button.
2) When a particular app which need to be be locked launches, the app is shown on the screen for a 1 second or 2 before my locker activity gets called.i want my locker activity to be invoked directly.
3) And some times my locker activity is called again once a user has already verified himself which is do not want. (i think this is cause of the timing of the service to check the foreground activity)
My Service
public class LockerService extends Service {
private static final String TAG = "MyService";
String LockedApps[];
String allowedapp = null;
DataBaseHandler handler;
private final static Handler servicehandler = new Handler() {
#Override
public void handleMessage(Message msg) {
}
};
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
handler = new DataBaseHandler(this);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private Runnable checkforeground = new Runnable() {
public void run() {
// / Any thing you want to do put the code here like web service
// procees it will run in ever 1 second
handler.open();
LockedApps = handler.getPackages();
handler.close();
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am
.getRunningAppProcesses();
String foregroundapp = runningAppProcessInfo.get(0).processName
.toString();
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(LockerService.this);
allowedapp = sp.getString("allowedapp", "anon");
if ((Arrays.asList(LockedApps).contains(foregroundapp))
&& (allowedapp.equals(foregroundapp))) {
// do nothing
} else if (Arrays.asList(LockedApps).contains(foregroundapp)) {
// show your activity here on top of
// PACKAGE_NAME.ACTIVITY_NAME
Intent lockIntent = new Intent(getBaseContext(), Locker.class);
lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getBaseContext().startActivity(lockIntent);
}
servicehandler.postDelayed(this, 1500); // 1.5 seconds
}
};
#Override
public void onStart(Intent intent, int startId) {
servicehandler.removeCallbacks(checkforeground);
servicehandler.postDelayed(checkforeground, 1500);// 1.5 second
Log.d(TAG, "onStart");
}
}
Just Override onBackPressed() method in locker activity and fire a intent to the home launcher. that is nothing but it will takes you to the home screen.
I need to close the current activity from a broadcast receiver. I'm not sure how to call finish from it, maybe there is a way to simulate a "Back" key keypress. Any implementation will be fine as long as it does the job.
#Override
public void onReceive(Context context, Intent intent) {
// How can I finish the current activity here?
}
At your broadcast receiver write:
YourCurrentActivityName.this.finish();
Or you can terminate the front activity with this.finish(); so the last open in stuck comes to front.
Update:
Code for first case:
Use of broadcast receiver to terminate activity at back stack:
public class ActivityFirstName extends Activity {
private BroadcastReceiver mFinishReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// other code
if (mFinishReceiver == null) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.ACTION_TERMINATE");// a string to identify your action
mFinishReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// How can I finish the current activity here?
if ("com.example.ACTION_TERMINATE".equals(intent.getAction())) {
ActivityFirstName.this.finish();
}
}
};
registerReceiver(mFinishReceiver, intentFilter);
}
// other code
}
#Override
protected void onDestroy() {
super.onDestroy();
if (isFinishing()) {
if (mFinishReceiver != null) {
unregisterReceiver(mFinishReceiver);
}
}
}
}
And the front/current running activity, the sender of the broadcast:
public class ActivitySecondName extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
// code code code
final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Perform action on click
terminateBackActivities();
}
});
}
private void terminateBackActivities() {
Intent i = new Intent("com.example.ACTION_TERMINATE"); // the two action strings MUST be same
// i.putExtra(...); // to send extra data
sendBroadcast(i);
}
}
You can simply call this.finish();
Assuming from your comment that the BroadcastReceiver is not an internal class of the activity, here is what you should do: Rather than having the broadcast receiver in a separate class, define it inside your activity like so:
private BroadcastReceiver mFinishReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent){
YourActivity.this.finish();
}
};
Then, you will want to register the receiver in onResume() as such:
#Override
public void onResume(){
super.onResume();
registerReceiver(mFinishReceiver, new IntentFilter(yourIntentAction));
}
You will also want to unregister this receiver in onPause() so you don't leak it:
#Override
public void onPause(){
super.onPause();
unregisterReceiver(mFinishReceiver);
}
Then you can remove the other receiver that had its own separate class and also remove its definition in the manifest. The above example will ensure that you can always call finish() with no issues because the receiver is only registered when the activity is running, as it is internal to the activity's class.
EDIT: Change the methods to onCreate() and onDestroy() rather than onPause() and onDestroy(), according to madlymad's comment.
The ActivityManager class can give you the current foreground activity (even if it's not from your app). The getRunningTasks methods will give you a list of the running tasks, the first element of the list being the most recent launched activity.Unfortunately,this method will just give you an object of type RecentTaskInfo , not the activity itself, so there is no way to call its finish() method,I believe :/
On the other hand, if you want to close the current activity from your app, you can implement a static variable on a personal class that each activiy would set in their onResume() method. This way you will always know what activity is the current one. But I guess it's not what you are looking for.
Edit: The getRunningTasks is just intended for debug purposes, as says the doc..
As suggested by other answers you can simply call finish() on the activity in the broadcast receiver code or you can even trigger a back button press key event yourself.
this.dispatchKeyEvent(new Keyevent(ACTION_DOWN, KEYCODE_BACK));
Not sure about whether this is helpfull to you or not but its help me once and i think thats a same case here so i am answering for you.
Whenever the broadcast receiver get call, you can navigate to any activity by clicking on that broadcast message.
Just like:
#Override
public void onReceive(Context context, Intent intent) {
// My Notification Code
notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.app_icon;
//System.out.println("The ID Number is: "+Long.parseLong(intent.getData().getSchemeSpecificPart()) );
contentText = intent.getStringExtra("MyMessage");
System.out.println("The Message is: "+intent.getStringExtra("MyMessage"));
CharSequence text = "Your tax amount due period";
CharSequence contentTitle = "Tax Toolbox";
long when = System.currentTimeMillis();
intent = new Intent(context, MenuPageActivity.class); // here i am calling activity
intent.putExtra("sixMonth", "sixMonth");
intent.putExtra("messageSixMonth", contentText);
PendingIntent contentIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification = new Notification(icon,text,when);
long[] vibrate = {0,100,200,300};
notification.vibrate = vibrate; // To vibrate the Device
notification.ledARGB = Color.RED;
notification.ledOffMS = 300;
notification.ledOnMS = 300;
notification.defaults |= Notification.DEFAULT_LIGHTS;
//notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(com.project.TaxToolbox.NotificationConstants.NOTIFICATION_ID_SIX_MONTH, notification);
}
Now, on the onCreate() of that activity you have to identify whether it is call by Notification or not.
As like:
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
System.out.println("The Extra for twoMonth is: "+getIntent().hasExtra("twoMonth"));
System.out.println("The Extra for sixMonth is: "+getIntent().hasExtra("sixMonth"));
System.out.println("The Extra for EveryMonth is: "+getIntent().hasExtra("everyMonth"));
if(getIntent().hasExtra("sixMonth")){
notificationManager.cancel(NotificationConstants.NOTIFICATION_ID_SIX_MONTH);
final AlertDialog alert3 = new AlertDialog.Builder(MenuPageActivity.this).create();
alert3.setTitle("Tax Toolbox");
alert3.setMessage(getIntent().getExtras().getString("messageSixMonth"));
alert3.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alert3.setIcon(R.drawable.app_icon);
alert3.show();
// here you can do anything more or close the activity.
}
Not sure but might be helpfull to you.
Feel free to comments if it help you.
Create a common Activity class and extend this common class from all activities, that way you can have a centralized code. Have a register the broadcast receiver in onStart of the activity and unregister in onStop that way only one activity, the one which is visible will be registered for the broadcast intent.
Sample code:
public class BaseActivity extends Activity {
/*
* (non-Javadoc)
*
* #see android.app.Activity#onCreate(android.os.Bundle)
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(receiver, new IntentFilter(YOUR_INTENT_FILTER));
}
/*
* (non-Javadoc)
*
* #see android.app.Activity#onStop()
*/
protected void onStop(){
unregisterReceiver(receiver);
}
/*
* (non-Javadoc)
*
* #see android.app.Activity#onStart()
*/
protected void onStart(){
super.onStart();
registerReceiver(receiver, new IntentFilter(YOUR_INTENT_FILTER));
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
/*
* (non-Javadoc)
*
* #see
* android.content.BroadcastReceiver#onReceive(android.content.Context,
* android.content.Intent)
*/
#Override
public void onReceive(Context context, Intent intent) {
onBackPressed();//on back pressed simply calls finish()
}
};
} // End of BaseActivity
// End of File
Try using:
Intent i = new Intent(context,intent.getClass());
Follow the instructions from gezdy on How to get current foreground activity context in android? to ensure you can get a reference to the current activity from anywhere in your application.
From there you can call .finish() to close the current activity.
Place finish(); after u completed all the tasks in onReceive() of BroadcastReceiver class as below:
#Override
public void onReceive(Context context, Intent intent) {
// Do all the tasks onReceive of BroadCast Receiver
finish(); // This finishes the current activity here....
}