I am having a recyclerview which has a TextView (progresstxt) and a Progressbar (downloadprogress) as part of the inflated items.
I need to know how I can access the TextView and Progressbar in the SimpleAdapter from the IntentService so I can update their values?
I am trying to achieve this with a BroadcastReceiver but it doesn`t work, the TextView and Progressbar are not being updated.
Thank you in advance.
I access the TextView and Progressbar through onBindViewHolder.
public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.SimpleViewHolder> implements FollowRedirectsCallback {
private final Context mContext;
private String recievedStr;
private int receivedProg;
private MyBroadcastReceiver myBroadcastReceiver;
private MyBroadcastReceiver_Update myBroadcastReceiver_Update;
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
public final TextView title, progresstxt;
public ProgressBar downloadprogress;
public SimpleViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.simple_text);
progresstxt = (TextView) view.findViewById(R.id.progress_text);
downloadprogress = (ProgressBar) view.findViewById(R.id.progressdownload);
}
...
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
recievedStr = intent.getStringExtra(MoService.EXTRA_KEY_UPDATE);
//progresstxt.setText(result); ?
//how to access the TextView in onBindViewHolder?
}
}
public class MyBroadcastReceiver_Update extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
receivedProg = intent.getIntExtra(MoService.EXTRA_KEY_UPDATE_PROGRESS, 0);
//downloadprogress.setProgress(update); ?
//how to access the Progressbar in onBindViewHolder?
}
}
...
#Override
public void onBindViewHolder(final SimpleViewHolder holder, final int position) {
//
myBroadcastReceiver = new MyBroadcastReceiver();
myBroadcastReceiver_Update = new MyBroadcastReceiver_Update();
//register BroadcastReceiver
IntentFilter intentFilter = new IntentFilter(MoService.ACTION_MyIntentService);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
mContext.registerReceiver(myBroadcastReceiver, intentFilter);
IntentFilter intentFilter_update = new IntentFilter(MoService.ACTION_MyUpdate);
intentFilter_update.addCategory(Intent.CATEGORY_DEFAULT);
mContext.registerReceiver(myBroadcastReceiver_Update, intentFilter_update);
//
holder.progresstxt.setText(recievedStr);
holder.downloadprogress.setProgress(receivedProg);
holder.progresstxt.setVisibility(View.VISIBLE);
holder.downloadprogress.setVisibility(View.VISIBLE);
//
}
mContext.unregisterReceiver(myBroadcastReceiver);
mContext.unregisterReceiver(myBroadcastReceiver_Update);
}
Through a IntentService (MoService) several file operations are done and I want to access/update the TextView and Progressbar from this IntentService.
public class MoService extends IntentService {
public static final String ACTION_MyIntentService = "com.sample.RESPONSE";
public static final String ACTION_MyUpdate = "com.sample.UPDATE";
public static final String EXTRA_KEY_UPDATE = "EXTRA_UPDATE";
public static final String EXTRA_KEY_UPDATE_PROGRESS = "EXTRA_UPDATE_PROGRESS";
String message;
int mProgress;
..
public MoService() {
super("MyService");
}
#Override
public void onCreate() {
context = this;
super.onCreate();
}
#Override
protected void onHandleIntent(Intent intent) {
//
Intent intentUpdate = new Intent();
intentUpdate.setAction(ACTION_MyUpdate);
intentUpdate.addCategory(Intent.CATEGORY_DEFAULT);
intentUpdate.putExtra(EXTRA_KEY_UPDATE, message);
sendBroadcast(intentUpdate);
//
}
class MyDownloadDownloadStatusListener implements DownloadStatusListener {
#Override
public void onDownloadComplete(DownloadRequest request) {
message = "Status: completed...";
mProgress = 0;
progresstxt.setVisibility(View.GONE);
downloadprogress.setVisibility(View.GONE);
..
}
}
There are a couple of issues with the code. You should not create a new Receiver in your onBindViewHolder method.
There should be a single receiver which updates the Item list used by your adapter and call notifyDataSetChanged on the adapter.
Hope it helps
Related
I am trying to finish activity from adapter class while clicking Recyclerview item
using the code
public void onBindViewHolder(#NonNull CountryCodeAdapter.CountryViewHolder holder, int position{
CountryModel countryMode = countryModels.get(position);
final String cCode = countryModel.getName();
holder.llcountryCode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(v.getContext(),RegisterActivity.class);
i.putExtra("countryCode", cCode);
v.getContext().startActivity(i);
((AppCompatActivity)context).finish();
}
}
}
Also tried this but didn't work
((Activity)context).finish();
And i get this error:
cannot be cast to android.support.v7.app.AppCompatActivity
Make an interface for the adapter (inside the adapter class)like this :
public interface YourAdapterInteraction {
void onClickCountryCode();
}
Make your Activity implement your interface, like this:
public class YourActivity extends AppCompatActivity implements YourAdapter.YourAdapterInteraction
Inside YourActivity :
#Override
public void onClickCountryCode() {
Intent i = new
Intent(this,RegisterActivity.class);
i.putExtra("countryCode", cCode);
startActivity(i);
finish();
}
fetch Activity instance in Adapter constructor:
public class MyAdapter extends IAdapter<RecyclerView.ViewHolder,MyDS> {
private Activity activity;
public MyAdapter(Activity activity) {
this.activity = activity;
}
}
Do this :
public void onBindViewHolder(#NonNull
CountryCodeAdapter.CountryViewHolder holder, int position{
CountryModel countryModel = countryModels.get(position);
final String name = countryModel.getName();
holder.llcountryCode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context,RegisterActivity.class);
i.putExtra("countryCode", cCode);
context.startActivity(i);
((Activity)context).finish();
}
}
});
instaed of :
Public void onBindViewHolder(#NonNull
CountryCodeAdapter.CountryViewHolder holder, int position{
CountryModel countryModel = countryModels.get(position);
final String name = countryModel.getName();
holder.llcountryCode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new
Intent(v.getContext(),RegisterActivity.class);
i.putExtra("countryCode", cCode);
v.getContext().startActivity(i);
((AppCompatActivity)context).finish();
}
}
});
Create an interface callback inside your recyclerView, implement the method in your activity and call the method when an item is clicked.
// in your recyclerView
public interface RecyclerViewCallback {
void onItemClick(Item item)
}
// in your activity
#Override
void onItemClicked(Item item) {
this.finish();
}
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
I have an activity MyActivity that holds a service class MyService.
I would like the service to send String data to the activity, and then create a button using this data.
Following this post I created a static method in the activity.
The problem of course is that i can't use this in a static context.
public class MyActivity extends Activity {
private MyService myService;
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.main);
myService = new MyService();
}
public static void connectMethod (String buttonName) {
Button btn = new Button(this); // error
btn.setId(i);
final int buttonID = btn.getId();
btn.setText(buttonName + buttonID);
}
}
public class MyService {
...
private void showButton (String data) {
MyActivity.connectedMethod(data);
}
}
Two possible solutions to avoid your error:
public static void connectMethod (Context context, String buttonName) {
Button btn = new Button(context);
btn.setId(i);
final int buttonID = btn.getId();
btn.setText(buttonName + buttonID);
}
// ...
public class MyService {
private Context context;
public MyService(Context context) {
this.context = context;
}
...
private void showButton (String data) {
MyActivity.connectedMethod(context, data);
}
}
Or create a static class field : private static Context context;
public static void connectMethod (String buttonName) {
Button btn = new Button(context);
btn.setId(i);
final int buttonID = btn.getId();
btn.setText(buttonName + buttonID);
}
i want to know if there is any way to pass a string from an activity to a class which extends phoneStatelistener.
in sending end, i used
Intent pass = new Intent(ListActivity.this,CallHelper.class);
pass.putExtra("name", name);
and in the receiving end..
public class CallHelper {
private class CallStateListener extends PhoneStateListener {
int flag;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
String name = getintent().getStringExtra();
}
but it showing error in getintent() part, is there any alternate way?
You can't call getIntent() in a class that extends PhoneStateListener. If CallHelper is an activity, what I suggest is to override the default constructor of your CallStateListener.
public class CallHelper extends Activity{
String name;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.call_helper_layout);
Bundle extras = getIntent().getExtras();
if(extras != null){
name = extras.getString("name");
}
CallStateListener c = new CallStateListener(name);
}
private class CallStateListener extends PhoneStateListener {
int flag;
String name;
public CallStateListener(String name){
this.name = name;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
//do stuff with name
}
}
}
I always do it like this: I create the class and then use a setter to set the value. Sending an Intent is a bit much in my opinion...
the Activity:
class SomeActivity extends Activity {
public void onCreate(Bundle savedInstanceState){
CallStateListener listener = new CallStateListener();
listener.setFlag(myValue);
}
}
the Listener:
class CallStateListener extends PhoneStateListener {
int flag;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
String name = getintent().getStringExtra();
}
public void setFlag(int flag) {
this.flag = flag;
}
...
}
Hope that helps you!
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