I've made an app that is receiving some data from a TCP Client to my TCP Server that store the data in SQlite DB, and actually i've made a recyclerView where to visualize all that data but now my issue is what i'm trying like 2 weeks to refresh the recyclerView in real Time, i mean if a TCP Client will send a new package to my TCP Server and if i'm in the activity with the recyclerView the data have to be added dynamically.
I will also accept any type of tips and suggestions on how to improve my app.
Actually it's my 1st app i've ever created in Android.
HERE you can find my Server(TCPServer),RecyclerViewAdapter,Adapter(constructor),allert.java(class where i invoke the RecyclerViewAdapter.
Hope someone will be able to help me and ill be very grateful.
Try sending broadcast method. Here are the steps :
Make a inner class that extends BroadcastReceiver in your activity.
private class ExampleBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//do stuffs here, e.g. getting extras from intent
}
Declare a instance of the class outside any methods.
public class MainActivity extends AppCompatActivity {
private ExampleBroadcastReceiver exampleBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
//stuffs
}
}
Override onResume method. Initialize the instance you just made in this method. Then, register it with a intent-filter. This will make sure that your broadcast receiver ready when user open the activity.
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.MainActivity");
exampleBroadcastReceiver = new ExampleBroadcastReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(exampleBroadcastReceiver, filter);
}
Override onPause method and unregister your receiver.
#Override
protected void onPause() {
super.onPause();
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(exampleBroadcastReceiver);
} catch (IllegalArgumentException e) {
if (!e.getMessage().contains("Receiver not registered")) {
// unexpected, re-throw
throw e;
}
Make sure you use ArrayList for dynamic data.
Whenever you receive data from server, after you store them in your database, send a broadcast with extras contains data you want to display in your activity.
EDITED
I registered the receiver using an instance of LocalBroadcastManager.
Related
I'm using greenrobot EventBus and have some misunderstandings how to use it.
In my app, I have 4 activities: MainActivity and 3 other. Each Activity have it's own role in app, and MainActivity holds connection via COM port and sends/receives messages. So, when message is received, it sends via EventBus to current working activity. And when other Activity needs to sent message to COM port, it sending message to MainActivity via EventBus too. Problem is that when I'm working in one activity - all works fine, but when I try to do something in other activities - messages from EventBus are duplicaed. There is more - when I try to work in third activity - message is multiplies by 3 and so on.
Here some code:
public class ManualControl extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//my other code here
}
#Override
protected void onPause()
{
super.onPause();
EventBus.getDefault().unregister(this);
}
#Override
public void onResume()
{
super.onResume();
EventBus.getDefault().register(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEventFromMain event)
{
//code to do when get message from MainActivity
};
private void sendMessage(String messageID, String messageName)
{
EventBus.getDefault().post(new MessageEventFromIntent(messageID, messageName));
}
}
This method I use to send message to another Activity from MainActivity
EventBus.getDefault().post(new MessageEventFromMain(messageFromSerial));
And catch event from other Activities in MainActivity
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEventFromIntent(MessageEventFromIntent event)
{
//code to do when get message from intent
}
As you can see, I'm unregistering onPause() and registering onResume(), but when I'm closing this activity and starting it again messages are duplicating.
Example:
1st use:
55017031011_TURN_STRAIGHT27
2nd use:
55017031011_TURN_STRAIGHT2755017031011_TURN_STRAIGHT27
I have readed gitHub issues, but not found any answer.
And sorry for mistakes.
Unregister MainActivity from MessageEventFromIntent event after the activity is closed.
In an application I am developing I have some code that attempts to submit information to the internet. If the connection can not be made, I pop up a toast message instructing the user to check the network connection.
Toast.makeText(getApplicationContext(), "Check network connection.", Toast.LENGTH_SHORT).show();
The problem I have is the toast message comes up no matter what the user is looking at! Even if the user is in a different app and my app is running in the background! This is not the desired behavior as I send a notification to the user if network activity fails. I only want the toast message to appear if the user is in the activity that is generating the network activity. Is there a way to do this?
If this is not possible my idea was to just put some kind of visual element in my activity - rather than display a toast message.
Thank You!
You can use a boolean class member in order to keep track of activity state changes.
public class YourClass extends Activity {
private boolean mIsResumed = false;
#Override
public void onResume() {
super.onResume();
mIsResumed = true;
}
#Override
public void onPause() {
super.onPause();
mIsResumed = false;
}
public boolean isResumed() {
return mIsResumed;
}
}
Then you can use something like this:
if (isResumed()) {
//show Toast
}
Use a dynamic BroadcastReceiver. Your background service will broadcast an Intent when something happens. All of your app's activities will register a dynamic BroadcastReceiver which will listen for these events. When such event occurs it will show a toast. When none of your activities are running nothing will happen.
Inside your service
public static final ACTION_SOMETHING = BuildConfig.APPLICATION_ID + ".ACTION_SOMETHING";
public void doSomething() {
// ...
// Show toast if app is running. Or let the app react however you please.
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_SOMETHING));
// ...
}
Of course you can put additional information in the Intent as extras and access them in the BroadcastReceiver.
Inside your activities
private final IntentFilter onSomethingIntentFilter = new IntentFilter(MyService.ACTION_SOMETHING);
private final BroadcastReceiver onSomething = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// This check seems redundant but it's not. Google it.
if (MyService.ACTION_SOMETHING.equals(intent.getAction()) {
// Show toast here.
}
}
};
public void onResume() {
super.onResume();
// Start listening for events when activity is in foreground.
LocalBroadcastManager.getInstance(this).registerReceiver(onSomething, onSomethingIntentFilter);
}
public void onPause() {
super.onPause();
// Stop listening as soon as activity leaves foreground.
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(onSomething);
} catch (IllegalArgumentException ex) {}
}
You may want to pull this code to a common activity parent, a BaseActivity, so you don't repeat yourself.
This is a common case of Provider-Subscriber pattern. Another implementation would be an EventBus.
Keeping it simple, try adding a boolean flag in Activity and set its value as true in onResume & false in onPause. Then display the toast if the boolean flag is true.
I have a GCMListenerService that will be used for push notifications from my server to my client. I need this listener to interrupt a thread that is running in the Presenter (my project is structured using the MVP pattern). However, I do not know how to pass a result receiver to the Service because I don't think I can overrride onStartCommand(). The other option would be a LocalBroadCast Manager, but I'd like the message to go through even when the activity is paused, so I don't think a local broadcast manager would work.
create abstract BroadcastReceiver as follows :
public abstract class DataReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
onDataRefresh(intent);
}
protected abstract void onDataRefresh(Intent intent);
}
and use it in the activity as follow:
class Acb extends Activity{
onCreate(){
DataReceiver data = new DataReceiver(
#Override
protected void onMenuItemUpdate(Intent intent) {
});
}
}
whatever the data you passed using sendBroadcast(intent); ,that data you can access here .
I have a outGoingCall broadcast receiver.
basically I want it to intercept any outgoing call and show a dialog for certain pre-defined numbers.
so I made this broadcast init an activity which inits an FragmentDialog which init a AlertDialog.
When the user click "no"
I want to stop the call from happening.
I know setResultData(null); in the broadcast should do it.
But how can I pass the dialog result to the broadcast ?
there is no onActivityResult() in a broadcast.
I know how to pass it till the activity only.
fragmentDialog code:
public class YesNoDialogFragment extends DialogFragment {
private YesNoDialogFragmentListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
// Instantiate the NoticeDialogListener so we can send events to the
// host
mListener = (YesNoDialogFragmentListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString()
+ " must implement NoticeDialogListener");
}
}
here is my activity code:
public class MainActivity extends FragmentActivity implements
YesNoDialogFragmentListener {
public static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showYesNoDialog();
}
#Override
public void onDialogPositiveClick() {
// how to send result to receiver ??
finish();
}
here is my receiver code:
#Override
public void onReceive(final Context context, final Intent intent) {
Log.v(Constants.LOGTAG, "OutgoingCallReceiver onReceive");
if (intent.getAction()
.equals(OutgoingCallReceiver.OUTGOING_CALL_ACTION)) {
Log.v(Constants.LOGTAG,
"OutgoingCallReceiver NEW_OUTGOING_CALL received");
// get phone number from bundle
String phoneNumber = intent.getExtras().getString(
OutgoingCallReceiver.INTENT_PHONE_NUMBER);
if ((phoneNumber != null)
&& phoneNumber
.equals(OutgoingCallReceiver.ABORT_PHONE_NUMBER)) {
Toast.makeText(
context,
"NEW_OUTGOING_CALL intercepted to number 123-123-1234 - aborting call",
Toast.LENGTH_LONG).show();
Intent i = new Intent(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
SharedPreferences sharedPreferences = context
.getSharedPreferences(Constants.SHARED_PREF_NAME,
Context.MODE_PRIVATE);
boolean isBloacked = sharedPreferences.getBoolean(
Constants.IS_NUMBER_BLOCKED, true);
if (isBloacked) {
// dialog and then:
setResultData(null);
}
}
as you can see i tried to share the activity result via shared preferences, how come the code is async and the setResultData(null); is called before the dialog is shown?
from what I know there is no way to end the call besides setResultData(null);
You have to go through an activity (or a fragment) and then pass it to the receiver. Whenever you start a dialog, it has a parent activity, and that is where the result is sent. Just add something to your activity that passes the result on to your receiver.
You might actually consider altering your design to put more of your logic into the activity. Receivers are generally intended to be pretty lightweight objects that receive notification of something, pass it on to somewhere else. and then go away. Anyway, I obviously don't know your code, so maybe this doesn't make sense.
EDIT
Sorry, I understand your problem better now. I'm used to only working with setResultData when one activity has launched another activity, and the 2nd one wants to send something back to the 1st one. But you are using it to stop an ordered broadcast, right?
Unfortunately, Android does now allow you to do what you are trying to do. This section of the doc specifically says that you cannot show a dialog from within a broadcast:
http://developer.android.com/reference/android/content/BroadcastReceiver.html#ReceiverLifecycle
I think what you need to do is always return setResultData(null) right after starting your activity. If the user then clicks "no" in your dialog, then you are done. But if the user clicks "yes" (I'm assuming there is a "yes") then you would have to go ahead and make the call, and make sure you don't catch it again in your receiver.
Does that make sense? Sorry for my confusion earlier.
How can I keep data updated between two android activities. I am working on a android album project where the mainactivity is album activity(where I can add remove and rename albums). But when the user clicks on one of the albums just created I start a intent with a photo activity where he can add remove and move photos. All the operations are done for the album in the photoactivity and I use serialization to write the data back to a text file in both activities. The problem is when I back out to the main activity from the photo activity making some changes on a particular album. The mainactivity doesn't know about the updates.
Code in main activity to start the photo intent on a particular album selected by user
albumGridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//Toast.makeText(MainActivity.this, "" + position, Toast.LENGTH_SHORT).show();
Intent photoIntent = new Intent(MainActivity.this, Photo.class);
photoIntent.putExtra("userNode", user);
photoIntent.putExtra("position", position);
startActivity(photoIntent);
// Toast.makeText(MainActivity.this, position, Toast.LENGTH_SHORT).show();
}
});
You see I pass in the user object which is linkedlists of all album and photo nodes which added removed or moved. It is basically the entire user data of the that user. So whenever I start the old reference of the user node is passed on to the photo intent. I have implemented readerUser() and writeUser methods using serialization. I need to keep the reference of the user object in the main activity updated with all the changes in the photo activity..
Use contentProvider to provide unique access to your photo data and implement an Observer design pattern. That is , in on side, inside the the ContentProvider, when dataset changed due to insert ,update,or delete, notify the the contentResolver;on the other side, user has to register the notification by calling getContentResolover().registerContentObserver
Check out those links:
http://developer.android.com/reference/android/content/ContentProvider.html
http://developer.android.com/reference/android/content/ContentResolver.html
http://mylifewithandroid.blogspot.com/2008/03/observing-content.html
Look into implementing an Android Application. The Application class essentially gives you a GUI-less activity that remains constant for the duration of your session. Instead of serializing objects (slow, excess overhead), you can just call a method on your Application to save images to a data structure in the Application.
Using an Application means that any of your normal Activities can obtain a reference to the Application singleton and access any field or method which you expose.
Read the offical doc and do a Google search for some implementation examples, of which there are many.
I think what you need is database. Use sqlite http://developer.android.com/reference/android/database/sqlite/package-summary.html .
That is guessing you also want the data persisted and restored when the application is run a second time.
Implement broadcast receivers.
http://developer.android.com/reference/android/content/BroadcastReceiver.html
I used as #Vegito1044 proposed a local BroadcastReceiver in the main Activity that can be triggered from other activities. The relevant code for this looks like this:
public class AlbumActivity extends Activity {
private BroadcastReceiver myReceiver = null;
class _AlbumUpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive (Context context, Intent intent) {
Log.i(Global.LOG_CONTEXT, "AlbumActivity.onReceive(intent='" + intent + "')");
reloadGui();
}
}
#Override
public void onResume() {
super.onResume();
if (myReceiver == null)
{
myReceiver = new _AlbumUpdateReceiver();
IntentFilter filter = new IntentFilter(Global.REFRESH_GUI);
registerReceiver(myReceiver, filter);
}
reloadGui();
}
#Override
public void onPause() {
if (myReceiver != null)
{
unregisterReceiver(myReceiver);
myReceiver = null;
}
super.onPause();
}
void reloadGui()
{
Log.d(Global.LOG_CONTEXT, "AlbumActivity.refreshGui()");
... do what is neccessary to update gui
}
}