Can i start an android service without activity or GUI? - android

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.

Related

Broadcast DOWNLOAD_COMPLETE is not recieved if app is not running

Issue: broadcasts android.intent.action.DOWNLOAD_COMPLETE is received only if application is running or in background. If application is killed then broadcast never received.
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS" />
<receiver
android:name=".adapters.VideoListAdapter$VideoDownloadedReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
Receiver class
public static class VideoDownloadedReceiver extends BroadcastReceiver implements AsyncResponse {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("YES", "in receive");
}
}
Please note the I am facing this issue not in all devices.
Devices on which I am facing this issue: Lenevo A600, Asus Zenfone Max
Device on which it's working fine: Asus Zenfone 5 (cyanogenmod 13), Android Studio Emulator (Nexus 6p marshmallow), Samsung J7 Prime , Samsung j5, Nexus 5
I think the reason may be due to the customization ROM ,limited the broadcast,CM,ASOP,is the originally System.so,,,
if you want to receive broadcast even after app closed then you should use broadcast in service
following will help you to implement:-
https://stackoverflow.com/a/16824692/4246910
The receiver appears to be an internal class. Since the app is destroyed so is your internal receiver class which is part of a destroyed class.
I am basing this assumption because your manifest has
android:name=".adapters.VideoListAdapter$VideoDownloadedReceiver".
Separate the 'BroadcastReceiver' into its own class and it should work as expected.
As for working on some phones, I would check the other apps running and what kind of app suppression apps you may have running in the background which may be contributing to force closing your app.
you should have something like this. i looked at code and you have nested receeiver but you are not holding the service on.
Calling function to start the action
private void startDownloadService() {
Intent downloadIntent = new Intent(this, VideoDownloadReceiverService.class);
if (!VideoDownloadReceiverService.isRunning()) {
// My manifest has enabled="false" so i do this to turn it 'ON'
component = new ComponentName(CounterActivity.this, VideoDownloadReceiverService.class);
getPackageManager()
.setComponentEnabledSetting(component,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
// Start the service
startService(downloadIntent);
}
}
in separate file here is the service
public class VideoDownloadReceiverService extends Service{
private static boolean isRunning = false;
public VideoDownloadReceiverService(){
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// you may not need this since oyu register it in the Manifest. the fact the service is running
// should keep your app alive and receiving and unable to be shutdown
// but this is what i did
IntentFilter filter = new IntentFilter();
filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
receiver = new VideoDownloadReceiver();
registerReceiver(receiver, filter);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentText("Viewer Text In Notification").build();
startForeground(MyConstants.NOTIFICATION_ID, notification);
isRunning = true;
return START_STICKY; // This is the line that keeps the service running no matter what
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy(){
unregisterReceiver(receiver);
super.onDestroy();
}
}
In separate file, here is the receiver
public class VideoDownloadReceiver extends BroadcastReceiver {
public VideoDownloadReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"com.example.johnbravado.zionwork");
wakeLock.acquire();
Toast.makeText(context, "in service", Toast.LENGTH_SHORT).show();
Log.i("YES", "service on receive");
wakeLock.release();
}
}

Creating a daemon like service for android application

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.

Android keep intentservice running and listen for broadcasts

Im trying to track how many times the "SCREEN_ON" is triggered without the user starting the app. The app itself shows a single activity with some charts and info nothing more. I created a small test but i think it's not the correct way because it's draining my battery.
I got a broadcast receiver "BOOT_COMPLETED" that starts a sticky IntentService that is registering the "SCREEN_ON" broadcast receiver with a never ending loop to catch to broadcast's (the battery drain problem).
Is it possible that i can listen on the "SCREEN_ON" broadcast without a Service?
Jur
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".Application"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:hardwareAccelerated="true">
<activity
android:name=".activities.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".services.ScreenOnService" />
<receiver android:name=".broadcast.receivers.AutoStartReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".broadcast.receivers.ScreenOnReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
</intent-filter>
</receiver>
</application>
AutoStartReceiver
public class AutoStartReceiver extends BroadcastReceiver
{
public void onReceive(Context aContext, Intent anIntent)
{
Log.i("[AutoStartReceiver]", "onReceive");
aContext.startService(new Intent(aContext, ScreenOnService.class));
}
}
ScreenOnReceiver
public class ScreenOnReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.i("[ScreenOnReceiver]", "onReceive");
}
}
ScreenOnService
public class ScreenOnService extends IntentService
{
private ScreenOnReceiver theReceiver;
public ScreenOnService()
{
super(ScreenOnService.class.getName());
theReceiver = new ScreenOnReceiver();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("[ScreenOnService]", "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
protected void onHandleIntent(Intent intent)
{
Log.i("[ScreenOnService]", "onHandleIntent");
registerReceiver(theReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
while(true);
}
#Override
public void onDestroy()
{
Log.i("[ScreenOnService]", "onDestroy");
unregisterReceiver(theReceiver);
super.onDestroy();
}
}
Do you have any particular reason for using an IntentService as opposed to a regular started Service?
You should be able to achieve this using a regular started Service. Register the receiver as part of onStartCommand.
Something like this:
public class MyService extends Service {
private ScreenOnReceiver mReceiver;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mReceiver == null) {
mReceiver = new ScreenOnReceiver();
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
}
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
// remember to unregister receiver in onDestroy...
}
This way you avoid busy looping. IntentService is designed to be a short lived service performing a background operation. Your usage does not fit the purpose of IntentService.
I got a broadcast receiver "BOOT_COMPLETED" that starts a sticky IntentService that is registering the "SCREEN_ON" broadcast receiver with a never ending loop to catch to broadcast's (the battery drain problem)
This is completely inappropriate for an IntentService. Your problem is that an IntentService shuts down after onHandleIntent() returns, forcing you into this busy-wait.
Instead, use a regular Service.
Is it possible that i can listen on the "SCREEN_ON" broadcast without a Service?
AFAIK, ACTION_SCREEN_ON still cannot be registered for in the manifest, so, yes, you need a Service. But you need a Service, not an IntentService.
I got a broadcast receiver "BOOT_COMPLETED" that starts a sticky
IntentService that is registering the "SCREEN_ON" broadcast receiver
with a never ending loop to catch to broadcast's (the battery drain
problem).
This is not correct. The intent service is not design for long running operation.Actually It is no longer remain running after onHandleIntent().
If you want to listen constantly up to device is turn on then service will sure help you to listen each every trigger.
public class ScreenOnService extends Service
{
...........
}

IntentService on Android run in background

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.

How to run a service in 4.0?

Hi i have developed an service application using activity and that works great in 2.2 and 2.3 android version and it starts on boot and runs my app for once in 30 mins and sending location to server but in 4.0 the app is not running on services on boot can anybody say me why?
my code:
BroadcastReceiver.java:
public class autostart extends BroadcastReceiver {
public void onReceive(Context arg0, Intent arg1) {
if ("android.intent.action.BOOT_COMPLETED".equals(arg1.getAction())) {
Intent intent = new Intent(arg0, gps_back_process.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
}
}
service.java:
public class gps_back_process extends Service
{
private static final String TAG = "MyService";
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d("Testing", "Service got created");
Toast.makeText(this, "gps_back_process,onCreate();", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid)
{
Intent intents = new Intent(getBaseContext(),MainActivity.class);
intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intents);
Toast.makeText(this, "gps_back_process.onCreate();", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}
}
Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<receiver android:name=".autostart" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity" >
</activity>
<service
android:name=".gps_back_process"
android:enabled="true" />
</application>
thank you.
Once the user runs the app for the first time (and does not force stop it), everything behaves as before — a reboot will cause BOOT_COMPLETED broadcasts to be received and so on. However, if the user installs the app, until and unless they run the app manually, no broadcasts will be received. And if the user force-stops the app, until and unless they run the app manually, no broadcasts will be received.
Check this for more detail.
This happens because from Android 3.1+ you Service will not run on Boot unless you start(launch) your Application atleast once after installation. So, when you install your Application and restart the device prior of launching the Applications MainActivity your BroadCastReceiver won't be fired. For that you have to launch your MainActivity once and then restart the device. That works!
For reference you can check my question here.
You should add add android.permission.RECEIVE_BOOT_COMPLETED,
If you don't have this permission your app won't receive the boot completed intent.

Categories

Resources