Android Service Running as a separate process - android

I have a service Class in android. Is it be possible for a Service to run as a separate process than an application just for receiving SMS and enqueue them in a queue after that an application reads SMS from this Queue.
Is it possible to launch a separate service?
I have tag the source code of SmsService class below
public class SmsService extends Service {
private SMSReceiver mSMSreceiver;
private IntentFilter mIntentFilter;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public SmsService(){
/*dba = new DataBaseAdapter(this);*/
mSMSreceiver = new SMSReceiver();
}
#Override
public void onCreate(){
super.onCreate();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(ConstantClass.SMS_RECEIVED);
registerReceiver(mSMSreceiver,mIntentFilter);
}
#Override
public int onStartCommand(Intent intent , int flags, int type){
return START_STICKY;
}
#Override
public void onDestroy(){
super.onDestroy();
//unregisterReceiver(mSMSreceiver);
}

To enroll your service in a different process, you need to define android:process attribute when defining your service in AndroidManifest.xml
For example:
<service android:process=":kaushik" />
This will run your service in a new process called kaushik.

Related

Best practices for running worker threads for periodically updating the UI

What are the best practices for running worker threads in the background that periodically update UI elements in an activity. The goal here is to avoid any screen freezing on any kind of updates and if there are any specific guidelines/standards that should be followed.
Try Service for Background Work.
I have made an example for you.
Try this.
TestActivity.java
public class TestActivity extends AppCompatActivity {
private final String TAG = "TestActivity";
public final static String RECEIVER_ACTION = "com.action.MyReceiverAction";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_work);
registerMyReceiver();
startService(new Intent(this, BackgroundService.class));
}
MyReceiver myReceiver = new MyReceiver();
private void registerMyReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RECEIVER_ACTION);
registerReceiver(myReceiver, intentFilter);
}
class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive() called");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
}
BackgroundService.java
public class BackgroundService extends Service {
private String TAG = "BackgroundService";
#Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate() called");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind() called");
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand() called");
notifyToUI();
return super.onStartCommand(intent, flags, startId);
}
/**
* This Methd will notify your Activity
*/
private void notifyToUI()
{
Intent myIntent = new Intent();
myIntent.setAction(TestActivity.RECEIVER_ACTION);
sendBroadcast(myIntent);
}
}
Now at the end register BackgroundService in AndroidManifest.xml file
<service android:name=".BackgroundService"/>
Use AlarmManager (or some other timer) to periodically start a service. That service then updates the model, and notifies UI thread with for example LocalBroadcastManager. UI thread can then use BroadcastReceiver to catch the Intent and update itself.

Could I call a function of service from another service in Android?

I have a function in a service as follows:
public class ServiceA extends Service {
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
private final IBinder mBinder = new LocalBinder();
public void readFunc() {
//I have a function in here
}
}
I want to call the readFunc() in the service B. Could I do it in Android? Thank all. This is my service B
public class serviceB extends Service {
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("A");
intentFilter.addAction("B");
registerReceiver(broadcastReceiver, intentFilter);
return START_STICKY;
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case "A":
Log.d(TAG,"A");
//Call the function here
break;
case "B":
Log.d(TAG,"B");
break;
}
}
};
}
Well, you COULD do it, just instancing a new ServiceA and calling the function, but you should not do it like that. Services are not meant to be instantiated just to call a function which is not even part of the Service functionality. You have different options:
You could make readFunc() static if it does not modify variables of the class and you think it should belong to ServiceA and not to ServiceB. I don't think this is a goog approach in your case.
You could create a class ServiceAB which has readFunc(), and the define both ServiceA and B as "extends ServiceAB". Then both classes would inherit this function and you could just call readFunc() in both of them. I think this would be the correct approach in your case: both classes need some common functionality.
You could have readFunc() in a different class, and the instantiate it to use it in each of your services.
The way I would do it:
public class ServiceAB extends Service {
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
public void readFunc() {
//I have a function in here
}
}
Then:
public class serviceB extends ServiceAB {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("A");
intentFilter.addAction("B");
registerReceiver(broadcastReceiver, intentFilter);
return START_STICKY;
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case "A":
Log.d(TAG,"A");
readFunc(); //Just call the function
break;
case "B":
Log.d(TAG,"B");
break;
}
}
};
}
And ServiceA:
public class ServiceA extends ServiceAB {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
private final IBinder mBinder = new LocalBinder();
}
Quoting #Kingfisher Phuoc here and #Mr Snowflake here
there are three obvious ways to communicate with services and EventBus:
Using Intents
Using AIDL
Using the service object itself (as singleton)
EventBus
In your case, I'd go with option 3. Make a static reference to the service it self and populate it in onCreate():
void onCreate(Intent i) {
sInstance = this;
}
Make a static function MyService getInstance(), which returns the static sInstance.
Then in Activity.onCreate() you start the service,
asynchronously wait until the service is actually started (you could have your service notify your app it's ready by sending an Intent to the activity.) and get its instance.
When you have the instance, register your service listener object to you service and you are set.
NOTE: when editing Views inside the Activity you should modify them in the UI thread, the service will probably run its own Thread, so you need to call Activity.runOnUiThread().
The last thing you need to do is to remove the reference to you listener object in Activity.onPause(), otherwise an instance of your activity context will leak, not good.
NOTE: This method is only useful when your application/Activity/task is the only process that will access your service. If this is not the case you have to use option 1. or 2.

Manage communication between two app using service and messenger

I want to develop two apps. I need an app able to start and stop a second app. To do this I set up a messenger between these two apps using a service. The service is sticked to the second app.
I initialized the intent like this in app1:
protected void onCreate()
{
super.onCreate();
Intent mIntent = new Intent();
mIntent.setAction("com.package.service");
bindService(mIntent, mServiceConnection, BIND_AUTO_CREATE);
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName arg0) {
mIsBinded=false;
mServiceConnection=null;
}
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
mIsBinded=true;
mMessenger = new Messenger(arg1);
}
};
And I send a message to Close the app2.
In app2 I have a service like this:
public class RemoteServiceClient extends Service
{
static final int STOP = 0;
static final int CONTINUE = 1;
private static final String TAG ="service" ;
class MyHandler extends Handler
{
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch(msg.what)
{
case STOP:
sendBroadcast(new Intent("stop"));
Log.d(TAG,"stopapp");
break;
case CONTINUE:
break;
}
}
}
Messenger mMessenger = new Messenger(new MyHandler());
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mMessenger.getBinder();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
return Service.START_STICKY;
}
}
and I also put in manifest inside application:
<service android:name="com.package.app.service"
android:process=":exported">
<intent-filter>
<action android:name="com.package.service" />
</intent-filter>
</service>
In activity of app2 I put a braodcast receiver that when the message STOP is delivered the app calls finish() .
The problem I have is that the first time the messanger delivers the message and reboot the app2. Once app2 is reboot the app1 cannot be able to stop app2 again. I get this error:
05-04 15:47:28.168 16741-16755/com.package.app1 W/System.err: android.os.DeadObjectException
05-04 15:47:28.178 16741-16755/com.package.app1 W/System.err: at android.os.BinderProxy.transact(Native Method)

Service not binding

I have an android device with an integrated barcode scanner. I'm setting up the service as follows:
public class BarcodeService extends Service {
private final LocalBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
public BarcodeService getService() {
return BarcodeService.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
return binder;
}
#Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("ServiceStartArguments");
thread.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Get scanner
}
}
The service is also in the AndroidManifest.xml. The class that makes use of this service is:
public class BarcodeReader extends Activity {
private BarcodeService barcodeService;
private boolean isBound = false;
private ServiceConnection barcodeServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
barcodeService = ((BarcodeService.LocalBinder)service).getService();
isBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
barcodeService = null;
isBound = false;
}
};
#Override
protected void onStart() {
super.onStart();
if (!isBound) {
Intent intent = new Intent(this, BarcodeService.class);
startService(intent);
bindService(intent, barcodeServiceConnection, Context.BIND_AUTO_CREATE);
}
}
#Override
protected void onStop() {
super.onStop();
if (isBound) {
unbindService(barcodeServiceConnection);
}
}
}
However the service is not binding, ie. barcodeService is always null. The code never reaches onServiceConnected.
What am I missing? And is it necessary to use a class that extends Activity?
Common Android Service troubleshooting
Just some general remarks and stuff to check if your service is not starting.
Service class defined in Manifest
Common mistake is not to have the service in manifest (android doesn't warn you about that) or have it there but misspelled the class name.
<manifest ... >
...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>
Or you might have it in the manifest (or one of the manifests) but the final manifest after merging that is used within the apk doesn't have the service definition. For that check:
project_folder/app_folder/build/intermediates/manifests/full/...
A project clean and rebuild might help.
Check bindService return value
When debugging check the boolean return value on the bindService call to see if service was started successfully or not.
Debug Activity and Service implementation
Also the service might be running but not bind or might not execute anything hence have no visual effect that it's running in the background. For that use the debugger on both the bound Activity and the Service itself.
Check onBind, onStartCommand in Service class or even the onCreate there.
In Activity check bindService, ServiceConnection and so.
Resources
also check https://developer.android.com/guide/components/services.html

Receiving sms through a Service Class

I wish to make a service class that receive sms received from a broadcast receiver and get database updated for that I hava developed some code for SmsService class but it does not work. Sir pl tell me is it possible to receive SMS through a service class and update database at background. thanks and sorry for my bad pronounciation if not understand.
below is my source code of SmsService Class.
public class SmsService extends Service {
private SMSReceiver mSMSreceiver;
private IntentFilter mIntentFilter;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public SmsService(){
/*dba = new DataBaseAdapter(this);*/
mSMSreceiver = new SMSReceiver(this);
}
#Override
public void onCreate(){
super.onCreate();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(ConstantClass.SMS_RECEIVED);
registerReceiver(mSMSreceiver,mIntentFilter);
}
#Override
public int onStartCommand(Intent intent , int flags, int type){
return START_STICKY;
}
#Override
public void onDestroy(){
super.onDestroy();
//unregisterReceiver(mSMSreceiver);
}
}
thanks in advance
Om Parkash Kaushik
You can check
http://mobiforge.com/developing/story/sms-messaging-android
This tutorial shows how to send and then receives, giving a notification (toast) when you receive a text.
Let me know if this helps!
Also you can check android: register application to receive sms for more details.
Thanks

Categories

Resources