I am new to game development, and i'm struggling a bit with combining the google play service realtime multiplayer functionality in my LibGDX game. I do not find a lot of tutorials regarding this online.
I have downloaded the BaseGameUtils library, and everything is connected (my signIn method works), and i'm using interfaces to combine the android package with my core package.
In my AndroidLauncher, i have this code:
#Override
public void startQuickGame() {
final int MIN_OPPONENTS = 1, MAX_OPPONENTS = 1;
Bundle autoMatchCriteria = RoomConfig.createAutoMatchCriteria(MIN_OPPONENTS, MAX_OPPONENTS, 0);
RoomConfig.Builder rtmConfigBuilder = RoomConfig.builder((RoomUpdateListener) this);
rtmConfigBuilder.setMessageReceivedListener((RealTimeMessageReceivedListener) this);
rtmConfigBuilder.setRoomStatusUpdateListener((RoomStatusUpdateListener) this);
rtmConfigBuilder.setAutoMatchCriteria(autoMatchCriteria);
//prevent screen from sleeping
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Games.RealTimeMultiplayer.create(gameHelper.getApiClient(), rtmConfigBuilder.build());
}
I try to use the code in my Menu class:
#Override
protected void handleInput() {
if (Gdx.input.justTouched() && isOnBtn()) {
try {
crush.playServices.startQuickGame();
} catch (Exception e) {
e.printStackTrace();
}
gsm.set(new OnlineMultiplayerState(gsm));
dispose();
I'm not sure about how i should actually start the game?
At this point, everything just go black.
I would also like to use the code for methods like
handleSelectPlayersResult(int response, Intent data)
The problem is that when i try to define this method in my interface, it wont work because Intent only work in the Android package (not in core where my interface is).
Do you have an suggestion to how i can solve this?
Thank You!
Related
I want to implement Google Play Games Services in my game on the libgdx engine. I tried using gdx-gamesvcs for this. But I am having trouble saving data. I understood from the example that one value is being saved, not the entire state of the game. So I decided to check it out: save and load one value using gsClient.loadGameState and gsClient.saveGameState. I deliberately deleted the game data from the device. But as a result, not only the test value changed, but many others as well. I thought that the state of the entire game is being saved, but the values obtained do not fit into the logic of the game and could not be obtained in it.
How should I use this tool and is it worth it at all, or is it better to use what libgdx itself offers?
Here is a piece of code:
if (gsClient.isSessionActive()) {
try {
gsClient.saveGameState("data", intToByteArray(testValue), 0, null);
} catch (UnsupportedOperationException unsupportedOperationException) {
}
if (gsClient.isSessionActive()) {
try {
gsClient.loadGameState("data", new ILoadGameStateResponseListener() {
#Override
public void gsGameStateLoaded(byte[] gameState) {
if (gameState != null) {
setTestValue(bytesToInt(gameState));
}
}
});
} catch (UnsupportedOperationException unsupportedOperationException) {
}
}
UPD
Yes, saving occurs both to the cloud and to the device, for saving to the device I use Preferences. I have a Google account login button in the game, it works, I have repeatedly seen this standard bar of my account level, which appears at the top when I log in. Everything is set up in the developer console too, I have an id for achievements and leaderboards. In code, I work with the client like this (In the create() method):
public IGameServiceClient gsClient;
if (gsClient == null) {
gsClient = new MockGameServiceClient(1) {
#Override
protected Array<ILeaderBoardEntry> getLeaderboardEntries() {
return null;
}
#Override
protected Array<String> getGameStates() {
return null;
}
#Override
protected byte[] getGameState() {
return new byte[0];
}
#Override
protected Array<IAchievement> getAchievements() {
return null;
}
#Override
protected String getPlayerName() {
return null;
}
};
}
gsClient.setListener(this);
gsClient.resumeSession();
Next is loading.
The exception is not caught, I removed it and everything works as before.
Well, libgdx offers no built-in cloud-save, it is hard to use it for that. :-)
You should in any case save to local AND to cloud, as the cloud is not very fast to load its state.
I can see no problem in your code besides the fact that you swallow an UnsupportedOperationException that is thrown if you did not activate cloud save feature. So the interesting question is: what happens if you don't swallow the exception, and did you intialize GpgsClient with cloud save enabled? Are you really logged in to Gpgs, and is the feature also activated in your developer console?
The main problem was that gameState was null, this arose due to the fact that you had to wait 24 hours after enabling the save function in the developer console, and the advice on clearing the memory of google play games on the test device did not help. After a while gameState began to pass the existing values, but I started having problems with the graphics flow, probably due to the asynchronous loading.
I have made an app in android studio and a game in Unity. Now I want to combint these two together. Starting is no problem in android calling the unityNativePlayer. But when I want to go back from the unity activity to the MainActivity.java it comes to this: I have an exit button in the unity game calling Application.exit(); and nothing happens when I press the button. Is there a mistake?
Application.exit() does not exist in Unity API.
For the Editor, use UnityEditor.EditorApplication.isPlaying = false;
Use Application.Quit() for your builds.
It is better to use Editor pre-processor to do this or you will have problem building your code that contains UnityEditor.EditorApplication.isPlaying = false; line of code for other platforms.
The code below should solved that problem:
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
Please understand that you should not have have any exit UI Button for mobile devices. It will work but it is a bad design. This is what the physical Home(iOS) or back(Android) buttons are used for.
EDIT:
You just want to quit Unity Activity from Java. The function should do it.
public void quitUnityActivity ()
{
UnityPlayer.currentActivity.runOnUiThread(new Runnable(){
public void run()
{
Log.v("Unity", "Unity Activity Exited!" );
this.mUnityPlayer.quit();
UnityPlayer.currentActivity.finish();
}
});
}
If that doesn't work, try
public void quitUnityActivity()
{
Log.v("Unity", "Unity Activity Exited!");
this.mUnityPlayer.quit();
UnityPlayer.currentActivity.finish();
}
To call the Java function from Unity using C#.
void exitUnity()
{
AndroidJavaClass myClass = new AndroidJavaClass("com.companyName.productName.MyClass");
myClass.Call("quitUnityActivity");
}
Make sure to replace com.companyName.productName.MyClass with whatever you named your class in your Android Studio.
Google review team requires glassewares to:
Dim the screen if there isn't an expectation that a user is
looking at it.
This is consistent with the "in the here and now" experience of Glass.
Glassware should always dim the screen if there isn't an expectation
that a user is looking at it. Ideally it behaves like a timeline and
dims after 15s. A user can 'rewake' the screen by looking up.
Update to be made: If a user is not looking at the results set in the
card scroller, dim the screen.
This hints at using the EyeGesture, which doesn't seem to be mentioned anywhere on the Glass Develop Page.
After some searching I found this EyeGesture library (github) that from this stackoverflow post (Google Glass Eye Gesture Crashing (EyeGestureLib)) doesn't seem to work anymore (and hasn't been updated in 4 months+).
The accepted answer (from the stackoverflow post) proposed using this revised EyeGesture library (github)
It was also mentioned (in the stackoverflow post - as a comment ) that:
Basically, you're trying to expose classes that exist in the Glass
environment itself, but not through the official APIs. By declaring
these stub classes (none of the methods are implemented) and by
putting them into the com.google.android.glass.eye package, we're
allowing our code to compile with these unimplemented classes. At
runtime, the system has implementations of those classes and the
application will instead use the system's implementations.
Here are my following questions:
Will there be (and when) an offcial API for EyeGesture's any time soon?
I tried Implementing the revised EyeGesture library into my activity by following the guide proposed without any luck. What could I be doing wrong?
Is there something I'm missing for it to be detected? I know that with the GestureDetector I'm required to Override the onGenericMotionEvent(MotionEvent event), is there something similar for the EyeGesture?
Here is what I'm currently doing:
I have a package named com.google.android.glass and in this package I have the following:
EyeGesture enum that implements Parcelable
EyeGestureManager class
I have in the main package:
GestureIds class (This one is different the github in that it's a public class and not private)
In my activity I have:
private void createEyeGestureDetector(ResultActivity resultActivity) {
final GestureIds gestureIds = new GestureIds();
//The github guide didn't mention any class names for
//mEyeGestureManager and mEyeGestureListener .. so I added some..
EyeGestureManager mEyeGestureManager = EyeGestureManager.from(resultActivity);
EyeGestureManager.Listener mEyeGestureListener = new EyeGestureManager.Listener() {
#Override
public void onDetected(EyeGesture gesture) {
Log.i("EyeGestureListener", "Gesture: " + gesture.getId());
int id = gesture.getId();
if(id == gestureIds.WINK_ID || id == gestureIds.DOUBLE_WINK_ID) {
Log.d("EyeGesture", "Wink");
} else if (id == gestureIds.BLINK_ID || id == gestureIds.DOUBLE_BLINK_ID){
Log.d("EyeGesture", "Blink");
} else if (id == gestureIds.LOOK_AT_SCREEN_ID || id == gestureIds.LOOK_AWAY_FROM_SCREEN_ID) {
Log.d("EyeGesture", "Screen");
}
}
};
}
In my onCreate I have:
//..
super.onCreate(bundle);
createEyeGestureDetector(this);
//..
Update Logcat:
When I do:
for (EyeGesture eg : EyeGesture.values()) {
boolean supported = mEyeGestureManager.isSupported(eg);
Log.w("yupyup", eg.name() + ":" + supported);
}
I get:
12-10 18:40:51.252 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ WINK:true
12-10 18:40:51.252 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ DOUBLE_WINK:false
12-10 18:40:51.252 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ BLINK:false
12-10 18:40:51.252 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ DOUBLE_BLINK:true
12-10 18:40:51.260 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ DON:true
12-10 18:40:51.268 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ DOFF:true
12-10 18:40:51.268 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ LOOK_AT_SCREEN:true
12-10 18:40:51.268 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ LOOK_AWAY_FROM_SCREEN:false
I also added (from the first github link):
#Override
protected void onStart(){
super.onStart();
createEyeGestureDetector(this);
for (EyeGesture eg : EyeGesture.values()) {
boolean supported = mEyeGestureManager.isSupported(eg);
Log.w("yupyup", eg.name() + ":" + supported);
}
mEyeGestureManager.register(EyeGesture.LOOK_AT_SCREEN, mEyeGestureListener);
mEyeGestureManager.register(EyeGesture.LOOK_AWAY_FROM_SCREEN, mEyeGestureListener);
mEyeGestureManager.register(EyeGesture.WINK, mEyeGestureListener);
}
and
#Override
protected void onStop(){
mEyeGestureManager.unregister(EyeGesture.LOOK_AT_SCREEN, mEyeGestureListener);
mEyeGestureManager.unregister(EyeGesture.LOOK_AWAY_FROM_SCREEN, mEyeGestureListener);
mEyeGestureManager.unregister(EyeGesture.WINK, mEyeGestureListener);
super.onStop();
}
This gives me:
12-10 18:46:11.314 2553-2553/com.google.android.glass.websurg.websurg I/EyeGestureManager﹕ Removing listener: com.google.android.glass.websurg.websurg.ResultActivity$1#41b8b908 for eye gesture: LOOK_AT_SCREEN
12-10 18:46:11.314 2553-2553/com.google.android.glass.websurg.websurg I/EyeGestureManager﹕ Removing listener: com.google.android.glass.websurg.websurg.ResultActivity$1#41b8b908 for eye gesture: LOOK_AWAY_FROM_SCREEN
12-10 18:46:11.314 2553-2553/com.google.android.glass.websurg.websurg I/EyeGestureManager﹕ Removing listener: com.google.android.glass.websurg.websurg.ResultActivity$1#41b8b908 for eye gesture: WINK
However they do not get detected.. even the WINK since it seems to be supported.
Google team already answered some of these but I will go ahead and provide more details about their answer and also provide an alternate way of doing these stuff you requested.
Dim the screen if there isn't an expectation that a user is looking at
it.
This is consistent with the "in the here and now" experience of Glass.
Glassware should always dim the screen if there isn't an expectation
that a user is looking at it. Ideally it behaves like a timeline and
dims after 15s. A user can 're-wake' the screen by looking up.
Update to be made: If a user is not looking at the results set in the
card scroller, dim the screen.
Glass handles that itself but the problem is that if the user doesn't touch the Glass pad for about 10 seconds or more, Glass will go to sleep and your App will stop running.
Great way of fixing this is to make Glass screen always on and check when the user looks at the screen or when they remove the Glass.
If the user looks at the screen, increase the brightness of the screen, if they look away, decrease the brightness of the screen.
If they remove the Glass from their face, decrease the brightness to zero, turn off the screen and stop running all the big CPU intensive code you have.
If they put back the Glass on their face, increase the brightness of the screen,turn on the Screen and then enable all your CPU intensive code.
You could just have a boolean variable to determine when to start or stop running. This method is recommended if you don't want your app to stop running after no touch event for seconds. It also saves battery when running your app.
Code Examples for the things I said above are below:
To Get Screen Brightness:
//Get Screen Brightness
public float getScreenBrightness() {
WindowManager.LayoutParams wMLayout = getWindow().getAttributes();
return wMLayout.screenBrightness;
}
To Set Screen Brightness(0 to 1):
//Set Screen Brightness
public boolean setScreenBrightness(float sBrightness){
if(sBrightness>=0){
WindowManager.LayoutParams wMLayout = getWindow().getAttributes();
wMLayout.screenBrightness = sBrightness; //Modify Brightness
getWindow().setAttributes(wMLayout); //Apply changes
return true;
}else
{
return false;
}
}
To Keep the Screen On or Off:
//Turn Screen On/Off
public void keepScreenOn(boolean screenOn){
if(screenOn) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}else{
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
Don't forgeet to add permision in the Manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
If you are just doing developing and don't want to worry about permision right now, you can use:
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
and avoid having to look up what permission to use. I suggest you use that for now as it will save you time during development and you don't have to worry about permission when coding.
[EYE GESTURE]
No Google official API available for detecting those. Anything available now is a little hack to access hidden Glass API for that. Glass team is working on it and they said the API will only be release when it is reliable. Right now, it is NOT perfect according to them.
NOTE
The answer I am about to post below SHOULD work but may NOT work on the next Glass update. When they do update, something magically changes and one function will STOP working. Glass API and Glass itself is on Beta Mode and therefore expect things to keep changing until official EYE Gesture API gets released.
There are two ways to detect Eye Gesture. One way is to use IntentFilter and wait for "gesture" message.Another way is to use Stub Library to Access the hidden Glass API. I will talk about both here as there are prons and cons for each method.
Method 1 (Stub Lib):
This is the way you are currently trying to do it.
Pros:
Can detect more gestures
Cons:
Wink CANNOT be stooped from taking pictures.
Yo are using different library than the one I used that is still working. I will try to fix your problem if that doesn't work, You should then do it the way I did mine with the library I used too.
You got Step 1 wrong.
Step 1: Create the stubs:
Create a package called com.google.android.glass. In this package
create two classes: EyeGesture and EyeGestureManager
It should be
com.google.android.glass.eye
NOT
com.google.android.glass
com.google.android.glass may have worked in the past but there were too many updates.
So, EyeGesture and EyeGestureManager must be placed in your package called com.google.android.glass.eye
If Eye gesture is still not detected, forget about that library and use the one I am currently using. Close your project and create a new one.
Steps:
1) Download the library from here. (Last update was 4 months ago). The one you are currently using was probably last updated 8 months ago or even a year ago.
https://github.com/prt2121/EyeGestureLib
The zip file will have a long name like "EyeGestureLib-fwenindioniwenubwudew".
Rename the Zip file to "EyeGestureLib".
Extract the folder inside with a long name like "EyeGestureLib-f8a9fef3bde4396f947106e78cd0be7c7ecdd5a6"
Rename that folder to "EyeGestureLib"
The "EyeGestureLib" folder should have two folders inside it called "EyeGestureStub" and "EyeGestureDemoApp" plus other useless files.
2) Open Eclipse and create a new project.
create a simple MainActivty class activity.
3) Inside your MainActivity class:
private EyeGestureManager mEyeGestureManager;
private EyeGestureListener mEyeGestureListener;
private EyeGesture target1 = EyeGesture.WINK;
private EyeGesture target2 = EyeGesture.DOUBLE_BLINK;
private EyeGesture target3 = EyeGesture.LOOK_AT_SCREEN;
Inside onCreate:
mEyeGestureManager = EyeGestureManager.from(this);
mEyeGestureListener = new EyeGestureListener();
Inside onStart:
mEyeGestureManager.register(target1, mEyeGestureListener);
mEyeGestureManager.register(target2, mEyeGestureListener);
mEyeGestureManager.register(target3, mEyeGestureListener);
Inside onStop:
mEyeGestureManager.unregister(target1, mEyeGestureListener);
mEyeGestureManager.unregister(target2, mEyeGestureListener);
mEyeGestureManager.unregister(target3, mEyeGestureListener);
Inside MainActivity (Not inside any function but just anywhere inside you MainActivity class):
private class EyeGestureListener implements Listener {
#Override
public void onEnableStateChange(EyeGesture eyeGesture, boolean paramBoolean) {
}
#Override
public void onDetected(final EyeGesture eyeGesture) {
//Show what we just detected
Log.i(eyeGesture.toString() , " is detected");
//Check which eye event occured
if (eyeGesture.name() == target1.name()) {
// Wink
Log.i("EyeGesture: ", " you just winked");
} else if (eyeGesture.name() == target2.name()) {
// Double blink
Log.i("EyeGesture: ", " you just double winked");
} else if (eyeGesture.name() == target3.name()) {
// Look at Screen
Log.i("EyeGesture: ", " you Looked at Screen");
}
}
}
4) You will get error.
Import the EyeGestureStub that is inside the EyeGestureLib folder to fix it.
To fix the error:
a) Go to File -> Import -> Android -> Existing Android Code into Workspace
Click Next, Browse and Browse the EyeGestureStub folder inside EyeGestureLib folder.
Make sure to exclude the "EyeGestureDemoApp" if it is there. You ONLY need EyeGestureLib folder which contains EyeGesture and EyeGestureManager.
b) Right click on "EyeGestureStub" -> Properties -> Android ->
On the right side,under Project Build Target make sure that "Glass Development Kit Preview" check-box is checked.
Under Library, make sure that the "Is Library" check-box is checked.
Click Apply and Ok to exit the window.
c) Open Android SDK Manger. check for the version of Android SDK Build-tools installed. I have 21.1.1.
d) Open the project.properties of EyeGestureStub and change sdk.buildtools=18.1.1 to sdk.buildtools=21.1.1
Finish.
Done. It should work if you followed the instruction.
Run it and choose MainActivity as the the Launch Activity.
<-------------------------------------------------------------------------------------------------------------------------------->
[STILL NOT WORKING? IMPORT EVERYTHING && work from there]
If you can't get it to Work, delete the current project and import the whole project downloaded then work from there up. This is the easiest way. You may need to fix some errors before you can compile.**
To import the project,
1) Go to File -> Other -> Android -> Android Project from Existing Code.
Next -> Browse
then choose the EyeGestureLib folder which contains both the EyeGestureStub and EyeGestureDemoApp.
Make sure under Project to Import that both EyeGestureStub and EyeGestureDemoApp are check-box are checked then click Finish.
2) Right click on "EyeGestureStub" -> Properties -> Android ->
On the right side,under Project Build Target make sure that "Glass Development Kit Preview" check-box is checked.
Under Library, make sure that the "Is Library" check-box is checked.
Click Apply and Ok to exit the window.
3) Right click on "MainActivity" -> Properties -> Android ->
On the right side,under Project Build Target make sure that "Glass Development Kit Preview" check-box is checked.
4) You will get invisible error that will not be showing.
To see it Go to Windows -> Show View -> Problems
There, you will see all the problems.
Next step to fix it, we have to match the Android SDK Build-tools version with the ones listed in the project.properties of both EyeGestureStub and MainActivity
a) Open Android SDK Manger. check for the version of Android SDK Build-tools installed. I have 21.1.1.
b) Open the project.properties of EyeGestureStub and change sdk.buildtools=18.1.1 to sdk.buildtools=21.1.1
c) Open the project.properties of MainActivity and change sdk.buildtools=18.1.1 to sdk.buildtools=21.1.1
Note: Changing the first project.properties may automatically change the second one.
Done. It should work if you followed the instruction.
Run it and choose MainActivity as the the Launch Activity.
<-------------------------------------------------------------------------------------------------------------------------------->
Method 2 (IntentFilter)
Pros:
Wink CAN be stopped from taking pictures.
Cons:
Detects WINK ONLY
The first method can receive four events (WINK,DOUBLE_WINK,DOUBLE_BLINK,LOOK_AT_SCREEN,) but this method can ONLY receive one event (WINK).
This method is useful if you just want to detect ONLY WINK without Glass taking a picture.
To listen to Intent, you have to extend BroadcastReceiver.
public class EyeGesture extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra("gesture").equals("WINK")) {
//Disable Camera Snapshot
abortBroadcast();
Log.e("WINKED ","");
}else {
Log.e("SOMETHING", "is detected " + intent.getStringExtra("gesture"));
}
}
}
You must register the intent in the Manifest as below:
<receiver android:name="com.inno.inno.glassplugin.EyeGesture">
<intent-filter>
<action android:name="com.google.android.glass.action.EYE_GESTURE" />
</intent-filter>
</receiver>
The name specified in the Manifest must match the name of the class listening to the intent which is EyeGesture.
Simple as that. No library required but only WINK can be detected. It also stops Glass from taking picture when wink is detected. You can comment abortBroadcast(); if you want Glass to take picture when event is detected.
This is for any one looking to detect Eye Gesture from Glass at this moment. These are the only current solutions around until Google releases their official Eye Gesture API.
You should file for a new Glass API feature here. File it as Glass Eye Gesture API Request. If the Glass team receives too much of this feature request, they will make it their top priority and release it. I already filed for one.
Got a return from the Google Glass Review team. Their response to :
Dim the screen if there isn't an expectation that a user is looking at
it.
This is consistent with the "in the here and now" experience of Glass.
Glassware should always dim the screen if there isn't an expectation
that a user is looking at it. Ideally it behaves like a timeline and
dims after 15s. A user can 'rewake' the screen by looking up.
Update to be made: If a user is not looking at the results set in the
card scroller, dim the screen.
was this:
The platform handles this, are you overriding this in some way, are
you holding a wake-lock when the result is shown?
So it seems as of now it is not intended to actually work straight with the EyeGesture, since it apparantely does it automatically (need confirmation on this part). In any case there is no point in trying to handle the LOOK_AT_SCREEN since the LOOK_AWAY_FROM_SCREEN isn't handled.
12-10 18:40:51.268 2405-2405/com.google.android.glass.websurg.websurg W/yupyup﹕ LOOK_AWAY_FROM_SCREEN:false
For those interested in handling the Wink EyeGesture here is what apparantely works according to some information I've gathered (needs to be confirmed).
The idea is to use is to use an EyeGesture and EyeGestureManager stub. Pretty much they exist within the environment but not in the API. This means to access them you need to create Subs that durring runtime will work (atleast that's how I understood it).
Apparantely there is a known bug when handling the WINK EyeGesture. It will take a picture. This may be caused from within the Google Glass settings where Take a picture when a wink is detected is activated. (needs to be confirmed).
So how to actually handle it?
Step 1: Create the stubs:
Create a package called com.google.android.glass. In this package create two classes: EyeGesture and EyeGestureManager
EyeGesture:
package com.google.android.glass.eye;
import android.os.Parcel;
import android.os.Parcelable;
/**
* https://gist.github.com/victorkp/9094a6aea9db236a97f3E
*
*/
public enum EyeGesture implements Parcelable {
BLINK, DOFF, DON, DOUBLE_BLINK, DOUBLE_WINK, LOOK_AT_SCREEN, LOOK_AWAY_FROM_SCREEN, WINK;
public int getId(){
return -1;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
}
EyeGestureManager:
package com.google.android.glass.eye;
import android.content.Context;
/**
*
* If there are any updates required check: https://gist.github.com/victorkp/9094a6aea9db236a97f3
*
*/
public class EyeGestureManager {
public static final int INFINITE_TIMEOUT = -1;
public static final String SERVICE_NAME = "eye_gesture";
public interface Listener {
public void onDetected(EyeGesture gesture);
}
public static EyeGestureManager from(Context paramContext) {
return null;
}
public void activateGazeLogging(boolean paramBoolean) {
}
public boolean applyAndSaveCalibration(EyeGesture paramEyeGesture) {
return false;
}
public boolean clearCalibration(EyeGesture paramEyeGesture) {
return false;
}
public void enableGazeService(boolean paramBoolean) {
}
public boolean endCalibrationInterval(EyeGesture paramEyeGesture) {
return false;
}
public boolean isCalibrationComplete(EyeGesture paramEyeGesture) {
return false;
}
public boolean isGazeLogging() {
return false;
}
public boolean isRegistered() {
return false;
}
public boolean isSupported(EyeGesture paramEyeGesture) {
return false;
}
public boolean loadCalibration(EyeGesture paramEyeGesture) {
return false;
}
public boolean register(EyeGesture gesture, EyeGestureManager.Listener listener){
return false;
}
public boolean startCalibrationInterval(EyeGesture paramEyeGesture) {
return false;
}
public boolean unregister(EyeGesture gesture, EyeGestureManager.Listener listener) {
return false;
}
}
Great, you've got both stubs. First thing you should notice is that they aren't 100% like the one from the github link. Some of the functions have been deprecated, I've kept the ones that work. (I haven't tried every single one).
What is next? Well you need (not really but it's easier if you do) to create the GestureId class (yes you can put this anywhere you want to).
GestureId:
package com.google.android.glass.websurg.websurg;
import com.google.android.glass.eye.EyeGesture;
/**
*
*
* For updates check out: https://gist.github.com/victorkp/9094a6aea9db236a97f3
*
*
*
*/
public class GestureIds {
public int BLINK_ID;
public int WINK_ID;
public int DOUBLE_BLINK_ID;
public int DOUBLE_WINK_ID;
public int LOOK_AT_SCREEN_ID;
public int LOOK_AWAY_FROM_SCREEN_ID;
public GestureIds() {
BLINK_ID = EyeGesture.BLINK.getId();
WINK_ID = EyeGesture.WINK.getId();
DOUBLE_BLINK_ID = EyeGesture.DOUBLE_BLINK.getId();
DOUBLE_WINK_ID = EyeGesture.DOUBLE_WINK.getId();
LOOK_AT_SCREEN_ID = EyeGesture.LOOK_AT_SCREEN.getId();
LOOK_AWAY_FROM_SCREEN_ID = EyeGesture.LOOK_AWAY_FROM_SCREEN.getId();
}
}
Great now you have all the classes to actually get started. Keep in mind the stubs are the ones that will work correctly during runtime (atleast I think so since I don't get any errors?)
Say you have a MainActivity and you want to add the EyeGesture:
private void createEyeGestureDetector(Context context) {
mGestureIds = new GestureIds();
mEyeGestureManager = EyeGestureManager.from(context);
mEyeGestureListener = new EyeGestureManager.Listener() {
#Override
public void onDetected(EyeGesture gesture) {
Log.w("EyeGestureListener", "Gesture: " + gesture.getId());
int id = gesture.getId();
if (id == mGestureIds.WINK_ID || id == mGestureIds.DOUBLE_WINK_ID) {
Log.d("EyeGesture", "Wink");
} else if (id == mGestureIds.BLINK_ID || id == mGestureIds.DOUBLE_BLINK_ID) {
Log.d("EyeGesture", "Blink");
} else if (id == mGestureIds.LOOK_AT_SCREEN_ID || id == mGestureIds.LOOK_AWAY_FROM_SCREEN_ID) {
Log.d("EyeGesture", "Screen");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.w("detected", "omg detected");
}
});
}
};
}
Notice I have also a run(). I've added both since one github linked had it and the other didn't. Tried both and doesn't seem to get detected.
You call this (the one right above) function in your onCreate(); , then in your onResume();
mEyeGestureManager.register(EyeGesture.LOOK_AT_SCREEN, mEyeGestureListener);
mEyeGestureManager.register(EyeGesture.LOOK_AWAY_FROM_SCREEN, mEyeGestureListener);
mEyeGestureManager.register(EyeGesture.WINK, mEyeGestureListener);
The on your onPause():
mEyeGestureManager.unregister(EyeGesture.LOOK_AT_SCREEN, mEyeGestureListener);
mEyeGestureManager.unregister(EyeGesture.LOOK_AWAY_FROM_SCREEN, mEyeGestureListener);
mEyeGestureManager.unregister(EyeGesture.WINK, mEyeGestureListener);
Now all this seems to work (no errors when the functions are called, and logs are shown saying they were called (notice there are no logs in the stubs)).
However, my google glass doesn't seem to be detecting the EyeGesture. I'm pretty sure it's all good, or that I'm missing something minor. I won't accept it as an answer since, it only answers part of my question. Feel free to try this out yourself and let me know how it works.
I'm using the example code on this page (http://altbeacon.github.io/android-beacon-library/samples.html) in the Starting an App in the Background section and I've got a working app.
It detects whenever a beacon is in range even on background.
The problem is I need to know which beacon is it (UUID, Major, Minor) to then match it against my local database and throw a notification with the app still on background.
The didEnterRegion(Region region) function only has a matchesBeacon method, and I've tried doing the following to identify which of the beacons is being seen but it's throwing a NullPointerException:
public class SightSeeing extends Activity implements BootstrapNotifier, RangeNotifier {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Region region = new Region("sightRegion", null, null, null);
regionBootstrap = new RegionBootstrap(this, region);
BeaconManager.getInstanceForApplication(this).getBeaconParsers().add(
new BeaconParser(). setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")
);
BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);
}
#Override
public void didEnterRegion(Region region) {
regionBootstrap.disable();
BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);
try {
BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
Log.e(TAG, "Can't start ranging");
}
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
Iterator<Beacon> beaconIterator = beacons.iterator();
while (beaconIterator.hasNext()) {
Beacon beacon = beaconIterator.next();
//check if beacon exists in our DB and throw notification
}
}
}
Am I missing something obvious or isn't this possible with this library?
EDIT:
I've updated the code sample to give you guys a broader idea and I've tried implementing the suggestion by FOliveira without any success.
EDIT2:
Updated code to reflect the davidgyoung's suggestion. Still no luck. I have a Log.d() right on the first line of the didRangeBeaconsInRegion() function and it isn't being called.
I've tried adding BeaconManager.getInstanceForApplication(this).setRangeNotifier(this); before the try/catch block and the result is the same.
Did I implement the suggestion wrong or is there any other way to get this working?
If you want the app to launch itself on beacon detection, then the RegionBootstrap is the easiest way to go. In order to combine this with Ranging needed to detect individual beacons, then add code in your didEnterRegion method like this:
try {
BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
Log.e(TAG, "Can't start ranging");
}
Then implement a ranging callback like you have.
You also need to remove the code below, which is probably what is causing your NullPointerException, because the :
for(int i=0; i< beaconsList.size(); i++) {
Beacon b = new Beacon.Builder()
.setId1(beaconsList.get(i).get("uuid"))
.setId2(beaconsList.get(i).get("major"))
.setId3(beaconsList.get(i).get("minor"))
.build();
if(region.matchesBeacon(b)) {
//get info from DB and throw notification
}
}
EDIT: I have updated the library's reference application to show how this can be done successfully. See here: https://github.com/AltBeacon/android-beacon-library-reference/blob/master/src/org/altbeacon/beaconreference/BeaconReferenceApplication.java
you can implement RangeNotifier interface and you can access all the beacon information captured in the public void didRangeBeaconsInRegion(Collection<Beacon> Beacons, Region region) method of that interface. Hope i got the question right
I want to make application for cricket live streaming.
I want to know following things :
From where I can found the links to play cricket streaming ?
Which type of links are these ?
Is there any player to play this type of videos ?
Currently, I have implemented web page but I am looking for other alternative.
Below is my code :
link1 = (RelativeLayout) findViewById(R.id.link1);
link2 = (RelativeLayout) findViewById(R.id.link2);
link3 = (RelativeLayout) findViewById(R.id.link3);
link4 = (RelativeLayout) findViewById(R.id.link4);
link5 = (RelativeLayout) findViewById(R.id.link5);
link6 = (RelativeLayout) findViewById(R.id.link6);
link7 = (RelativeLayout) findViewById(R.id.link7);
link1.setOnClickListener(this);
link2.setOnClickListener(this);
link3.setOnClickListener(this);
link4.setOnClickListener(this);
link5.setOnClickListener(this);
link6.setOnClickListener(this);
link7.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.link1:
linkFunction("http://changevssame.blogspot.com/2014/03/willow-cricket-hd-live-streaming.html");
break;
case R.id.link2:
linkFunction("http://changevssame.blogspot.com/2014/03/foxsports-live-streaming.html");
break;
case R.id.link3:
linkFunction("http://changevssame.blogspot.com/2014/03/sky-sports-live-streaming.html");
break;
case R.id.link4:
linkFunction("http://changevssame.blogspot.com/2014/03/ten-sports-live-streaming.html");
break;
case R.id.link5:
linkFunction("http://changevssame.blogspot.com/2014/03/star-cricket.html");
break;
case R.id.link6:
linkFunction("http://changevssame.blogspot.com/2014/03/icc-t20-world-cup-2014-live-streaming.html");
break;
case R.id.link7:
linkFunction("http://changevssame.blogspot.com/2014/03/ptv-sports.html");
break;
default:
break;
}
I will try to answer your questions but there are many fundamentals you've got to learn in order to build up a successful Streaming Application.
1. From where I can found the links to play cricket streaming ?
No idea, but this is not a SO standard question anyway.
2. Which type of links are these ?
IF you mean live streaming links, there are many types but mostly they are either HLS or RTSP.
HLS links are simple HTTP links that often end with a ".m3u8" postfix. (e.g "http://somewebsite.com/streams/hls_stream_video.m3u8")
RTSP links on the other hand, have a format like this: "rtsp://somewebsite.com/streams/an_rtsp_stream.mp4"
3. Is there any player to play this type of videos ?
Absolutely. You can do so by any means.
I'm not exactly sure by "a player" whether you mean Android API player or third-party player applications. So I'll cover both cases for you and future passengers.
I) Android API: You can do so with the help of a MediaController, a MediaPlayer and a SurafceView. The latter two are also available in a unit entity known as VideoView.
There is a code in the answer below, you can use that. But Be aware of two key points:
I-a) Using MediaPlayer is harder to implement but gives you more detailed control compared to VideoView.
I-b) If you use some code similar to the below answer Never call prepare() for network streams. Always prepareAsync(). And Always call setAudioStreamType() before prepareAsync. Otherwise you will face transient sync issues between Audio and Video when seeking on the progressbar.
II) Player Application: I have done streaming with MXPlayer and it works great.
There are some considerations to take before starting:
What protocol to choose?
Assuming you are targeting Android, I can advice you to narrow your choices down to HLS and RTSP.
You need to study them well before making a decision. But to give you a hint. HLS is preferred when functioning on lower Bandwidths.
There are many other topics like whether to choose UDP/TCP, IP-Multicast/Broadcast and so on...
Want to delve into coding and learn Video Streaming programmatically?
Go and visit this tutorial. This is the most complete zero-to-hero guide in my opinion.
Since SO lacks a thorough post on Video Streaming, maybe I will extend my answer on demand.
Follow this link :
Android Video Streaming
Below code works for me :
public static void getVideoFromHttp(String urlPath) {
try {
// Start the MediaController
MediaController mediacontroller = new MediaController(mContext);
mediacontroller.setAnchorView(mVideoview);
// Get the URL from String VideoURL
Uri mVideo = Uri.parse(urlPath);
mVideoview.setMediaController(mediacontroller);
mVideoview.setVideoURI(mVideo);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
mVideoview.requestFocus();
mVideoview.setOnPreparedListener(new OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mVideoview.start();
}
});
mVideoview.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
}
});
}
Try this:
private void playLive(String path){
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepare();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}