Google Glass How to know if the glass is worn - android

I know this problem is really vague but i am really looking for a informative answer of how to do it.. or stuff like that..
A question on Stackoverflow already..
There are two ways to do it. One is the on Head wake and the other is notification glance. Can these be accessed for glassware apps. Can we basically control the glass rear view camera when inside an app and verify whether a user has actually worn it rather than just having a vague access with head wake or notificaiton glance.

You can listen to the ACTION_ON_HEAD_STATE_CHANGED broadcast Intent to know if the user is wearing Glass or not: this requires that the user has turned this feature on.
To do so, create a BroadcastReceiver to handle the Intent and register it within your Activity:
BroadcastReceiver mOnHeadStateChangedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean isOnHead = intent.getBooleanExtra(Intents.EXTRA_IS_ON_HEAD, false);
// Process the intent.
}
};
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(Intents.ACTION_ON_HEAD_STATE_CHANGED);
registerReceiver(mOnHeadStateChangedReceiver, filter);
}
#Override
protected void onPause() {
unregisterReceiver(mOnHeadStateChangedReceiver);
super.onPause();
}
This example is using an Activity but this can be done in a Service or anywhere you have access to a valid Context.

Related

Broadcast action for WIFI change

In my application I have to get notified whenever the device connects or disconnects from a WIFI network. For this I have to use a BroadcastReceiver but after reading through different articles and questions here on SO I'm a bit confused which Broadcast action I should use for this. In my opinion I have three choices:
SUPPLICANT_CONNECTION_CHANGE_ACTION
NETWORK_STATE_CHANGED_ACTION
CONNECTIVITY_ACTION
To reduce resources I really only want to get notified whenever the device is CONNECTED to a WIFI network (and it has received an IP address) or when the device has DISCONNECTED from one. I do not care about the other states like CONNECTING etc.
So what do you think is the best Broadcast action I should use for this? And do I have to manully filter the events (because I receieve more then CONNECTED and DISCONNECTED) in onReceive?
EDIT: As I pointed out in a comment below I think SUPPLICANT_CONNECTION_CHANGE_ACTION would be the best choice for me but it is never fired or received by my application. Others have the same problem with this broadcast but a real solution for this is never proposed (in fact other broadcasts are used). Any ideas for this?
You can go for WifiManager.NETWORK_STATE_CHANGED_ACTION works.
Register receiver with WifiManager.NETWORK_STATE_CHANGED_ACTION Action, either in Manifest or Fragment or Activity, which ever suited for you.
Override receiver :
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
boolean connected = info.isConnected();
if (connected)
//call your method
}
}
Please try
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction("android.net.wifi.STATE_CHANGE");
registerReceiver(networkChangeReceiver, filter);
}
#Override
protected void onDestroy() {
unregisterReceiver(networkChangeReceiver);
super.onDestroy();
}
and
BroadcastReceiver networkChangeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (!AppUtils.hasNetworkConnection(context)) {
showSnackBarToast(getNetworkErrorMessage());
}
}
};
I am using this and it is working for me. Hope it will help you out.

sendStickyBroadcast() does not really stick around

I am currently working on a test application that will show a dialog that asks the user to stop using the app if he/she is driving. Supposing that the user has their GPS on, I have created a custom intent to be broadcast and then on the onReceive() method of the subclassed BroadcastReceiver class, the speed of the vehicle is calculated and if it's found to be in the range of usual car speeds, a dialog is shown to the user.
The second part (the onReceive() code) works great: the speed is calculated and the dialog is shown. However, I am at a loss about how the dialog can be shown at any point of the lifeycle of that specific activity. If the app is launched while the user is driving or if the user navigates to another activity and then back to the activity that does the speed check (essentially, if onCreate() or onResume() are called), the dialog is shown. If the dialog is dismissed and the user stays on the same activity, the dialog is not reshown, even if the user keeps driving (to be clear, the desired behavior is for the dialog to keep getting shown for as long as the user keeps driving and is in the activity). Here is the code of the activity that sends the Broadcast(the relevant code, everything else is omitted):
public class MainActivity extends Activity {
IntentFilter intentFilter;
SpeedReceiver speedceiver = new SpeedReceiver();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
broadcastSender();
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.animationshitz.ACTION_GET_SPEED");
}
public void onResume() {
super.onResume();
registerReceiver(speedceiver, intentFilter);
Log.d("Loggger", "BROADCAST RECEIVER REGISTERED");
}
public void onPause() {
super.onPause();
unregisterReceiver(speedceiver);
}
public void broadcastSender() {
Intent intent = new Intent();
intent.setAction("com.example.animationshitz.ACTION_GET_SPEED");
sendStickyBroadcast(intent);
Log.d("Loggger", "BROADCAST SENT");
}
}
Am I completely wrong about this? I thought that the sticky broadcast would keep calling the onReceive() method of the receiver so that it would keep checking the speed in the background. Is there some other way to achieve what I want? Maybe the onReceive() method should start a service that keeps checking the speed in the background? Any help would be really appreciated.

Application never receives RSSI_CHANGED_ACTION

I am new to Android programming and am trying to understand the concept of BroadcastReceivers. In order to help myself, I am just trying to write a small application that monitors Wifi signal strength.
Now, from my understanding I can simply wait to receive the RSSI_CHANGED_ACTION broadcasted by the system. The RSSI should change frequently which means I should be receiving this notification frequently...however, never do I receive it once. I have watered my code down to the bare minimum so it just logs a message when the notification is received.
public class RssiActivity extends Activity {
public BroadcastReceiver rssiReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d("Rssi", "RSSI changed");
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onResume() {
super.onResume();
registerReceiver(rssiReceiver, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
Log.d("Rssi", "Registered");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(rssiReceiver);
Log.d("Rssi", "Unregistered");
}
}
I have already seen this post Android: How to monitor WiFi signal strength and it doesn't seem to help me. I have also tried the code sample here http://android-er.blogspot.com/2011/01/check-rssi-by-monitoring-of.html and it never updated the RSSI value either. I'm quite confused as to why this is. Any help you can give me would be greatly appreciated. Thanks!
So, I had the same problem that you did, wanting to an updated RSSI value as the user walked around, etc, and I could not solve it using RSSI_CHANGED_ACTION.
Like the issue you're having, my callback would not be called correctly. Strangely, it was only called once, when the activity was created, and then never again.
My Workaround
In your onCreate(), register a callback for SCAN_RESULTS_AVAILABLE_ACTION. Then call WifiManager.startScan().
Now, in your callback, do:
WifiManager wifiMan=(WifiManager)getActivity().getSystemService(Context.WIFI_SERVICE);
int newRssi = wifiMan.getConnectionInfo().getRssi();
wifiMan.startScan();
Now you have a loop, where the callback initiates a scan, receives the results, and initiates another scan.
It's gross and will suck a lot of power, however, you can watch the RSSI values change as you walk around.
Full Code
(note that I use onResume and onPause to register and unregister, so it will only scan repeatedly, e.g. waste battery, when the activity is onscreen)
#Override
public void onResume() {
super.onResume();
//Note: Not using RSSI_CHANGED_ACTION because it never calls me back.
IntentFilter rssiFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
this.registerReceiver(myRssiChangeReceiver, rssiFilter);
WifiManager wifiMan=(WifiManager)getActivity().getSystemService(Context.WIFI_SERVICE);
wifiMan.startScan();
}
#Override
public void onPause() {
super.onPause();
this.unregisterReceiver(myRssiChangeReceiver);
}
/**
* Broadcast receiver to update
*/
private BroadcastReceiver myRssiChangeReceiver
= new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent arg1) {
WifiManager wifiMan=(WifiManager)getActivity().getSystemService(Context.WIFI_SERVICE);
wifiMan.startScan();
int newRssi = wifiMan.getConnectionInfo().getRssi();
Toast.makeText(getActivity(), ""+newRssi, Toast.LENGTH_SHORT).show();
}};
Sorry I'm so late, I just had to find out I had to solve your problem :P
WifiManager.RSSI_CHANGED_ACTION is triggered when the RSSI levels change. I.E. you lose or win a wifi bar. It does not happen that often.
My guess is it's sticky so it triggers when registered.
As said, the best way I found to solve the problem is through WifiManager.SCAN_RESULTS_AVAILABLE_ACTION .
are you shure that it has to trigger (meaning are you shure the signal strength is changing)? have you read the BroadcastReciever Dokumentation?
Note: If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause(). (You won't receive intents when paused, and this will cut down on unnecessary system overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back in the history stack.
Try to register your reciever inside of your AndroidManifest.

How to stop service when ACTION_SCREEN_OFF

I am trying to make my UpdateService for my digital clock widget stop when the screen is turned off to conserve battery, and then back on when the screen is activated. I currently have it in my onReceive() in my AppWidgetProvider, but I have also tried it in a BroadcastReciever.
My current code is:
public static boolean wasScreenOn = true;
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.d("Screen switched on. ", "Starting DigiClock UpdateService.");
context.startService(new Intent(UpdateService2by2.ACTION_UPDATE));
wasScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d("Screen switched off. ", "Stopping DigiClock UpdateService.");
context.stopService(new Intent(context, UpdateService2by2.class));
wasScreenOn = true;
}
Can anyone help me out here? I am stumped.
I'm fairly sure that you have to register your receiver in code for ACTION_SCREEN_OFF/ON. I don't think registering them in the manifest will work.
It seems you cannot register for the ACTION_SCREEN_ON/OFF intents with a filter in the manifest. You have to register your BroadcastReceiver in code. See here for an examples for an activity and a service.
You'll only receive the intent if your service or activity is running. In contrast to other broadcast events, the system will not start your process to handle the SCREEN_ON intent. It is similar to ACTION_BATTERY_CHANGED in this regard.
To handle this intent with a widget, I think you have to start a service that listens for the intent and then notifies your widget.
The article linked from Jens' answer to this same question provides a great presentation on this topic. I used it to implement a solution that worked for me.
The key insight is that your BroadcastReceiver can only be registered in code; you neither want nor need an entry in your manifest.
I recommend the article, but for those in a hurry, the simplest possible functioning approach would be to just paste something like this into your activity's onCreate() method:
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver screenoffReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.v("screenoffReceiver", "SCREEN OFF");
}
else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.v("screenoffReceiver", "SCREEN ON");
}
return;
}
};
registerReceiver(screenoffReceiver, filter);
As the article points out, for a running activity, onPause() / onResume() are always called when the power button is used to blank/unblank the display, so if you have something that you don't mind doing even in those cases for which the power button was not the reason for the onPause() or onResume() call, you can do it in those methods and thereby catch every instance of the power button being used to blank or unblank the screen (along with calls due to other causes), without the overhead of creating a BroadcastReceiver.
That was the case for me; I had a button that made my activity's main view invisible when pressed and visible when released, and if the user held the button down and then tapped the power button while the app was hidden, it would stay hidden permanently when the screen was unblanked by another tap of the power button. So in my case I only had to put a setVisibility(VISIBLE) call for my main view in my activity's onResume() override.
In fact, as the article shows, even if you only want to respond to the power button events, the proper way to do that is to set a flag in the BroadcastReceiver and then test that flag in onPause() and/or onResume() to see if the power button was the specific cause of the call to those methods.
Maybe you should use
public class MyReceiver extends BroadcastReceiver {..}
And then use this classname in the manifest

Inform Activity from a BroadcastReceiver ONLY if it is in the foreground

Maybe it's easy, but I couldn't really figure this out right so far... I got a BroadcastReceiver waiting to get triggered by the AlarmMangager - this works fine.
Now: because the event, if it occurs, needs to refresh some elements on screen of the main Activity, I would like to send an Intent from that background BroadcastReceiver to my Activity - but only if it is currently in the foreground, aka active.
If it is not running or not visible, I don't care - and the last thing I want to do is start the Activity by my intent! I handle repainting of the views in my onResume() method, so I don't care at all.
Any hints on how to do that?
Thanks!
EDIT: my BroadcastReceiver is waiting for alarms that must be notified to the user. So, it must be there and declared in the manifest. The problem is: it will have to decide whether the mentioned Activity is currently up in front or not.
I believe that you're familiar with AlarmManager now (creating a new Alarm, register a receiver...) so I will not talk about that. Just give you a solution for your question.
Instead of registering a BroadcastReceiver in a class file and in manifest, you only create a new BroadcastReceiver in your activity, and then, register it in onResume method, and unregister it in onPause method, sth like this in your activity:
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//do something
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("your alarm action");
...
}
#Override
protected void onResume() {
registerReceiver(mIntentReceiver, mIntentFilter);
...
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(mIntentReceiver);
...
super.onPause();
}
The receiver will only receive the alarm intent when your activity is in foreground :)
(Sorry if my English is not clear)
So this is almost Bino's answer, but: instead of moving the receiver into the activity, use two receivers, with different Intents. The first one is your original alarm Intent, with a receiver registered in the manifest as you already have, and then that receiver sends a second broadcast intent, which is handled by a receiver registered by the activity as Bino says.
I've done this in my own timer project, on github. Here are the alarm receiver and the requery receiver. Hope that helps.

Categories

Resources