Android and Java Static variable Initialization - android

This is my code for service class here previous_network_type is global static variable it is not initialized in oncreate() or onstartcommand() function also not from activity on create function why is that any help?? whenever i used it, it gives me 0 value it should give me 10 after starting of this service but returns 0. To be more clear
First MyService has previous_network_type variable i want to assign it a value in oncreate or oncommand function
which i'l use in another class which is broadcast receiver
and you know that broadcast receiver runs only when an event is occur so what m trying to do whenever a particular event occur i want to access this value
public class MyService extends Service {
static int previous_network_type=0;
public void onCreate() {
previous_network_type=10;
};
public int onStartCommand(Intent intent, int flags, int startId) {
previous_network_type=10;
return Service.START_STICKY;
}
}
and the code of other class(Broadcast receiver is given below)
public void onReceive(Context context, Intent intent)
{
MyService.current_network_type=MyService.previous_network_type;
}

public class MainActivity extends Activity {
Intent i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
i=new Intent(this,MyService.class);
startService(i);
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();;
stopService(i);
}
}
public class MyService extends Service {
static int previous_network_type=0;
public void onCreate() {
previous_network_type=10;
};
public int onStartCommand(Intent intent, int flags, int startId) {
previous_network_type=10;
Log.e("check","Value"+previous_network_type);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
check once if you have defined the Service in Android.manifest.xml
<service android:name="com.example.kuchbhi.MyService"
></service>

Just make sure that you are accessing the value after the service has been created/started.
Try to debug.

Related

Does a paused activity, still receive callbacks from service?

So here is what I am trying to understand.
I have a service like this
public MyService extends Service {
public List<MyListener> listenersList = new ArrayList<>();
public void addListeners(MyListeners mylistener) {
listenersList.add(myListener);
}
public void eventAOccured(){
for ( MyListner mylistener : listeners ) {
mylistener.eventAOccured();
}
}
public void eventBOccured(){
for ( MyListner mylistener : listeners ) {
mylistener.eventBOccured();
}
}
}
And here is my MyListener Interface which activities
public Interface MyListener {
public eventAOccured();
public eventBOccured();
}
Now we have three activites
public Activity1 extends AppCompatActivity implements MyListener{
public static int myVariable = 1;
//starts service. For sake of brevity I am skipping this part.
MyService.add(this);
//on click of a button
startActivity( new Intent (Activity1.this, Activity2.class);
//Now I know this will put Activity1 in paused state
#Override
public void eventAOccured() {
//Call activity 3
}
#Override
public void eventBOccured() {
myVariable = 3;
}
}
This is the second activity which is called by clicking a button in activity 1. After Activity2 is launched, lets say eventB occurs. Now If I access myVariable from Activity1, will it be 1 or 3.
After some time let us say, eventA has occured. Now will Activity3 will be launched?
I know an activity being paused means it is no longer visible to the user, but will the communication with service continue?
yes, paused activity still will receive the event as it is in the back stack of system and is not destroyed.
Override the onStartCommand(Intent intent, int flags, int startId) and returen STRAT_STICKY. this will restart the service.
You can check following Example.
public class Test extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Test Service ", "onStartCommand");
return START_STICKY; //It will restart Service in onPause/onDestroy
}
#Override
public void onCreate() {
super.onCreate();
//Do your operation
}
}

Android: Run code when application is permanently closed

So I have code that I want called when my application is closed. Not just when it is sent to the background or the surface is destroyed. How do I do this? Is there a method that I can override in a SurfaceView or Activity class?
New Edit - current BackgroundService class:
public class BackgroundService extends Service {
private String savedString;
public void onCreate() {
System.out.println("Service created");
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("start command: ");
savedString = intent.getStringExtra("myString);
return super.onStartCommand(intent, flags, startId);
}
public IBinder onBind(Intent intent) {
return null;
}
public void onTaskRemoved(Intent rootIntent) {
System.out.println("the saved string was: " + savedString);
super.onTaskRemoved(rootIntent);
}
public void onDestroy() {
System.out.println("destroyed service");
super.onDestroy();
}
}
Where I then have this in my other class:
Intent serviceIntent = new Intent(activity.getApplicationContext(), BackgroundService.class);
serviceIntent.putExtra("myString", "this is my saved string");
activity.startService(serviceIntent);
you need to add a background service
public class BackgroundServices extends Service
{
#Override
public void onCreate() {
Toast.makeText(this, "start", Toast.LENGTH_SHORT).show();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
then in your activity. where you want to trigger this service
use
startService(new Intent(getBaseContext(), BackgroundServices.class));
in your case it will be call on onDestory function of that activity
Yes when the process is terminated
That is not possible in general. Nothing in your app is called when the process is terminated.
For example when you open the running apps screen, and swipe away the app to stop it from running
That is a task removal. It may result in your process being terminated, and there are many ways in which your process can be terminated that has nothing to do with task removal.
To detect task removal, override onTaskRemoved() in a Service.

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.

How to pass context var when I use IntentService in BroadcastReceiver?

I need to use Context object in the function killCall, but I don't know how to pass the Context object to KillCall, could you help me? Thanks!
public class ReceiverCall extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent msgIntent = new Intent(context, InternetServerCall.class);
context.startService(msgIntent);
}
}
public class InternetServerCall extends IntentService{
public InternetServerCall(String name) {
super("InternetServerCall");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
HandleCall.killCall(context); //Need context
}
}
public class HandleCall {
public static boolean killCall(Context context) {
try {
....
Toast.makeText(context, "PhoneStateReceiver kill incoming call Ok",Toast.LENGTH_SHORT).show();
} catch (Exception ex) { // Many things can go wrong with reflection calls
return false;
}
return true;
}
}
You can get Context into InternetServerCall by doing InternetServerCall.this. And this is because all Android Components overrides Context class, on of them is IntentService.
You can also use getApplicationContext() into IntentService to get context. You can read my another similar answer Pass a Context an IntentService.
But you can not display Toast from IntentService directly, because it needs UI thread but IntentService runs into background thread. You need to use Handler to show Toast, like below example
public class TestService extends IntentService {
private Handler handler;
public TestService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
public TestService () {
super("TestService");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
return super.onStartCommand(intent, flags, startId);
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Handling Intent..", Toast.LENGTH_LONG).show();
}
});
}
}
An IntentService is subclass of Context so you can pass in this:
#Override
protected void onHandleIntent(Intent intent) {
HandleCall.killCall(this);
}

Service put and get some data

I have two applications. One run service and second is only small app. I want to put some data to service in first app, but I want to get this data in second app. How can I do that? I need that because when I use home button on second app and return I need check if id was changed. I think about run service with id in first app and second app when onResume check that id.
This is code service class:
public class ServiceId extends Service{
private int id;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
}
#Override
public void onDestroy() {
}
#Override
public void onStart(Intent intent, int startid) {
id = MainActivity.getApplicationId();
Log.v("Start", "Webservice started");
}
}
I start service in mainactivity:
startService(new Intent(MainActivity.this, ServiceId.class));
how get that id in other application?

Categories

Resources