Checking for variable change using infinite loop - java

I need to check when the value of a variable is changed in my activity by a service so that I can then update the UI with the new values. I am currently using an infinite loop to check for this within a new thread, will this be using a lot of resources/is there a more efficient way to do this?

You should use a broadcast from the Service to send the changes in the variable. First of all create a broadcast in your main Activity.
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Broadcast","broadcast received");
String value = intent.getStringExtra("Variable"); // this will get the value
// send from Service
}
};
Next set a intent filter to which the broadcast listens. This you can do in onCreate() of your activity.
IntentFilter intentFilter = new IntentFilter("FROM_SERVICE");
registerReceiver(broadcastReceiver,intentFilter);
then in your service you must send a broadcast. If you want to send some data from Service to Activity then you must replace the above code with below
Intent intent = new Intent("FROM_SERVICE");
intent.putExtra("Variable", "change");
sendBroadcast(intent);

Related

Implementing exit app button in the persistent notification

My app runs a background service indicated by the persistent notification. Users need to use the toggle button in MainActivity to turn on/off this service and thus to remove the persistent notification.
Now I want to implement a notification action that can turn this service off & as well as the toggle within MainActivity. All in all, it should be an exit button to close my app and background service directly from the notification.
How do I achieve this?
note that I have two different java files, one for NotificationService
and the other is MainActivity. The toggle belongs to MainActivity.
edit: Is this okay to call System.exit(0) if I use pending intent with
BroadCastReceiver to exit from the app completely?
You have to use PendingIntent with BroadcastReceiver or Service to perform this. Here is an example of PendingIntent with BroadcastReciever.
Build a Notification
public static void createNotif(Context context){
Intent intentAction = new Intent(context,StopServerBroadcast.class);
//This is optional if you have more than one buttons and want to differentiate between two
intentAction.putExtra("action","actionName");
pIntent = PendingIntent.getBroadcast(context,1,intentAction,PendingIntent.FLAG_UPDATE_CURRENT);
drivingNotifBldr = (NotificationCompat.Builder) new NotificationCompat.Builder(context, CHANNEL_NAME)
.setSmallIcon(R.drawable.steeringwheel)
.setContentTitle("Stop Service")
.setContentText("Example Text")
.addAction(R.drawable.smallmanwalking, "On/off", pIntent)
.setOngoing(true);
...
}
Now the receiver which will receive this Intent
public class StopServerBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Toast.makeText(context,"recieved",Toast.LENGTH_SHORT).show();
String action=intent.getStringExtra("action");
if(action.equals("action1")){
performAction1();
/*
Code that will stop your service
*/
}
}
}
Register Receiver in Manifest
<receiver
android:name=".StopServerBroadcast"
android:enabled="true" />

Update textview of MainActivity from class that extends Service

I'm trying to create an android app that communicate with Bluetooth low energy module. I am able to connect to module, read data and so on. But the problem is i do not know how to update textview from class that extends Service (the one in which whole connection to BLE is going on). I know there is like BILLION or even more posts like these, but believe me i tried.
Here is MainActivity: http://pastebin.com/6yaP0dYM
and here is a class that extends Service: http://pastebin.com/cYuAUina
If someone could provide me some tips to solve my issue that would be more than great!
Create Broadcast Receiver and broadcast that in Service.
If your Activity is ope, register receiver and in onReceive() update the UI.
The receiver should be in the Activity...
Below is the working code
https://stackoverflow.com/a/14695943/1403112
You can get values through broadcast receiver......as follows, First create your own IntentFilter as,
Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");
Then create inner class BroadcastReceiver as,
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
/** Receives the broadcast that has been fired */
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction()=="YOUR_INTENT_FILTER"){
//HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW///////////
String receivedValue=intent.getStringExtra("KEY");
}
}
};
Now Register your Broadcast receiver in onResume() as,
registerReceiver(broadcastReceiver, intentFilter);
And finally Unregister BroadcastReceiver in onDestroy() as,
unregisterReceiver(broadcastReceiver);
Now the most important part...You need to fire the broadcast from wherever you need to send values..... so do as,
Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);
....cheers :)

Communication between running activities?

I'm new to android and is currently developing a quest/tresurehunt application. It is a prototype and is going to be evaluated in the field and i would therefore like to implement some sort of cheat to skip checkpoints if the application should crash during the tests.
My application work the way that when you select a quest a activity will be loaded to handle all checkpoints and the user location(ActivityAdapter.java). This activity will open the diffrent navigation tool activities and pass information to them based on the next checkpont using intent. I have implemented a long press event in the app i would like to activate the skip/cheat. My problem is that i can't figure out how to do this.
Location changed event of ActivityAdapter.java:
public void onLocationChanged(Location location) {
location.distanceBetween(location.getLatitude(), location.getLongitude(), lat, lng, dist);
if (dist[0]<= 10) {
if (cid == checkpoints.size()) {
Intent intent = new Intent(ActivityAdapter.this, SuccessActivity.class);
intent.putExtra("title", checkpoints.get(cid).get("title"));
startActivity(intent);
} else {
new loadAndStartQuest().execute();
}
}
}
loadAndStartQuest() just find the next checkpoint and start the right activity (navigationtool). I have tryed creating a object of the ActivityAdapter and set a variable and add it to the the if statement which did not work. I guess it is because it will create another instance of the activity and not affect the current/running one. So how would you communicate between two running activities?
To send data from Activity1 to running Activity2, you must pass through the next steps:
In Manifest.xml set launch mode "singleTask" for Activity2
<activity android:name="Activity2" android:launchMode="singleTask">
Put extras and start Activity2 from Activity1 (if Activity2 was started before, intent will be sended to existing instance).
Intent intent = new Intent(getContext(), Activity2.class);
intent.putExtra("CHECK_POINT", checkPointData);
startActivity(intent)
Override method onNewIntent() in Activity2
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
onNewCheckPoint();
}
private void onNewCheckPoint(){
Intent intent = getIntent();
Bundle extras = intent.getExtras();
//in this moment, you can process data, like you want.
}

LocationPoller and multiple broadcast receiver

I am using cwac-Location Poller (from here) to constantly poll user location and display location based notifications. This all is working fine but now I am trying to attach another BroadcastReceiver so that if my application is in foreground, instead of displaying notification animate the google map to current user location. But for some reason I can't get it working.
onCreate() method of MapActivity I have following code to start poller:
#Override
public void onCreate(Bundle savedInstanceState) {
.....
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent i = new Intent(this, LocationPoller.class);
Bundle bundle = new Bundle();
LocationPollerParameter parameter = new LocationPollerParameter(bundle);
parameter.setIntentToBroadcastOnCompletion(new Intent(this, LocationReceiver.class));
parameter.setProviders(new String[] {LocationManager.GPS_PROVIDER, LocationManager.NETWORK_PROVIDER});
parameter.setTimeout(60000);
i.putExtras(bundle);
pendingIntent = PendingIntent.getBroadcast(this, 0, i, 0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), PERIOD, pendingIntent);
}
in onResume() method I am registering another receiver using registerReceiver() method:
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(com.commonsware.cwac.locpoll.LocationPollerParameter.INTENT_TO_BROADCAST_ON_COMPLETION_KEY);
intentFilter.setPriority(1);
registerReceiver(locationReceiver, intentFilter);
}
Where locationReceiver looks like:
private BroadcastReceiver locationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "mapActivity called");
abortBroadcast();
}
};
And in order to send ordered broadcast to multiple receiver I have modified LocationPollerService to use sendOrderedBroadcast instead of sendBroadcast
public void onLocationChanged(Location location) {
handler.removeCallbacks(onTimeout);
Intent toBroadcast = createIntentToBroadcastOnCompletion();
toBroadcast.putExtra(LocationPollerResult.LOCATION_KEY, location);
sendOrderedBroadcast(toBroadcast, null);
quit();
}
Now the problem is my dynamically registered receiver never get called but the one mentioned in AndroidManifest.xml does:
<receiver android:name=".receiver.LocationReceiver" />
<receiver android:name="com.commonsware.cwac.locpoll.LocationPoller" />
<service android:name="com.commonsware.cwac.locpoll.LocationPollerService" />
Your problem is in a disconnect between the IntentFilter you create in Java and your createIntentToBroadcastOnCompletion() implementation, which you did not include in your question. Your IntentFilter is expecting a broadcast with a certain action string -- the Intent you are creating in createIntentToBroadcastOnCompletion() apparently does not include this action string.
BTW, with respect to "And in order to send broadcast to multiple receiver", sendBroadcast() is perfectly capable of sending broadcasts to multiple receivers.

Broadcast Action: ACTION_CAMERA_BUTTTON

Is there any way after this action has been broadcast via a receiver to determine that the action has finished? i.e the user has exit camera mode and is doing something else?
You can register a broadcast receiver to receive this intent.
Note however that this intent will be broadcasted every time the user pushes the camera button, and is thus not directly related to any specific "action" (e.g. taking a photo).
BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do whatever you want to do
}
};
registerReceiver(myReceiver, new IntentFilter(Intent.ACTION_CAMERA_BUTTON));
unregisterReceiver(myReceiver);
Is there any way after this action has been broadcast via a receiver to determine that the action has finished?
No. For starters, there may be no "action" to "finish", and there is no definition of "action".

Categories