Unable to use TextView - android

I'm writing a GCM application.
I'm unable to set a received message to a text view.
Check the below code:
public class GcmMessageHandler extends IntentService {
String mes;
private Handler handler;
public GcmMessageHandler() {
super("GcmMessageHandler");
}
#Override
public void onCreate() {
super.onCreate();
handler = new Handler();
}
#Override
public void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
mes = extras.getString("title");
showMsg();
Log.i("GCM", "Received : (" +messageType+") "+extras.getString("title"));
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
public void showMsg(){
handler.post(new Runnable() {
public void run() {
TextView textview = (TextView)findViewById(R.id.getMsg);
textview.setText(mes );
}
});
}
}
(Error msg : The method findViewById(int) is undefined for the type new Runnable(){})

What you're trying to do is to get the reference of your TextView R.id.getMsg in the layout. You're using the findViewByIdmethod in an IntentService Class which does not provide this method. See Android Documentation
Normally you do that in an Activity or Fragment in lifecycle methods like onCreate or onCreateView etc. where the View is given as parameter value. That looks similar to the following line of code:
TextView textview = (TextView)view.findViewById(R.id.getMsg);
After you've retrieved your TextView reference, you're able to use it in implemented methods.
You need a way to handle data from your Intent Service back to your Application/Activity etc. A possible solution could be to pass your retrieved message data from the IntentService back to the Activity you could use a BroadcastReceiver (as shown here)

Your textview is in service class and textview must be at activity
class . If you want to set data in activity than create an interface
or make textview public static.

Related

Get variable from MainActivity in OnHandleIntent

I´m pretty new in android. I have made communication between two Apps with BroadcastReceiver and intentServices .
The thing is, I want to send information to the app2 from app1. In app1 I need to access a variable which is in MainActivity.class , I need to send it to servicev.class (the service where the intent is handled) but the variable "res" is null when I access it, why does that happen? (App2 calls app1 onHandleIntent and it breaks in res.getOtp() ) I try to create an extra setter getter class and also an intent but getIntent() does not work inside onHandleIntent... how can I achieve to pass res.getOTP (string) ? I really dont want to use SQLite
servicev:
public class servicev extends IntentService {
private static final int RESULT_OK = 1;
protected ResultReceiver mReceiver;
public servicev() {
super("yeah");
}
#Override
protected void onHandleIntent(Intent intent) {
//I receive here the intent from app2 and I need to response with res.getOTP()
helper h = new helper();
String val = intent.getStringExtra("foo");
Intent in = new Intent("com.banorte.bem.movil.veriToken.SendBroadcast");
in.putExtra("resultCode", this.RESULT_OK);
in.putExtra("resultValue", "My Result Value. Passed in: " + h.getRes().getOtp()); //h here is null... setter and getter approach does not work... maybe sqlite could work but it is necesary?
sendBroadcast(in);
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
VTTokenAPI api;
TextView textView;
Button button;
EditText input;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidSetup.getInstance().init(this);
helper h = new helper();
api = new VTTokenAPI("FFFFFF");
res = api.getStatus();
res.getOtp(); //correct value
h.setRes(res);
setContentView(R.layout.activity_main);
}
}
helper:
public class helper {
public VTResult getRes() {
return res;
}
public void setRes(VTResult res) {
this.res = res;
}
VTResult res;
}
You are trying to instantiate a new MainActivity which is not the same as the running activity but a new instance.
If you need your IntentService to be able to get data from a running Activity you have options such as using SharedPreferences or SQLite. Instead of keeping the data in memory try to persist it in some database in the onCreate and then try to read it from the storage during handleIntent

Update/access Progressbar, TextView from a Service

I have an activity A which has a progressbar and a textview.
If user clicks a button a service is being started (ServiceB), I am trying to find a way how to update the progressbar in Activity A from the ServiceB and at the same time set the (progress) text in the Textview in Activity A.
I looked around on Google and Stackoverflow and I think I found a way to do it as described here
but I am having difficulties to implement this, any help is highly appreciated.
PS: don`t downvote, I know UI should not be directly accessed from a Service, so I am looking for a way to do it right.
Some relevant code:
Activity A:
#EActivity(R.layout.downloads_activity)
public class DownloadsActivity extends BaseActivity {
#ViewById(R.id.progress_text)
TextView progresstxt;
#ViewById(R.id.progressdownload)
ProgressBar downloadprogress;
// Update Progressbar and set Text sent from ServiceB
}
ServiceB:
public class ServiceB extends IntentService {
...
#Override
public void onProgress(DownloadRequest request, long totalBytes, long downloadedBytes, int progress) {
int id = request.getDownloadId();
if (!isActive) {
downloadManager.cancel(downloadId1);
deleteCancelledFile.deleteOnExit();
} else if (id == downloadId1) {
// How to update progressbar and textview of Activity A?
progresstxt.setText("Downloading: " + progress + "%" + " " + getBytesDownloaded(progress, totalBytes));
downloadprogress.setProgress(progress);
}
}
...
}
You need to use LocalBroadcastManager
Following are the steps which needs to be taken care
Create a LocalBroadcastManager inside activity.
private BroadcastReceiver mLocalBroadcast = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// take values from intent which contains in intent if you putted their
// here update the progress bar and textview
String message = intent.getStringExtra("message");
int progress = Integer.parseInt(intent.getStringExtra("progress"));
}
};
Register it on activity's onCreate()
LocalBroadcastManager.getInstance(this).registerReceiver(mLocalBroadcast ,
new IntentFilter("myBroadcast"));
UnRegister in activity's onDestroy()
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocalBroadcast );
Send updates from service to activity to update UI
From IntentService send progress and textView update via intent
Intent intent = new Intent("myBroadcast");
// You can also include some extra data.
intent.putExtra("message", "This is my message!"); // msg for textview if needed
intent.putExtra("progress", progressValue); // progress update
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
It will send these data to mLocalBroadcast which we register inside activity
Hope these help you.

Hello! I need some help in updating LIstView in Fragments

How can I update ListView in the other Fragment?
public class ChooseCS extends FragmentActivity {
final private Context context = this;
private HashMap<String, List<String>> mCitiesStreets = null;
private View rootViewStreetChangeFragment = null;
private SimpleAdapter adapter;
...
private static final int NUM_PAGES = 3;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
...
and two Fragments
public class CityChangeFragment extends Fragment {
and
public class StreetChangeFragment extends Fragment {
...
mMapDataAdapter.put("streets", fillcities);
adapter = new SimpleAdapter(
rootViewStreetChangeFragment.getContext(),
mMapDataAdapter.get("streets"), R.layout.grid_streets_4_7,
from, to);
mDataListViewStreets.setAdapter(adapter);
...
I need make update ListView in StreetChangeFragment from CityChangeFragment where I doing changing data
You can use LocalBroadcastManager to achieve this.
In your StreetChangeFragment write below code
#Override
public void onCreate(Bundle savedInstanceState) {
...
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-event-name".
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onDestroy() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
And use below method to send broadcast message from CityChangeFragment to StreetChangeFragment
private void sendMessage() {
Log.d("sender", "Broadcasting message");
Intent intent = new Intent("custom-event-name");
// You can also include some extra data.
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Note: You can pass data using intent (here you can position also on which you want to update data in listview)
You can check below link to learn more about LocalBroadcastManager
https://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
Interface is good idea,The idea is basically to define an interface and let the activity implement that interface.
Once it has implemented that interface, you could do anything you want in the method it overrides.
There is a good tutorial on Simple Developer Blog how to do exactly this kind of thing.
And you need t declare a method in fragment and it can be executed from the activity by getting the fragment instance from adapter like
Fragment fragment= mPagerAdapter.getItem(int positon);
((StreetChangeFragment )).updateList();
in StreetChangeFragment declare method and do what else you want, Thank you

Update view from different thread Android

I make a simple Android Apps that will update its view when an SMS is received. This is the code for my receiver class
public class SMSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
intent.setClass(context, SMSReceiverService.class);
intent.putExtra("result", getResultCode());
WakefulIntentService.sendWakefulWork(context.getApplicationContext(), intent);
}
}
That class will call SMSReceiverService class to handle the oncoming SMS and execute method notifyMessageReceived, which is shown below.
private void notifyMessageRecevied(SMS message) {
if(!isInMyApps()) {
launchPopUp();
}
else {
//updating view should go here
}
}
The problem is, I don't know how to update the view in my activity (which is in separate class, not the SMSReceiverService class), when I tried to update my TextView in my activity, it thrown an CalledFromWrongThreadException. Can anybody please help me ?
Thanks in advance, and sorry about my bad English...
You can create an activity variable to hold the instance of the activity you want.
In SMSReceiver (the one you want to call):
SMSReceiverService.setMainActivity(this);
In SMSReceiverService (the one you want to update from):
public static SMSReceiver smsActivity;
public static void setMainActivity(SMSReceiver activity)
{
smsActivity = activity;
}
...
smsActivity.runOnUiThread(new Runnable() {
public void run() {
try{
smsActivity.textView.setText("");
}
catch{}
}
}
Assuming SMSActivity is the file that contains the view you want to update.
Assuming the service has Context of User Activity
Activity a=(Activity)userContext;
a.runOnUiThread(/*runnable method of activity which calls UpdateView() */);

Android send data from TCP thread to different Activities using Handlers

I have a MainActivity the default start up Activity which creates a TCP worker thread.
This TCP thread receives some data from the server and passes it to the current Activity on display say there are two more Activities called Activity1 and Activity2 which will display the received data.
How do i achive this using Handlers ?
Here is a outline of what I have...please suggest solution or change everything if I am completely wrong.
public class MainActivity extends Activity
{
public static TCPFunctions tcp = null;
public static Handler handler;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
handler = new Handler();
tcp = new TCPFunctions(this, handler);
tcp.start();
}
}
----------------------------------------TCP Thread Class---------------------------------
public class TCPFunctions extends Thread
{
public Handler handler;
//socket and io streams are here and they work properly
Public TCPFunctions(MainActivity main, Handler _handler)
{
this.main = main;
handler = _handler;
}
public void run()
{
Intent showActivity1 = new Intent(main, Activity1.class);
main.startActivity(showActivity1);
while(true)
{
directories = new Vector<String>();
directories = (Vector<String>) inputStream.readObject();
Message msg = Message.obtain();
msg.obj = directories;
handler.sendMessage(msg);
directories = null;
}
}
}
now say in Activity1 I want this directories object...
Lets say my Activity1 has a button which when pressed sends a request to the server to get the directories object...which is received by the TCP thread...now how do I get this in Activity1 and update the UI...
Basically the directories object is a Vetor of Strings and I want to display the strings on a ListView contained in the Activity1/Activity2
public class Activity1 extends Activity implements OnClickListener,OnItemClickListener
{
private ListView directoryList;
private Button rootButton;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fileexplorer);
directoryList = (ListView) findViewById(R.id.directories);
rootButton.setOnClickListener(this);
directoryList.setOnItemClickListener(this);
}
public void onClick(View v)
{
switch(v.getId())
{
case R.id.root_button:
Log.d(TAG, "FileExplorer: Root Button Pressed");
//request for directories made here
break;
}
}
// What should be the Handler code to get the directories ?
}
First: The handler executes runnables and handles messages in the thread that created it. So if you want Activity1 to react to data from TCPFunctions, you have two options. Either:
-MainActivity, which created the handler in your current code, needs to react to the message, get the data, and send it along to Activity1
-Or Activity1 needs to be the one to create the handler.
In either case, the core answer to your question of how to react to a sent message, is that you need to override the handleMessage() method by subclassing the handler. Here's a boilerplate snippet you can use (pulled from one of the sample apps on the Android developer website)
mUpdateHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String chatLine = msg.getData().getString("msg");
addChatLine(chatLine);
}
};

Categories

Resources