How to hide the dialer intent while the call still active - java

I've the below code that launch the Dialer intent, and make a call with the given number.
I need to minimize/hide this activity, so I'm making a delay of 15 seconds that call the Press home intent but t is not working.
How can I hide the dialer while it still active (i.e. still making the required call)!
if (isChecked) {
val dial = "tel:12345678"
val phoneIntent = Intent(Intent.ACTION_CALL, Uri.parse(dial))
val startMain = Intent(Intent.ACTION_MAIN).apply {
addCategory(Intent.CATEGORY_HOME)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
val r = java.lang.Runnable {
context.startActivity(startMain)
}
context.startActivity(phoneIntent)
val h = Handler()
h.postDelayed(r, 15000) // will be delayed for 15 seconds
}

I managed it using the below code, but not clear wha is the different between this and the above one in the question:
Thread().run {
context.startActivity(phoneIntent)
Thread.sleep(2000)
context.startActivity(startMain)
}

Related

How to cancel a widget when creating by AppWidgetManager.requestPinAppWidget()?

If the user drags a widget normally to the home screen, then the configuration activity is started (if set). If the activity returns a result code of RESULT_CANCELED, then the widget creation is cancelled.
This is documented here.
Alternativly, to add a widget from an activity, one can use AppWidgetManager.requestPinAppWidget().
But then the configuration activity is not started, and the program should explicitly start it, as documented here.
This is my code that does it:
object StartWidgetConfigureReceiver : BroadcastReceiver() {
const val ACTION_NEW_WIDGET = "ACTION_NEW_WIDGET"
override fun onReceive(context: Context?, intent: Intent?) {
Intent(context, MyWidgetConfigureActivity::class.java).apply {
action = ACTION_APPWIDGET_CONFIGURE
putExtras(intent)
context?.startActivity(this)
}
}
}
val appWidgetManager = AppWidgetManager.getInstance(context)
val myProvider = ComponentName(applicationContext, MyWidgetProvider::class.java)
val successIntent = PendingIntent.getBroadcast(applicationContext, 0,
Intent(StartWidgetConfigureReceiver.ACTION_NEW_WIDGET),
PendingIntent.FLAG_MUTABLE)
appWidgetManager.requestPinAppWidget(myProvider,null, successIntent)
But how to cancel the widget if needed?
Adding resultCode = Activity.RESULT_CANCELED in onReceive does not seem to do it.
(I would need to wait for the result from the configuration activity, but that is not the question. Unless the way of starting the activity is relevant.)

How to perform a custom task from a action button click in notification?

I have a notification in my app and I want to perform a custom task on clicking of the action in the notification. I have done this to add a action:
timerNotificationBuilder.addAction(0, "STOP", null /*What to add here ?*/ );
But, I want to stop a handler from running on click of this action. I have only seen to open activities using this. But, how to stop a handler or any custom task?
Thanks 😀
#Sambhav.K , You need to pass Pending Intent in action button like below code
notificationBuilder.addAction(mCallAction)
val mCallAction = NotificationCompat.Action.Builder(
R.drawable.ic_reject_call,
"Stop",
mPendingIntent
)
val mCallIntent = Intent(context, CustomActionReceiver::class.java)
val mPendingIntent = PendingIntent.getBroadcast(
context, 999,
mCallIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
and create new CustomActionReceiver class and do your stuff what you want like below
class CustomActionReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// Do your Stuff
}}

my Android service won't keep running

I have a service that performs an AsyncTask which calls itself after each completion. As you'll see below, I am starting my service in the foreground. It starts successfully and keeps running as intended while I have it plugged into my computer and spitting output to LogCat. I know this because to test, I have my AsyncTask loop spitting out a notification every 5 minutes. However, when I unplug it from my computer, the notifications don't come! It's as if the service just completely stops after I start it!
NOTE: My service is a regular service, not an IntentService.
Here is my onStartCommand...
#SuppressWarnings("deprecation")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
getData(intent);
self = this;
// Enter foreground state
String title = "Service started.";
String subject = "Service is running.";
String body = "Monitoring...";
Notification notification = new Notification(R.drawable.ic_launcher, title,
System.currentTimeMillis());
if(notificationSounds)
notification.defaults |= Notification.DEFAULT_SOUND;
else
notification.sound = null;
Intent notificationIntent = new Intent(this, MainActivity3.class);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, subject, body, pendIntent);
startForeground(1500, notification);
new BatteryLifeTask(appContext).execute();
return START_NOT_STICKY;
}
Here is my AsyncTask:
// Looping AsyncTask for continuous mode
private class BatteryLifeTask extends AsyncTask<Void, Void, Void> {
// Member variables
Context appContext;
int batteryPct0;
public BatteryLifeTask(Context context) {
super();
appContext = context;
}
protected Void doInBackground(Void... params) {
System.out.println("Entering doInBackground");
// Get the initial battery level
batteryPct0 = getBatteryPercent();
System.out.println("Initial battery percent: " + batteryPct0);
// Check time
Calendar c = Calendar.getInstance();
Date dateNow = c.getTime();
// getTime returns ms, need minutes. 60000ms in a minute.
long currTime = dateNow.getTime() / 60000;
if(currTime >= timeToUse){
finished = true;
stopSelf();
}
System.out.println("Leaving doInBackground");
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(!finished) {
int waitTime = 60000 * interval; // 1 minute is 60000 miliseconds
System.out.println("Entering postExecute. waitTime is " + waitTime);
Runnable r = new Runnable() {
#Override
public void run() {
if(!finished) { // In case postDelayed is pending, avoids extra notification
System.out.println("An interval has passed.");
calculateHelper(batteryPct0);
new BatteryLifeTask(appContext).execute();
}
}
};
Handler h = new Handler();
h.postDelayed(r, waitTime);
}
}
}
And here is my code for creating notifications:
// Method for creating a notification
#SuppressWarnings("deprecation")
void notify0(int id, String title, String subject, String body, boolean playSound){
NotificationManager NM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notify = new Notification(android.R.drawable.
PendingIntent pending = PendingIntent.getActivity(
getApplicationContext(), 0, new Intent(), 0);
notify.setLatestEventInfo(getApplicationContext(), subject, body, pending);
if(playSound)
notify.defaults |= Notification.DEFAULT_SOUND;
else
notify.sound = null;
// Cancel running notification if exists
NM.cancel(id);
// Push notification
NM.notify(id, notify);
}
Can anyone help me? This is driving me insane! My app works PERFECTLY when plugged in and hooked up to USB debugging. But when unplugged, the service seems to completely halt and do nothing.
This is because you are returning START_NOT_STICKY on the Service's onStartCommand().
START_NOT_STICKY if this
service's process is killed while it is started (after returning from
onStartCommand(Intent, int, int)), and there are no new start intents
to deliver to it, then take the service out of the started state and
don't recreate until a future explicit call to
Context.startService(Intent).
You should return START_STICKY instead
START_STICKY If this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then
leave it in the started state but don't retain this delivered intent.
Later the system will try to re-create the service.
Check this service api changes especially the section of Service lifecycle changes.
Return START_STICKY instead of START_NOT_STICKY and review your design. In your case it's better to use the AlarmManager with a 5 minute timeout and then start an IntentService.

Why do Android alarms fire at the same time?

Below is a pretty simple method that takes a Date and an id for an alarm to be fired which starts a countdown. For some reason I don't understand, if I call it once with one date and id 0 and call it again with another date and id 1 (i.e., two different countdowns), Android will fire both alarms at the same time (specifically the first date passed with id 0) so both countdowns start at the same time.
Can anyone tell me why and how to fix it? Thanks!
public void setCountdownAlarm(Date fireTime, int id)
{
// startCountdown will be called at fireTime
BroadcastReceiver startCountdown = new BroadcastReceiver() {
#Override public void onReceive( Context context, Intent theIntent )
{
countdownTimer = new Timer();
countdownTimer.schedule(new TimerTask() {
#Override
public void run() {
onSecondTick(showtime);
}
}, 0, 100); // call every 10th of a second
}
};
this.registerReceiver( startCountdown, new IntentFilter("com.counter.app.CountActivity.COUNT") );
Intent intent = new Intent("com.counter.app.CountActivity.COUNT");
PendingIntent pintent = PendingIntent.getBroadcast( this, id, intent, 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
if (Build.VERSION.SDK_INT >= 19)
manager.setExact(AlarmManager.RTC_WAKEUP, fireTime.getTime(), pintent);
else
manager.set(AlarmManager.RTC_WAKEUP, fireTime.getTime(), pintent);
}
Editing to say that when I waited for the second alarm to fire, Android actually calls startCountdown twice -- once again for each alarm. Help!
I figured out what I did wrong. As explained in answers to similar questions, the second parameter of PendingIntent.getBroadcast (requestCode) must be unique if you want to get a unique pending intent. I took care of that by passing "id".
The second problem was that I registered the BroadcastReceiver each time I called setCountdownAlarm. The BroadcastReceiver should only be registered once, typically in the onCreate method of the activity.

addProximityAlert and KEY_PROXIMITY_ENTERING

In the documentation, when discussing addProximityAlert , the description about Intent confuses me a bit. Specifically this part..
The fired Intent will have a boolean extra added with key
KEY_PROXIMITY_ENTERING. If the value is true, the device is entering
the proximity region; if false, it is exiting.
This may sound like a dumb question but.. how do I get true or false when I'm entering/ or in a certain radius of a location.
I'm not sure how this would work exactly.
Do I have to write my own code and check when I'm in the proximity of my location and then have it return true and false as I'm exiting?
I can't figure it out.
I believe this works in conjunction with a BroadcastReceiver. You might set the addProximityAlert() method to fire the onReceive() method on this receiver, which will provide you an Intent as a parameter and then get that extra Boolean called KEY_PROXIMITY_ENTERING. So, step by step:
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// You need to declare an Intent for your class and declare a PendingIntent on it,
// so it might be passed to the addProximityAlert method as the fifth parameter.
Intent intent = new Intent("com.yourdomain.yourproject.MyAlert");
PendingIntent proxIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
lm.addProximityAlert(your_latitude, your_longitude, RADIUS_IN_METERS, -1, proxIntent);
Explaination of the parameters set here:
your_longitude: The longitude you want to calculate the Radius on
your_latitude: The latitude you want to calculate the Radius on
RADIUS_IN_METERS: This is a constant defined by yourself where you specify the length of the radius you want to trace from the coordinate defined by the above parameters. If you set it to be, for example, 1000, you're saying that if someone gets closer than 1 km to your coordinate, the KEY_PROXIMITY_ENTERING will be true if the previous execution of onReceive() was more distant than 1 km, and analogously otherwise.
-1: This is the time in milliseconds after which the proximity alert will stop. If set to -1, it will never expire.
proxIntent: The proximity Intent that will fire your BroadcastReceiver.
Further, you'll also need this:
IntentFilter filter = new IntentFilter("com.yourdomain.yourproject.MyAlert");
registerReceiver(new AlertOnProximityReceiver(), filter);
This way you're activating the Receiver for the filter you just set. This will fire the onReceive() event on it. So now, there's just one thing left, declare the BroadcastReceiver.
public class AlertOnProximityReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
Boolean getting_closer = intent.getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);
if (getting_closer)
Log.d("Radius", "Hey, I just entered your radius!");
else
Log.d("Radius", "I just exited your radius!");
}
}
---- UPDATE ----
I'm now seeing this in the documentation:
Throws
SecurityException if ACCESS_FINE_LOCATION permission is not present
So make sure you include this permission in your AndroidManifest.xml file.
Using addProximityAlert you specify the "special area" which should fire the proximity alert using the arguments it have (bold)
Parameters
latitude the latitude of the central point of the alert
region
longitude the longitude of the central point of the alert
region
radius the radius of the central point of the alert region, in
meters expiration
time for this proximity alert, in milliseconds, or
-1 to indicate no expiration
intent a PendingIntent that will be used to generate an Intent to fire when entry to or exit from the alert
region is detected
When the user enters the area declared when you called the method the intent is called and inside this you found this extra KEY_PROXIMITY_ENTERING which alerts you if you enter or leave this area.
I don't know really how it works, but it could be something like:
To know it will check if he is in the radius latitude and longitudine, if yes send the intent when he leaves call the intent again passing "false".
The answer to your question is anyway you shouldn't care about this fact, it's done by the System and you don't need to do anything.
The only thing you need to do is to read this extra and use it if you need.
From documentation:
Due to the approximate nature of position estimation, if the device passes through the given area briefly, it is possible that no Intent will be fired. Similarly, an Intent could be fired if the device passes very close to the given area but does not actually enter it.
Use this Code it will help you a lot.
Intent intent = new Intent(PROX_ALERT_INTENT);
PendingIntent proximityIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
locationManager.addProximityAlert(
lat, // the latitude of the central point of the alert region
lon, // the longitude of the central point of the alert region
POINT_RADIUS, // the radius of the central point of the alert region, in meters
PROX_ALERT_EXPIRATION, // time for this proximity alert, in milliseconds, or -1 to indicate no expiration
proximityIntent // will be used to generate an Intent to fire when entry to or exit from the alert region is detected
);
IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
registerReceiver(new ProximityIntentReceiver(orderStatusObject.getBidId()), filter);
Class - for Approximate Alert broadcast
public class ProximityIntentReceiver extends BroadcastReceiver{
private static final int NOTIFICATION_ID = 1000;
public Context mcontext;//Context of calling BroadCast Receiver
private String bidId; //Hold the value of bid Id
public ProximityIntentReceiver() {
// TODO Auto-generated constructor stub
}
public ProximityIntentReceiver(String bidId) {
// TODO Auto-generated constructor stub
this.bidId = bidId;
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String key = LocationManager.KEY_PROXIMITY_ENTERING;
Boolean entering = intent.getBooleanExtra(key, false);
if (entering) {
Log.d(getClass().getSimpleName(), "entering");
}
else {
Log.d(getClass().getSimpleName(), "exiting");
}
sendNotification(context);
}
public void sendNotification(Context mcontext){
// String extra=arg1.getExtras().getString("alert").toString();
long when = System.currentTimeMillis();
String message = "You are near of driver pickup area.";
NotificationManager notificationManager = (NotificationManager) mcontext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher,message, when);
String title = "Proximity Alert!";
Intent notificationIntent = new Intent();
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(mcontext, 0,notificationIntent, 0);
notification.setLatestEventInfo(mcontext, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults = Notification.DEFAULT_ALL;
notificationManager.notify(0, notification);
}

Categories