I have
public class Backgroundservice implements AlarmReceiverCallback {
private Context context;
public Backgroundservice(Context context) {
this.context = context;
}
#Override
public void onAlarmReceived() {
//interface trigger
}}
now i would like to extends Backgroundservice in my MainActivity class that extends AppCompatActivity .
so i can use my method inside the mainactivity once the interface in Backgroundservice get trigger
You can use BroadCastReceiver
in you serveice class
public class Backgroundservice implements AlarmReceiverCallback {
private Context context;
public Backgroundservice(Context context) {
this.context = context;
}
#Override
public void onAlarmReceived() {
// send broadcast from here
Intent intent = new Intent("alaram_received");
context.sendBroadcast(intent);
}
and in your MainActivity receive this broadcast.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Register Receiver
IntentFilter intentFilter = new IntentFilter("alaram_received");
registerReceiver(alarm_receiver,intentFilter);
}
BroadcastReceiver alarm_receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// refresh Token
}
};
}
Happy Coding.
I manged to get it working by creating new interface
public interface ReceiverCallback {
public void onReceived();}
and implements in my mainactivity, and than creating new object of it inside
#Override
public void onReceive(Context context, Intent intent)
Related
I have codes in two classes
First class is ExampleBroadcastReceiver:
public class ExampleBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
boolean noConnectivity = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false
);
if (noConnectivity) {
Toast.makeText(context, "Disconnected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Connected", Toast.LENGTH_SHORT).show();
}
}
}
}
Second class is MainActivity:
public class MainActivity extends AppCompatActivity {
ExampleBroadcastReceiver exampleBroadcastReceiver = new ExampleBroadcastReceiver();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(exampleBroadcastReceiver, filter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(exampleBroadcastReceiver);
}
}
How can I make the two classes into one by passing the code from the ExampleBroadcastReceiver class to MainActivity? Is it possible? Please don't ask why. Thanks.
Use java interface to handle an event in MainActivity that occurs in ExampleBroadcastReceiver. This way you don't have to merge classes to share an event based data.
public class ExampleBroadcastReceiver extends BroadcastReceiver {
public interface ConnectivityMonitorCallback {
void onConnectivityChanged(boolean connectivity);
}
public ConnectivityMonitorCallback callback;
public ExampleBroadcastReceiver(#NonNull ConnectivityMonitorCallback eventCallback) {
callback = eventCallback;
}
#Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
boolean noConnectivity = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false
);
callback.onConnectivityChanged(noConnectivity);
}
}
}
Finally in the MainActivity you handle the event.
public class MainActivity extends AppCompatActivity {
ExampleBroadcastReceiver exampleBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Define event handling code here which occurs in ExampleBroadcastReceiver
exampleBroadcastReceiver = new ExampleBroadcastReceiver(new ExampleBroadcastReceiver.ConnectivityMonitorCallback {
#Override
void onConnectivityChanged(boolean connectivity) {
// Handle the event that occured in ExampleBroadcastReceiver
}
});
}
#Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(exampleBroadcastReceiver, filter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(exampleBroadcastReceiver);
}
}
I have an Activity which creates a class that does some work. What is the typical Android method of having this class report back to the Activity in order to update the UI?
My activity, which creates the class:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyClass obj = new MyClass(this);
obj.DoWork();
}
}
The class that does the work, and wants to report back some
public class MyClass(Context context) {
private Context context;
public void DoWork() {
//Do some work with a countdown timer
//Report back some values
}
}
You can create your own interface like this:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyClass obj = new MyClass(this);
obj.setOnWorkDoneListener(new MyClass.OnWorkDoneListener(){
#Override
public void onDone(Values values) {
//Work done, use values
updateUI(values);
}
});
obj.DoWork();
}
}
public class MyClass(Context context) {
private Context context;
public interface OnWorkDoneListener{
void onDone(Values values);
}
private OnWorkDoneListener listener;
public void setOnWorkDoneListener(OnWorkDoneListener listener){
this.listener = listener;
}
public void DoWork() {
//Do some work with a countdown timer
when(workEnded) listener.onDone(backValues);
}
}
How the code Intent intent=new Intent(context,Activity.class) which is in the superclass can be reused by its subclasses given that the subclasses have different context and different activities to start after on click listener is called. Is it possible?
This is the superclass:
public class CommonPost extends AppCompatActivity {
public void on_create(final Context context, final Class aclass) {
post.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CommonPost commonPost = new CommonPost();
MyTask task = commonPost.new MyTask(context, aclass);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
task.execute();
}
});
}
class MyTask extends AsyncTask<Void,Void,Void> {
Context context;
Class aclass;
public MyTask(Context context,Class aclass){
this.context=context;
this.aclass=aclass;
}
#Override
protected void onPreExecute() {
// do something
}
#Override
protected Void doInBackground(Void... voids) {
// do something
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Intent intent = new Intent(context, aclass);
startActivity(intent);
}
}
One of the subclass:
public class PlacementPost extends CommonPost {
Context context=PlacementPost.this;
Class aclass=Placements.class;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
on_create(context,aclass);
}
}
I am getting the following error when I try the above code:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
at android.app.Activity.startActivityForResult(Activity.java:4266)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.app.Activity.startActivityForResult(Activity.java:4224)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
at android.app.Activity.startActivity(Activity.java:4548)
at android.app.Activity.startActivity(Activity.java:4516)
at studentapp.notefi.CommonPost$PlaceTask.onPostExecute(CommonPost.java:240)
at studentapp.notefi.CommonPost$PlaceTask.onPostExecute(CommonPost.java:177)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
I am not sure where I am wrong or what I am missing. I just tried out whatever logically I felt correct. Please do correct me out where I am wrong!
for the starters you should never initialize your Activity using new, it has it's own life cycle and context should be of the class where you are actually starting intent, change you code to
on_create
public void on_create(final Context context, final Class aclass) {
post.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MyTask task = new MyTask(stor_root, mProgress, editTextplace, post, ninfo, imageUri,
mstorage, mDatabase, context, aclass);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
task.execute();
}
});
}
MyTask - Stop passing context from child
class MyTask extends AsyncTask<Void,Void,Void> {
Class aclass;
public MyTask(Class aclass){
this.aclass=aclass;
}
#Override
protected void onPreExecute() {
// do something
}
#Override
protected Void doInBackground(Void... voids) {
// do something
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Intent intent = new Intent(CommonPost.this, aclass);
startActivity(intent);
}
}
SubClass
public class PlacementPost extends CommonPost {
Context context=PlacementPost.this;
Class aclass=Placements.class;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
on_create(aclass);
}
}
You need to make the variable a class scope not an inner class scope.
This is an inner class scope variables:
public class CommonPost extends AppCompatActivity {
...
class MyTask extends AsyncTask<Void,Void,Void> {
Context context;
Class aclass;
...
}
}
You can't access the Context context and Class aclass; from the child class.
You need to make it a class scope:
public class CommonPost extends AppCompatActivity {
// set to protected to only allow child class access.
protected Context context;
protected Class aclass;
...
class MyTask extends AsyncTask<Void,Void,Void> {
}
}
Then, in your child class, change the variables to:
public class PlacementPost extends CommonPost {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the value to the base class.
context = PlacementPost.this;
aclass = Placements.class;
on_create(context,aclass);
}
}
I want to have a function that is constant between all my Fragments placed in MainActivity. I am not sure how to pass the data to the active Fragment since the Fragment will be unaware of the function being run.
I have tried creating an interface in the MainActivity and have the Fragment implement the MainActivity.OnDataPass. but not sure how to initiate the interface in the MainActivity I keep getting a NullPointerException.
In my main activity:
public class Mainactivity extends FragmentActivity{
OnDataPass dataPasser;
BroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String str = intent.getStringExtra("data");
dataPasser.onDataPass(str);
}
};
}
public interface OnDataPass {
public void onDataPass(String data);
}
}
In my Fragment
public class Storage extends Fragment implements Mainactivity.OnDataPass{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
mrootview = (ViewGroup) inflater.inflate(R.layout.storage, container, false);
return mrootview;
}
#Override
public void onDataPass(String data) {
Log.v(TAG, data);
}
}
am I even on the right track or is there a better way to send data to the fragment?
You are pretty far already:
public class Mainactivity extends FragmentActivity{
OnDataPass dataPasser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//When you create your fragment, keep a reference of it in the dataPasser variable
dataPasser = /* your storage fragment class or any other fragment that implements onDataPass*/
......
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String str = intent.getStringExtra("data");
dataPasser.onDataPass(str);
}
};
}
public interface OnDataPass {
public void onDataPass(String data);
}
}
In MainActivity I have a TextView: textV1. I also have a method in MainActivity that updates that textview:
public void updateTheTextView(final String t) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
});
}
In a BroadcasrReceiver I need to update the text in textV1 in MainActivity.
public class NotifAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// other things done here like notification
// NEED TO UPDATE TEXTV1 IN MAINACTIVITY HERE
}
}
How can this be done? The BroadcastReceiver is run from a service. This code I cannot change. Can I access and change textV1 in MainActivity from onReceive()? I've tried many things but all fail.
In your MainActivity initialize a variable of MainActivity class like below.
public class MainActivity extends Activity {
private static MainActivity ins;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ins = this;
}
public static MainActivity getInstace(){
return ins;
}
public void updateTheTextView(final String t) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
});
}
}
public class NotifAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
MainActivity .getInstace().updateTheTextView("String");
} catch (Exception e) {
}
}
}
#Use Interface
Another way to deal with this situation is by using an Interface. I will describe the advantage of this approach but first, let's see how it's done.
Follow these steps:
1) Create an interface
public interface MyBroadcastListener{
public void doSomething(String result);
}
2) Initialize the listener in BroadCastReceiver
public class NotifAlarm extends BroadcastReceiver {
private MyBroadcastListener listener;
#Override
public void onReceive(Context context, Intent intent) {
listener = (MyBroadcastListener)context;
// other things done here like notification
// NUPDATE TEXTV1 IN MAINACTIVITY HERE
listener.doSomething("Some Result");
}
}
3) Implement the interface in Activity and override the method
public YourActivity extends AppCompatActivity implements MyBroadcastListener{
// Your Activity code
public void updateTheTextView(String t) {
TextView textV1 = (TextView) findViewById(R.id.textV1);
textV1.setText(t);
}
#Override
public void doSomething(String result){
updateTheTextView(result); // Calling method from Interface
}
}
##Advantages of using the interface?
When you have BroadcastReceiver in a different file
Decoupled BroadcastReceiver
Using an interface makes BroadcastReceiver independent of any
Activity. Let's say in future you want to use this BroadCastReceiver
with another Activity which takes the result from BroadcastReceiver
and start a DetailActivity. This is completely a
different task but you will use the same BroadcastReceiver without even
a single code change inside BroadcastReceiver.
How to do that?
Implement the interface in the Activity and Override the method. That's it!
public ListActivity extends AppCompatActivity implements MyBroadcastListener{
// Your Activity code
public void startDetailActivity(String title) {
Intent i = new Intent(ListActivity,this, DetailActivity.class);
i.putExtra("Title", title);
startActivity(i);
}
#Override
public void doSomething(String result){
startDetailActivity(String title); // Calling method from Interface
}
}
create an instance of the class and then pass the value to the function that changes TextView value follow these steps please :
in your BroadcastReceiver overRide onReceive method and paste These lines or changes theme as you wish
private Handler handler = new Handler(); // Handler used to execute code on the UI thread
// Post the UI updating code to our Handler
handler.post(new Runnable() {
#Override
public void run() {
//Toast.makeText(context, "Toast from broadcast receiver", Toast.LENGTH_SHORT).show();
YourActivityToUpdate.updateTheTextView(message);
YourActivityToUpdateinst = YourActivityToUpdate.instance();
if(inst != null) { // your activity can be seen, and you can update it's context
inst.updateTheTextView(message);
}
}
});
now we explain the updateTheTextView and inst
in YourActivityToUpdate class Paste these Lines please
private static SignUpVerify mInst;
public static SignUpVerify instance() {
return mInst;
}
#Override
public void onStart() {
super.onStart();
mInst = this;
}
#Override
public void onStop() {
super.onStop();
mInst = null;
}
and this is the updateTheTextView method that should be placed in YourActivityToUpdate class
public void updateTheTextView(final String verifyCodeValue) {
Log.i("verifyCodeValue", verifyCodeValue);
YourTextViewToUpdate.setText(verifyCodeValue);
}
i think this is a better way thanks to "kevin-lynx"
If someone is searching this exact solution, but in Kotlin, do the following:
class MainActivity : AppCompatActivity() {
companion object {
var ins: MainActivity? = null
fun getInstance(): MainActivity? {
return ins
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ins = this
}
fun updateTheTextView(t: String) {
this#MainActivity.runOnUiThread {
val textV1 = findViewById<TextView>(R.id.textV1)
textV1.text = t
}
}
}
class NotifAlarm : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
try {
MainActivity.getInstance()?.updateTheTextView("The String")
} catch (e: Exception) {
}
}
}
In your broadcastreceiver class send broadcast
public class mybroadcaster extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("updatetext"));
}
}
In your activity register your broadcastreceiver and call it, do your work at onReceive and unregister the broadcaster in onDestroy()
public class MyActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter("updatetext"));
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do your work here
}
};
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}