Unable to set text in TextView inside static inner class - android

I have created an application in which i am sending a broadcast to my activity and in this broadcast i am sending two values, one is type and other is a badge, i am receiving these values in my inner class which is extending BroadcastReceiver but when i am going to set these values in the TextView of my main class then it is not setting these values, i am not able to understand why is this happening.
Following is my main acitivity in which inner class is present, and it is extending BroadcastReceiver :-
import java.util.List;
import android.widget.ScrollView;
import android.widget.ViewAnimator;
public class TabActivity extends Activity implements OnClickListener{
static String type;
static String badges;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
................
}
public static class TabBroadcast extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
SharedPreferences shrd = context.getSharedPreferences("Gallery", context.MODE_WORLD_READABLE);
type = shrd.getString("type", "null");
badges = shrd.getString("badge_count", "null");
badge_tips_text.setText(badge);
/*Editor edit = shrd.edit();
edit.remove("type");*/
Toast.makeText(context, "" + type + "\n" + badge_tips_text.getText().toString(), Toast.LENGTH_LONG).show();
}
}
}
I am receiving the values but unable to set them in TextView, please reply any help will be appreciable.
Thanks

You can't reference instance(non static) TextView from a static inner class. Instead, pass the stuff required through constructor:
public static class TabBroadcast extends BroadcastReceiver{
private final TextView textview;
public TabBroadcast(TextView t){
this.textview = t;
}
#Override
public void onReceive(Context context, Intent intent) {
t.setText("works");
}
}

TabBroadcast is inner class of an Activity then try as to access UI elements :
public class TabActivity extends Activity implements OnClickListener{
static String type;
static String badges;
public TextView badge_tips_text; //<<<< TextView declare here
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
................
//<<<< initilze TextView here after setContentView
}
public static class TabBroadcast extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(TabActivity.this.badge_tips_text !=null)
TabActivity.this.badge_tips_text.setText(badge);
// your code here ...
}
}
}
and make sure you have initialized TextView before calling TextView.setText

This is happening because the broadcast receiver is running on a different thread. Try using a handler that is passed from your activity:
Where you create your broadcast class use:
new TabBroadcast(new Handler());
Pass the handler through the TabBroadcast constructor and now inside of your TabBroadcast onReceive, you can do the following:
handler.post(new Runnable() {
public void run() {
myTextview.setText("Text");
}
});
You will need to set myTextview as final

Related

How to Pass data from #EActivity to #EFragment and assign to view

I am trying to pass a simple String from #EActivity to #EFragment , so i can later on assign that value to textView in #EFragment , I don't want to use saving in bundle pattern
My attempt:
#EActivity(R.layout.activity_pre_plan_detail)
public class PrePlanDetailActivity extends AppCompatActivity {
// some long adapter code
#AfterViews
void inits_(){
adapter.addFragment( myFragment_.builder().build().setme("something"));
}
}
______________________________________________________________________________
#EFragment(R.layout.fragment1)
public class PlanDescription extends Fragment {
#ViewById
TextView tv_fpd_description;
public void setme(String data){
tv_fpd_description.setText(data);
}
}
output/error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Note: All mentioned annotations are part of boilerplate library [android annotation][1]
Try with local broadcast manager
**Activity code:**
-----------------
Intent intent = new Intent("my-custom-event");
intent.putExtra("message", "something");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
**fragment code:**
-------------------
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onReceiver , new IntentFilter("my-custom-event"));
}
#Override
public void onDestroy() {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onReceiver );
super.onDestroy();
}
**BroadCastReceiver:**
private BroadcastReceiver onReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String data= intent.getStringExtra("message");
tv_fpd_description.setText(data);
}
};
You should really use a Fragment argument for this:
#EFragment(R.layout.fragment1)
public class PlanDescription extends Fragment {
#FragmentArg
String someDescription;
#ViewById
TextView tv_fpd_description;
#AfterViews
void afterViews() {
tv_fpd_description.setText(someDescription);
}
}
And you can create the Fragment like this:
PlanDescription_.builder().
someDescription("your data")
.build();

how to call non static method from static inner class within same activity

public class ABC extends Activity{
public void foo(int val)
{
}
...
public static class Receive extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
....
}
}
...
}
can anyone help me how can i call foo() from onReceive() of Receive class
public class YourActivity extends AppCompatActivity {
static YourActivity instance;
...
...
#Override
protected void onCreate(Bundle savedInstanceState) {
instance = this;
}
...
...
public void foo() {}
static class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
instance.foo();
}
}
if you cant make foo method static then you can remove the static from receive class.
public class Receive extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
}
}
Move public void foo(int val) to Class Receive

Android make callback to an Activity from java class

How can i make a callback to an Activity form a Java Class?
Example:
public class TestClass{
String text = "Test";
public TestClass(Context context){
startActivity(new Intent(context, SomeActivity.class));
}
private void sendToSomeActivity(){
//Call some method of SomeActivity and pas text as string
}
}
When sendToSomeActivity() is called, i want to make a callback to the already started SomeActivity and pass some text to the Activity. In SomeActivity i want to use the text.
Note: The TestClass object that i want to use is already created in another class.
How can this be done?
The solution I chose is as follows:
Use BroadcastReceivers to communicate between Java classes and Activities.
Example:
public class SomeActivity extends Activity{
private MyBroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
receiver = new MyBroadcastReceiver();
this.registerReceiver(receiver, new IntentFilter(MyBroadcastReceiver.ACTION));
}
#Override
public void onDestroy() {
super.onDestroy();
this.unregisterReceiver(receiver);
}
private class MyBroadcastReceiver extends BroadcastReceiver{
public static final String ACTION = "com.example.ACTION_SOMETHING"
#Override
public void onReceive(Context context, Intent intent) {
String test = intent.getStringExtra("dataToPass");
}
}
}
public class TestClass{
private String test = "TEST";
private Context context;
public TestClass(Context context){
this.context = context;
}
private void sendToSomeActivity(){
Intent intent = new Intent();
intent.setAction(SomeActivity.MyBroadcastReceiver.ACTION);
intent.putExtra("dataToPass", test);
context.sendBroadcast(intent);
}
}
Try this..
public class TestClass{
interface Implementable{
public void passData(String text);
}
Implementable imple;
String text = "Test";
public TestClass(Context context){
startActivity(new Intent(context, SomeActivity.class));
}
private void sendToSomeActivity(){
if(imple != null){
imple.passData(text);
}
}
public void setListener(Implementable im){
imple = im;
}
}
class SomeActivity implements Implementable{
new TestClass().setListener(this);
#override
public void passData(String text){
//here is your text
}
}
In your java class create an interface like this
public class TestClass{
private MyInterface myInterface;
public interface OnSendSomething {
public void onSending(String sendWhateverYouWant);
}
public void setOnSendListener(MyInterface myInterface) {
this.myInterface = myInterface;
}
}
private void sendToSomeActivity(){
//Call some method of SomeActivity and pas text as string
myInterface.onSending(sendWhateverYouWant);
}
And in your activity do something like this:
TestClass tclass = new TestClass(context);
tclass.setOnSendListener(new OnSendSomething () {
#Override
public void onSending(String sendWhateverYouWant) {
//sendWhateverYouWant is here in activity
}
});
You can also visit these links for better understanding.
How to create our own Listener interface in android?
Observer Design Pattern in Java

How to make dynamically registered receive from outside of activity ?

I have a class structure as below
public class Admin extends DeviceAdminReceiver
{
public static class PubSub extends Activity
{
protected void onCreate(Bundle savedInstanceState) {
messageIntentReceiver = new MQTTMessageReceiver();
IntentFilter intentCFilter = new IntentFilter(MQTTService.MQTT_MSG_RECEIVED_INTENT);
registerReceiver(messageIntentReceiver, intentCFilter);
}
#Override
protected void onDestroy()
{
unregisterReceiver(messageIntentReceiver);
super.onDestroy();
}
public class MQTTMessageReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Bundle notificationData = intent.getExtras();
String newTopic = notificationData.getString(MQTTService.MQTT_MSG_RECEIVED_TOPIC);
String newData = notificationData.getString(MQTTService.MQTT_MSG_RECEIVED_MSG);
Log.e("Received Message on",newTopic+"- "+newData);
}
}
}
}
The receivers are dynamically registered and unregistered. The broadcast receiver works while PubSub activity stays on the screen. How to make it work from outside of activity?
I tried to do it in static way by registering in manifest.xml, but that dint work as MQTTMessageReceiver is a non static inner class. Cant able to instantiate the receiver runtime error I get.
I cant change the MQTTMessageReceiver class static as i need to access outer class members.

How to access Activity UI from my class?

I have an activity which creates an object instance of my class:
file MyActivity.java:
public class MyActivity extends Activity {
TextView myView = (TextView)findViewById(R.id.myView);
...
Points myPoints new Points();
...
}
--------------------------------------------------------------
file Points.java:
private class Points {
...
HOW TO USE myView HERE ???
...
}
--------------------------------------------------------------
How do I use the UI objects in my class (which does not extend an
Activity)? Should I pass some context to my Points class? How do I do, exactly?
see you post, i've edited it , to fix the problem
hope it helps :=)
here is the Edit :
file MyActivity.java:
public class MyActivity extends Activity {
TextView myView ;
protected void onCreate(android.os.Bundle savedInstanceState) {
myView = (TextView)findViewById(R.id.myView);
Points myPoints = new Points(this);
myPoints.displayMsg("Hello World !!!");
}
}
--------------------------------------------------------------
file Points.java:
private class Points {
protected MyActivity context;
//add a constructor with the Context of your activity
public Points(MyActivity _context){
context = _context;
}
public void displayMsg( final String msg){
context.runOnUiThread(new Runnable() {
#Override
public void run() {
context.myView.setText(msg);
}
});
}
}
Your Points can't be a private class without being an inner class. So your code doesn't even compile...
Pass the view as parameter to the constructor of your Points class:
public class MyActivity extends Activity {
TextView myView = (TextView)findViewById(R.id.myView);
Points myPoints new Points(myView);
private class Points {
public Points(TextView view) {
// todo
}
}
}
You should do everything and pass back the value to the activity to handle UI instead of doing any UI related stuff in the point stuff.
You can pass the main Activity's context (using Points(getApplicationContext());) to the class as a constructor parameter. You could also pass the specific UI elements you want to manipulate.
A better way to do it, however, may be to have Points not know about the Activity. Have your Activity call Points methods and take the necessary actions based on the method output.
You could just pass the view to your class.
Points myPoints = new Points(myView);
private class Points
{
private TextView mTextView;
Points(TextView textView)
{
this.mTextView = textView;
}
}
i was in same trouble..
i found the simple way..
make a static variable and function ...
call from other class..
TestActivity.java
public class TestActivity extends Activity {
static EditText edit_text1;
public void onCreate(Bundle savedInstanceState)
{
.....
edit_text1 = (EditText) findViewById(R.id.edit_text1);
.....
}
public static void setMSG(String str)
{
edit_text1.setText(str);
}
}
Test2.java
TestActivity.setMSG("this is text");
Could work using an interface
file MyActivity.java:
public class MyActivity extends Activity implements Points.MyListener {
TextView myView;
... onCreate(...){
myView = (TextView)findViewById(R.id.myView);
Points myPoints = new Points();
//pass in MyActivity's instance of the listener
myPoints.addListener(this);
}
#Override
public void updateTextView(String message){
myView.setMessage(message);
}
}
file Points.java:
public class Points {
public Points(){
}
public interface MyListener{
void updateTextView(String message);
}
MyListener myListener;
public void addListener(MyListener listener){
myListener = listener;
}
public void updatePoints(){
//do some operations in calculatePoints()
String points = calculatePoints();
//update views using MyActivity's implementation of updateTextView()
myListener.updateTextView(points);
}
}
Doing it this way, events can be fired / messages sent, for lack of better terms, from the external class to update the Activity UI. This might be overkill if all sb need is to call a method in the Points class that returns something

Categories

Resources