Access TextView and Progressbar in Recyclerview from IntentService - android

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

How to finish an activity from Adapter class using RecyclerView

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();
}

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

Sharing data between an activity and a class

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);
}

pass a String to a class which extends PhoneStateListener

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!

Unable to set text in TextView inside static inner class

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

Categories

Resources