Android:
public class LocationService extends Service {
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
startActivity(new Intent(this, activity.class));
}
}
I launched this service from Activity
In Activity if condition satisfies start
startService(new Intent(WozzonActivity.this, LocationService.class));
from my LocationService mentioned above could not launch Activity, how can I get context of current running Activity in service class?
From inside the Service class:
Intent dialogIntent = new Intent(this, MyActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
But, this does not work from Android 10+ due to battery optimisation restrictions
UPDATE ANDROID 10 AND HIGHER
Start an activity from service (foreground or background) is no longer allowed.
There are still some restrictions that can be seen in the documentation
https://developer.android.com/guide/components/activities/background-starts
I had the same problem, and want to let you know that none of the above worked for me.
What worked for me was:
Intent dialogIntent = new Intent(this, myActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(dialogIntent);
and in one my subclasses, stored in a separate file I had to:
public static Service myService;
myService = this;
new SubService(myService);
Intent dialogIntent = new Intent(myService, myActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myService.startActivity(dialogIntent);
All the other answers gave me a nullpointerexception.
Another thing worth mentioning: while the answer above works just fine when our task is in the background, the only way I could make it work if our task (made of service + some activities) was in the foreground (i.e. one of our activities visible to user) was like this:
Intent intent = new Intent(storedActivity, MyActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
storedActivity.startActivity(intent);
I do not know whether ACTION_VIEW or FLAG_ACTIVITY_NEW_TASK are of any actual use here. The key to succeeding was
storedActivity.startActivity(intent);
and of course FLAG_ACTIVITY_REORDER_TO_FRONT for not instantiating the activity again. Best of luck!
one cannot use the Context of the Service; was able to get the (package) Context alike:
Intent intent = new Intent(getApplicationContext(), SomeActivity.class);
You can also use getApplicationContext() method in your Service to run the startActivity() method as written below:
Intent myIntent = new Intent();
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(myIntent);
If you need to recal an Activity that is in bacgrounde, from your service, I suggest the following link. Intent.FLAG_ACTIVITY_NEW_TASK is not the solution.
https://stackoverflow.com/a/8759867/1127429
Alternately,
You can use your own Application class and call from wherever you needs (especially non-activities).
public class App extends Application {
protected static Context context = null;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
public static Context getContext() {
return context;
}
}
And register your Application class :
<application android:name="yourpackage.App" ...
Then call :
App.getContext();
SYSTEM_ALERT_WINDOW.requrid permission in manifest and enable from from mobile seting manully its works from android 10+.
Xiaomi Redmi 4A, Android 7, MIUI 10.2.3. Main activity for app in debug version could not start to foreground from service. There was MIUILOG- Permission Denied Activity error in logcat. Rebuilding this app in release version fixed the problem.
Related
Not sure how to get the receiver to work on the activity once the app is forced closed.
What am I missing to get this to work even if the app was forced closed? Any help would be appreciated.
I am getting the BroadcastReceiver service to work, Just not getting anything to pick up on the activity level.
I have my receiver (Service):
public class MyReceiver extends BroadcastReceiver {
public static final String SEND_NOTIFICATION_ACTION = "com.clover.sdk.app.intent.action.APP_NOTIFICATION";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver", "Triggered MyReceiver");
String action = intent.getAction();
Bundle getIntent = intent.getExtras();
if (action.equals(SEND_NOTIFICATION_ACTION)) {
Log.i("MyReceiver Gotten", "Found");
intent = new Intent("broadCastName");
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("orderId", getIntent.getString("payload"));
Log.i("Receiver OrderID", getIntent.getString("payload"));
context.sendBroadcast(intent);
}
}
}
My Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}
}
Then my broadcastReceiver in my activity:
// Add this inside your class
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("MyReceiver Gotten 2", "Found");
Bundle b = intent.getExtras();
Log.i("MyReceiver Gotten 3", b.getString("orderId"));
new SpecificOrderAsyncTask(MainActivity.this).execute(b.getString("orderId"));
}
};
Not sure how to get the receiver to work on the activity once the app is forced closed. What am I missing to get this to work even if the app was forced closed?
That's contradictory - you can't get a receiver to work in an Activity that registered it at runtime if that Activity that is hosting the receiver is killed. When you force close, every in the app process - including the Activity and the receiver you registered with it - disappears.
The point of calling registerReceiver is to listen for broadcasts only during a specific time frame or lifecycle.
If you want the receiver to work even when the app is closed, don't register it at runtime - register it in the manifest.
Simple,
Registering service in an activity is temporary, registering service in a manifest will run even after closing the application.
But the broadcast you use is a simple message transfer system, that won't work even after you register in manifest and close the application. You have to create a background service that runs always in background in android system and should awake listening to some events passed.
I have a java Class that extends Plugin (PhoneGap), but when inside this class, i call another class that extends Activity, it just doesn't work !. i mean, it seems like it doesn't get called. To confirm this, i have change my second class, this time, not extending from Activity and it works fine. i need teh second one to extends from Activity because i am using this two utilities (getFileStreamPath and openFileOutput) to create a file
File filepath = getFileStreamPath("filename.CPCL"); and openFileOutput
FileOutputStream os = this.openFileOutput(fileName, Context.MODE_PRIVATE);
I have an app with a class which extends a custom Service that calls another class which extends Activity.
First I instantiate the Activity. In the onCreate of your Plugin class use:
// get a handle on your Application
Application app = getApplication();
Intent intent = new Intent(getApplicationContext(), YourActivity.class);
app.startActivity(intent);
This will start your Activity and call the standard Lifecycle events.
The way I handle continued communication with the running Activity is by using a Handler to send a broadcast from your plugin which the Activity picks up in its receiver. In the onCreate of your plugin:
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d(TAG, "Call the Activity");
Intent intent = new Intent(YourActivity.CALL_FROM_PLUGIN);
intent.putExtra("request", <<Any extras you might want to send through>>);
sendBroadcast(intent);
}
});
In the Activity I declare the variable:
public static final String CALL_FROM_PLUGIN= "CALL_FROM_PLUGIN";
then in onCreate() I added the following;
IntentFilter filter = new IntentFilter();
filter.addAction(CALL_FROM_PLUGIN);
registerReceiver(mBroadcastReceiver, filter);
and then implemented a BroadcastReceiver:
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "BroadcastReceiver.onReceive()");
if (CALL_FROM_PLUGIN.equals(action)) {
Log.d(TAG, "Received call from Plugin");
// DO YOUR STUFF HERE
}
}
};
Someone else might be able to point out why this is necessary from a framework point of view, but this is the way I understand that Activities should be called. I hope this applies to your plugin class the way it does with my service class!
Im am trying to pass an instance of my activity to an intent service. The reason for this is the intent service does a lot of background server communication and if there is an network error or the server returns an error I want to display a pop up message.
When i create the service i use this
Intent service = new Intent(this, SyncService.class);
Bundle b2 = new Bundle();
b2.putParcelable(StringsConfig.OBJECT_DELIVERABLES, objects);
service.putExtras(b2);
startService(service);
Is there a way to pass an instance of an Activity over to it. I also have a method inside the SyncService class that accept an Activity but i dont know how to create an instance of the sync service class, pass the activity over via the method, and then start the sync service.
Any help is appreciated.
Its not a great idea to pass an Activity instance to an Intent Service. If your long running Background Service needs to show a dialog message, you are much better off modelling it as an Intent.
Just do:
Intent dialogIntent = new Intent(getApplicationContext(), YourDialogActivity.class);
dialogIntent.putStringExtra(Constants.TITLE, "Your Dialog Title");
dialogIntent.putIntExtra(Constants.MESSAGE, R.string.yourErrorMessageId);
startActivity(dialogIntent);
That way, the service contract is a lot cleaner.
The recommended way for an IntentService to communicate to an activity is via BroadcastReceiver. Take a look at this example:
In the activity that you want your IntentService to communicate with, create a BroadcastReceiver that listens for a specific intent action (a String). Here my example is called batchProcessReceiver, and listens for the BATCH_PROCESS_RECEIVER action. BATCH_PROCESS_RECEIVER can be a public static constant in your Activity.
private BroadcastReceiver batchProcessReceiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BATCH_PROCESS_RECEIVER)) {
// do what you need to do here
}
}
};
In your activity's onResume:
registerReceiver(batchProcessReceiver, new IntentFilter(BATCH_PROCESS_RECEIVER));
onPause:
unregisterReceiver(batchProcessReceiver);
Then at a point in your IntentService, you can do
sendBroadcast(new Intent(MyActivity.BATCH_PROCESS_RECEIVER));
to trigger the action you want to do in your activity.
I have an application in which I have to call off an alarm/notification each 30 Minutes.
I want the feature like
1- If app is closed, it open the app, Call a dialog box. On click it will call a serverFunction and if MainActivity is running, update its UI.
2- If the app is already opened , Call a dialog box. On click it will call a serverFunction. Since MainActivity is may or may NOT on the top, update its UI Or NOT.
In My MainActivity.class
private void callNotification()
{
AlarmManager service = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, i,PendingIntent.FLAG_CANCEL_CURRENT);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, Constants.TIME_CONSTANT);
service.set(AlarmManager.RTC_WAKEUP ,time.getTimeInMillis(), pending);
}
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(final Context context, Intent intent)
{
}
}
The problem here is , I can't put a dialog box in onReceive since context is not Activity context. What If the app is opened , Now how am I suppose to implement above features.
In your onReceive place this to call your activity:
Intent i = new Intent(context, AlertActivity.class);
i.setFlags
startActivity(i);
Once you are in your activity you can open up a dialog.
I recommend you use a different activity than your main one to handle displaying the alert, as it makes sense from a design standpoint and it also makes implementation easier. Remember you can make Activities look like dialogs...
I'm trying to simply set a proximity later for an area an for testing, I simply added this to the onCreate method of my main activity.
public void onCreate(Bundle bndBundle) {
IntentFilter filter = new IntentFilter(WidgetService.ACTION_STOP_PROXIMITY);
registerReceiver(new ProximityIntentReceiver(), filter);
LocationManager locManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
Intent ittIntent = new Intent(this, ProximityIntentReceiver.class);
ittIntent.putExtra(WidgetService.KEY_STOP_IDENTIFIER, 1000);
PendingIntent pitIntent = PendingIntent.getBroadcast(this, 0, ittIntent, 0);
locManager.addProximityAlert(60.15769, 24.94150, 150, -1, pitIntent);
super.onCreate(bndBundle);
getActionBar().setDisplayHomeAsUpEnabled(false);
}
..and here's the simple receiver class that I'm using
public class ProximityIntentReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
#Override
public void onReceive(Context context, Intent intent) {
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");
}
}
}
I'm testing this on my emulator and when I use the DDMS console to set the co-ordinates of the phone manually, I still don't see the log message.
My manifest file doesn't have any special code. I've added the correct permissions and have the code for a simple activity- no services or anything.
I read through a whole bunch of posts on StacKOverflow but I haven't been able to resolve the issue. Am I missing something in my snippet?
You are registering this receiver dynamically, through registerReceiver(), to have it respond to broadcasts whose action string is WidgetService.ACTION_STOP_PROXIMITY.
However, the actual broadcast you are sending is trying to use an explicit Intent, identifying your receiver class. This does not line up with the IntentFilter that you are using with registerReceiver().
Either:
Register your receiver in the manifest and get rid of registerReceiver(), in which case your explicit Intent will work, or
Use new Intent(WidgetService.ACTION_STOP_PROXIMITY) instead of new Intent(this, ProximityIntentReceiver.class), so your Intent lines up with your IntentFilter
You cannot use explicit Intent objects to send broadcasts to receivers registered via registerReceiver(). An explicit Intent will only work with a manifest-registered receiver.
make sure you type in the right coordinates. in DDMS they're reversed, longitude first, then latitude