Pass class object to service - java

I'm new in android and java and encountered with one issue. I have an activity with methods and I want to use them in background. For background I used a Service class. The problem is that I cannot pass activity object to service constructor because it must not contains any params in it. I read how to send strings and doubles via intend but I cannot find how to pass activity class.
public class MainActivity extends Activity
{
#Override
protected void onCreate( Bundle savedInstanceState ){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onStop(){
super.onStop();
startService(new Intent(this, MyService.class));
}
#Override
public void onResume(){
super.onResume();
stopService(new Intent(this, MyService.class));
}
public void toast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
//---------------------------------------
public class MyService extends Service
{
private MainActivity main;
public MyService() {
}
#Override
public void onCreate() {
super.onCreate();
main.toast("test"); // <- here I want to use some method
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Thank you for any help!

Hello please see below steps sure help you.
Step 1. Define an interface your Service will use to communicate events:
public interface ServiceCallbacks {
void Showtoast(String msg);
}
Step 2. Write your Service class. Your Activity will bind to this service. In addition, we will add a method to set the ServiceCallbacks.
public class MyService extends Service {
// Binder given to clients
private final IBinder binder = new LocalBinder();
// Registered callbacks
private ServiceCallbacks serviceCallbacks;
// Class used for the client Binder.
public class LocalBinder extends Binder {
MyService getService() {
// Return this instance of MyService so clients can call public methods
return MyService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
public void setCallbacks(ServiceCallbacks callbacks) {
serviceCallbacks = callbacks;
}
}
Step 3. Write your Activity class following the same guide, but also make it implement your ServiceCallbacks interface. When you bind/unbind from the Service, you will register/unregister it by calling setCallbacks on the Service.
public class MyActivity extends Activity implements ServiceCallbacks {
private MyService service;
private boolean bound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
}
#Override
protected void onStart() {
super.onStart();
// bind to Service
Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
// Unbind from service
if (bound) {
service.setCallbacks(null); // unregister
unbindService(serviceConnection);
bound = false;
}
}
/** Callbacks for service binding, passed to bindService() */
private ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// cast the IBinder and get MyService instance
LocalBinder binder = (LocalBinder) service;
service = binder.getService();
bound = true;
service.setCallbacks(this); // register
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
bound = false;
}
};
/* Defined by ServiceCallbacks interface */
#Override
public void Showtoast(String message) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
Thank you let me know if you any question.

Why so complicated? You can show toast from service easily.
So you can place you code into service's onCreate method
Toast.makeText(this, "text", Toast.LENGTH_SHORT).show();

Related

Call a Function in a OnPreferenceClickListener

I am trying to call a function in a OnPreferenceClickListener which is defined in a another class. Since I have not managed to initialisation an interface in OnPreferenceClickListener. I have given an example code below:
public void onCreatePreferences(Bundle bundle, String s) {
ListPreference preference = findPreference(getString(R.string.settings_ble_choose_device_key));
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(#NonNull Preference preference) {
callFunctionInMainActivity();
return false;
}
});
}
How i can call a function witch is implement in a another class?
Thank you very much
Rene
You can implement an intent for this. Where you send a broadcast from your OnPreferenceClickListener class and implement a broadcast received in the other class to listen for this intent and invoke the method that you want. Here is an example:
public void onCreatePreferences(Bundle bundle, String s) {
ListPreference preference = findPreference(getString(R.string.settings_ble_choose_device_key));
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(#NonNull Preference preference) {
sendBroadcast(new Intent(Constants.ACTION_STOP_MAIN_SERVICE));
return true;
}
});
}
In your other class:
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action= intent.getAction();
if(action.equalsIgnoreCase(ConstantesIdentifiant.ACTION_STOP_MAIN_SERVICE)){
finishAffinity();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter(ConstantesIdentifiant.ACTION_STOP_MAIN_SERVICE));
}
#Override
protected void onDestroy() {
unbindService(mConnection);
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}

Java - Interface - How do I assign a specific interface in multiple activities all together

I have a service which has an interface, I'm implementing the interface callback in multiple activities, but because of I'm calling the app instance on every activity's onCreate, the interfaces are responding on the current activity only. How do I make sure they work all together in every activity.
MyApp.java
public class MyApp extends Application {
private static MyApp myApp;
#Override
public void onCreate() {
super.onCreate();
myApp = new MyApp();
}
#Contract(pure = true)
public static synchronized MyApp getInstance() {
MyApp myApp;
synchronized (MyApp.class) {
myApp = MyApp.myApp;
}
return myApp;
}
public void setCallBackListener(MyService.ReceiversCallbacks receiversCallbacks) {
MyService.receiversCallbacks = receiversCallbacks;
}
}
MyService.java
public class MyService extends Service {
public static MyService.ReceiversCallbacks receiversCallbacks;
public MyService() {
super();
}
public interface ReceiversCallbacks {
void onReceiveCallbacks(String data);
}
#Override
public void onCreate() {
super.onCreate();
Notification notification = new NotificationCompat.Builder(this, NOTIFICATION_ID)
.setContentTitle("Background service")
.setSmallIcon(R.drawable.ic_launcher)
.build();
startForeground(1, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (MY_LOGIC) receiversCallbacks.onReceiveCallbacks("DATA_FROM_MY_LOGIC");
//stopSelf();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
ActivityA.java
public class ActivityA extends AppCompatActivity implements MyService.ReceiversCallbacks {
#Override
protected void onCreate(Bundle savedInstanceState) {
MyApp.getInstance().setCallBackListener(this);
}
#Override
public void onReceiveCallbacks(String data) {
// calling important functions
}
}
ActivityB.java
public class ActivityB extends AppCompatActivity implements MyService.ReceiversCallbacks {
#Override
protected void onCreate(Bundle savedInstanceState) {
MyApp.getInstance().setCallBackListener(this);
}
#Override
public void onReceiveCallbacks(String data) {
// calling important functions
}
}
Each activity's onCreate when I do this MyApp.getInstance().setCallBackListener(this); The focus of the call back shifts to the new activity. But I want the focus in both or more activities at the same time, how do I do that? Is there any better way for the solution I want?
Please note these:
I don't want to call those functions onResume
I don't want to use Broadcasts
I just created different interfaces for each activity and registered them to their corresponding activity, and they worked!
MyApp.getInstance().setCallBackListener(this);

How to perform/run background services in a custom Android OS like MIUI?

I am trying to implement a simple service demo in Android. When I start the service, it should run in the background even if I close the activity.
However on my Redmi phone (running MIUI OS) my service does not show as running when I close the activity.
It works with the stock OS like on a Moto phone.
Can you guys tell me how to do that?
Here is my activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start(View v)
{
Intent i=new Intent(this,MyService.class);
startService(i);
}
public void stop(View v)
{
Intent i=new Intent(this,MyService.class);
stopService(i);
}
}
Here is my Service:
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"hello",Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
Toast.makeText(this,"stopped",Toast.LENGTH_LONG).show();
}
}

How to set broadcast listener interface in fragment?

I have service, which gets data from API and sends this data to BroadcastReceiver class. Also, I create interface OnReceiveListener, which used in Activity. Look at the code here:
Activity:
public class StartActivity extends AppCompatActivity
implements MyBroadcastReceiver.OnReceiveListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
receiver.setOnReceiveListener(this);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter(MyBroadcastReceiver.START));
...
}
#Override
public void onReceive(Intent intent) {
// Do smth here
}
}
MyBroadcastReceiver:
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String START = "com.example.myapp.START";
public static final String GET_LINKS = "com.example.myapp.GET_LINKS";
private OnReceiveListener onReceiveListener = null;
public interface OnReceiveListener {
void onReceive(Intent intent);
}
public void setOnReceiveListener(Context context) {
this.onReceiveListener = (OnReceiveListener) context;
}
#Override
public void onReceive(Context context, Intent intent) {
if(onReceiveListener != null) {
onReceiveListener.onReceive(intent);
}
}
}
Service isn't important on this question.
---- Question ----
So, what's problem: I want to use this receiver in fragment, but when it sets context - I get exception "enable to cast". What I should to do on this case?
Here is my code in fragment:
public class MainFragment extends Fragment
implements MyBroadcastReceiver.OnReceiveListener {
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
myBroadcastReceiver.setOnReceiveListener(getContext());
LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver,
new IntentFilter(MyBroadcastReceiver.GET_LINKS));
}
#Override
public void onReceive(Intent intent) {
// Do smth here
}
}
Your MainFragment class implements your OnReceiveListener interface, not its Context as returned by getContext(). Instead of passing a Context object into setOnReceiveListener(), try directly passing an OnReceiveListener instance. Then your fragment and activity can both call setOnReceiveListener(this).
you don't need to dynamically register the receiver. i believe you must have registered it in manifest using <receiver> tag.
this is not required:
LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver,
new IntentFilter(MyBroadcastReceiver.GET_LINKS));
and about callback registering listener, instead of using getContext() use MainFragment.this like this:
myBroadcastReceiver.setOnReceiveListener(MainFragment.this);
After searching for hours for the appropriate way to implement such a solution to this problem, I've found a way finally. It is based on RussHWolf's answer. The complete solution with code is below:
In this way, a setListener() method is exposed so that Fragment or Activity can set the listener by sending an instance of IStatusChangeListener.
public class StatusChangeReceiver extends BroadcastReceiver {
private IStatusChangeListener listener;
public void setListener(IStatusChangeListener listener) {
this.listener = listener;
}
#Override
public void onReceive(Context context, Intent intent) {
if (NetworkUtil.isNetworkConnected()) {
listener.onConnected();
} else {
listener.onDisconnected();
}
}
}
This is the interface:
public interface IStatusChangeListener {
void onConnected(String status);
void onDisonnected(String status);
}
Now, it is required to have an instance of IStatusChangeListener interface instead of implementing the IStatusChangeListener interface. And then, pass this instance of IStatusChangeListener to setListener() method.
public class MainFragment extends Fragment { //Not implementing the interface
private IStatusChangeListener listener = new IStatusChangeListener() {
#Override
void onConnected(String status) {
//some log here
}
#Override
void onDisonnected(String status) {
//some log here
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
StatusChangeReceiver r = new StatusChangeReceiver();
r.setListener(listener); // pass the IStatusChangeListener instance
LocalBroadcastManager.getInstance(getContext()).registerReceiver(r, new IntentFilter("connectionStatus"));
}
}
Note: Always use LocalBroadcastManager if you register BroadcastReceiver from Fragment.

Call class function in BroadcastReceiver onReceive function

I have a service with a BroadcastReceiver.How can I call a function in the service class from the onReceive function of the BroadcastReceiver?And if I can't, what can I do?Here is some code :
public class MyService extends Service {
private BroadcastReceiver broadcastReceiver;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
... // How to call myFunction() here?
}
};
... // intentFilter, registerReceiver, etc...
}
private void myFunction() {
... // do something
}
}
You can call it like this:
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
myFunction();
}
};
Or, if myFunction has the same name as a BroadcastReceiver method, you can explicitly call the outer class method like this:
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
MyService.this.myFunction();
}
};

Categories

Resources