I need to have a service in background working on Android.
I made this service:
public class ServizioBackgrounds extends IntentService {
public static int DEFAULT_PORT = 35500;
private static int BUF_SIZE = 11;
private static ....
private static ....
public ServizioBackgrounds() {
super("ServizioBackground");
}
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("##### Servizio Attivato #####");
super.onStart(intent, startId); // If I don't use, the onHandleIntent method ins't call
return START_STICKY;
}
public void onDestroy(){
System.out.println("### Servizio Terminato ###");
Intent startService = new Intent("com.perseusgalaxia.interphone_citofono"); // Try.. But this method is never called
startService.putExtra("AccendiServ", "AccendiServ");
sendBroadcast(startService);
}
#Override
protected void onHandleIntent(Intent intent) {
System.out.println("##### SIAMO DENTRO #####");
DatagramSocket socketAttesa = null;
System.out.println("*** IL SERVIZIO E' ATTIVO ***");
while(true){
...
}
}
}
Then I have this BroadcasterReceiver:
public class BootCompletedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("*** Broadcast Ricevuto ***");
context.startService(new Intent(context,ServizioBackgrounds.class));
}
}
And this is the manifest:
<service android:name=".ServizioBackground"
/>
<receiver android:name=".BootCompletedReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="com.perseusgalaxia.interphone_citofono" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
This is the part where I start the service for the first time:
Intent startService = new Intent("com.perseusgalaxia.interphone_citofono");
startService.putExtra("AccendiServ", "AccendiServ");
sendBroadcast(startService);
I call the service in this way just for try.
The problem is that if I start from the app activity the service it start and works fine, but when I close the app the service is close too.
The amazing thing is that if I restart the smartphone the service start in background (without any activity shown etc.) and it works fine. Then (after reboot) if I start the app and close them the service come be closed!
Sorry for my english.
Thank's for answer.
To run your service in the background you need to call startForeground from your service.
Here's an example:
int serviceId = 101;
NotificationCompat.Builder b = new NotificationCompat.Builder(getApplicationContext());
b.setContentTitle("Working...")
.setContentText("I'm working!")
.setSmallIcon(R.mipmap.ic_launcher);
startForeground(serviceId, b.build());
Note that if your service runs in the background you must show a notification, so the user is notified about your work.
Related
Edit
Everybody thank you for reply,
unfortunately it was impossible to do this work at after Android Pie
https://nllapps.com/apps/acr/android9.htm
https://issuetracker.google.com/issues/112602629
I cannot keep the broadcast receiver running after the application is closed, I tried many methods but failed.
public class BoothService extends Service {
private final Handler mHandler = new Handler();
public BoothService() {
}
private String INCOMING_CALL_ACTION = "android.intent.action.PHONE_STATE";
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String mAction = intent.getAction();
if(mAction.equals(INCOMING_CALL_ACTION)) {
Toast.makeText(context, "BoothService", Toast.LENGTH_SHORT).show();
}
}
};
public void onCreate() {
IntentFilter intentToReceiveFilter = new IntentFilter();
intentToReceiveFilter.addAction(INCOMING_CALL_ACTION);
this.registerReceiver(receiver, intentToReceiveFilter, null, mHandler);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This service run from activitymain
Intent BS = new Intent(ActivityMain.this, BoothService.class);
startService(BS);
my purpose is to capture incoming calls, even if the application is closed
My manifest
<receiver
android:name=".RingReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
permission,
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
by the way this code works in the emulator ,but it doesn't work on real devices I've tried
Try to use JobService for register your implicit broadcast because after nought implicit broadcast is not working when app is close.
So register your broadcast reciever to jobservice and use schedule that service with jobservice.
Or you can refer this link as well
https://www.journaldev.com/23653/android-oreo-implicit-and-explicit-broadcast-receiver
I am developing a background services and in OnDestroy Method, I've called an intent to start my services again. I'ts not started again on miui rom (Xiaomi mobile and huawei mobile).
How do I handle this?
public class NotificationsService extends Service {
#Override
public void onCreate() {
ApplicationLoader.postInitApplication();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Intent intent = new Intent("example.app.start");
sendBroadcast(intent);
}
}
In Manifest:
<receiver android:name=".AppStartReceiver" android:enabled="true">
<intent-filter>
<action android:name="example.app.start" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
It doesn't new on Xiaomi because Xiaomi has a feature called app permission, where user has to allow the app to start automatically (Service).
Go like this and allow your app to autostart:
Settings > permissions > Autostart
Or,
Don't try to restart the same Service inside onDestroy() instead use START_STICKY inside onStartCommand(Intent intent, int flags, int startId) method.
Again you are sending broadcast not starting a service, Use onDestroy properly:
#Override
public void onDestroy() {
Intent intent = new Intent("example.app.start");
sendBroadcast(intent);
super.onDestroy();
}
I want to implement this scenario for my application. I want to schedule my service to start when the phone boots, and whenever another application calls my service I want my service to start a certain activity within the project.
So in order to be clear. I want to create a project which contains a service which runs whenever the phone boots, and is dormant, listening for a call from a third party application. And whenever that call is received this service calls an Activity (from the same project, not third party)
How can I configure my manifest file in order to achieve this?
I have also come across this suggestion but my scenario is pretty different.
Thank you very much in advance
**Define Service in manifest and Create the BroadcastReciever with boot complete permission and listen the intent.If boot completed start the service.**
public class MyService extends Service {
Context context = this;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
Intent activity = new Intent(context, MyActivity.class);
activity.putExtra("Message", "fromService");
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(activity );
} catch (Exception e) {
MyLog.printException(e);
}
return super.onStartCommand(intent, flags, startId);
}
}
By creating a BroadcastReceiver you can perform the service startup.
public class StartupReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent(context, ShowActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
and in the manifest
<receiver
android:name=".StartupReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
This allows you to run an Activity, you can then start a Foreground Service from that activity. I just set this example because I have it ready, you can adapt it to run a service as you like.
I have done an app as tutorial to learn how to restart deleted alarms after phone is rebooted. After reboot BroadcastReceiver receives BOOT_COMPLETED action and launches a service, which restarts all alarms. Alarms create notification when they are called. After first tests I have received notifications at expected time and then forgot about this tutorial app and didn't turn the phone off.
However, I'm still getting notifications on my screen as if the app has restarted alarms again. During the day I have received twice and all of them are unclear why. The only thing that may launch the restarting alarms is BOOT_COMPLETED action. What's going wrong here?
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.marat.recyclerviewtutorial">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
// list of activities
<service android:name=".BootService"/>
<receiver android:name=".AlarmBroadcastReceiver"/>
<receiver android:name=".RestartAlarmsReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
RestartAlarmsReceiver.java
public class RestartAlarmsReceiver extends BroadcastReceiver {
private static final String TAG = "myTag";
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent i = new Intent(context, BootService.class);
ComponentName service = context.startService(i);
if (null == service) {
// something really wrong here
Log.e(TAG, "Could not start service ");
}
else {
Log.e(TAG, "Successfully started service ");
}
} else {
Log.e(TAG, "Received unexpected intent " + intent.toString());
}
}
}
BootService.java
public class BootService extends Service {
private static final String TAG = "myTag";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
Database db = new Database(this);
db.open();
ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();
data = db.getData();
db.close();
Log.d(TAG, "db is openned");
for (int i=0; i<data.size(); i++) {
Intent notif = new Intent(this, AlarmBroadcastReceiver.class);
notif.putExtra("Text", data.get(i).get(2));
notif.putExtra("Position", data.get(i).get(0));
int sec = Integer.parseInt(data.get(i).get(3));
Log.d(TAG, "intent is openned");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, Integer.parseInt(data.get(i).get(0)), notif, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (sec * 1000), pendingIntent);
Log.d(TAG, "Alarm is restarted");
}
Log.d(TAG, "before returning service");
return Service.START_STICKY;
}
}
It's already huge portion of code. But if you will need other parts of my app I will include them.
Thanks in advance!
I think this is because of START_STICKY. I think during the day the system closes your running Service to free resources, and START_STICKY forces it to restart. And on restart onStartCommand() is triggered again.
The decision may to use IntentService instead. I don't see the need of using Service here.
My target Android is 4.1.2. I created an simple android service which will show Toast on boot. But this application should not have any GUI. I was success running this service only from an activity which show GUI on start.
public class MyServices extends Service {
private MediaRecorder recorder = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
public int onStartCommand(Intent intent, int flags, int StartId)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
}
}
You can start this service from RebootReceiver but As of Android 3.0 the user needs to have started the application at least once before your application can receive android.intent.action.BOOT_COMPLETED events.
Reboot Receiver -> Android BroadcastReceiver on startup - keep running when Activity is in Background
First you have to create a receiver:
public class BootCompletedReceiver extends BroadcastReceiver {
final static String TAG = "BootCompletedReceiver";
#Override
public void onReceive(Context context, Intent arg1) {
Log.w(TAG, "starting service...");
context.startService(new Intent(context, MyServices.class));
}
}
Then add permission to your AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and register intent receiver:
<receiver android:name=".BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
After this is done, your application (Application class) will run along with services, but no Activities, don't put your application on SD card (APP2SD or something like that), because it has to reside in the main memory to be available right after the boot is completed.