OnRecomputeFinished won't get invoked - android

i'm using a listener for computing the route once it's invoked by code throuter Route.Compute(...), but when i go out of the computed route , the method "OnRecomputeStarted" doesn't fire !
this is my code :
Router.RouteComputeListener mRouteComputeListener = new Router.RouteComputeListener() {
#Override
public void onComputeError(Router router, #Router.RouteComputeError int error) {
}
#Override
public void onProgress(Router router, int progress, int routeIndex) {
// update progress
}
#Override
public void onComputeStarted(Router router) {
}
#SuppressLint("SetTextI18n")
#Override
public void onPrimaryComputeFinished(Router router, com.sygic.sdk.route.RouteInfo routeInfo) {
mapRoutePrimary = new MapRoute(routeInfo, MapRoute.RouteType.Primary); // routeInfo is obtained via onPrimaryComputeFinished() method in RouteComputeListener
mpView.addMapObject(mapRoutePrimary);
}
#Override
public void onAlternativeComputeFinished(Router router, com.sygic.sdk.route.RouteInfo routeInfo) {
mapRouteAlternative = new MapRoute(routeInfo, MapRoute.RouteType.Alternative); // routeInfo is obtained via onAlternativeComputeFinished() method in RouteComputeListener
mpView.addMapObject(mapRouteAlternative);
for (RouteManeuver maneuver : routeInfo.getManeuvers()) {
directionText.setText(maneuver.getType()+" "+directionText.getText());
}
}
#Override
public void onComputeFinished(Router router) {
NavigationManager.getInstance().setRouteForNavigation(mapRoutePrimary.getRouteInfo());
if (mapRouteAlternative!=null)
mapRoutePrimary.getRouteInfo().getBoundingBox().union(mapRouteAlternative.getRouteInfo().getBoundingBox());
Objects.requireNonNull(mpView.getCamera()).setMapRectangleWithMargin(mapRoutePrimary.getRouteInfo().getBoundingBox(),mapAnimation,15,15,15,15);
NavigationManager.getInstance().addOnDirectionListener(new NavigationManager.OnDirectionListener() {
#Override
public void onDirectionInfoChanged(#NonNull DirectionInfo directionInfo) {
final int distance = directionInfo.getDistance();
final int nextDistance = directionInfo.getNextDistance();
final RouteManeuver primaryManeuver = directionInfo.getPrimary();
if (primaryManeuver != null) {
final int type = primaryManeuver.getType();
final String roadName = primaryManeuver.getRoadName();
final String nextRoadName = primaryManeuver.getNextRoadName();
directionText.setText(roadName);
Log.d("directions", "direction of type " + type + " on the road " + roadName + ". Next road is " + nextRoadName);
//Toast.makeText(getApplicationContext(), "direction of type " + type + " on the road " + roadName + ". Next road is " + nextRoadName,Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public void onRecomputeStarted() {
// called when recompute was invoked. Recompute can be invoked after leaving computed route
mpView.removeMapObject(mapRoutePrimary);
}
#Override
public void onRecomputeFinished(com.sygic.sdk.route.RouteInfo routeInfo, int i) {
mpView.removeMapObject(mapRoutePrimary);
mapRoutePrimary = new MapRoute(routeInfo, MapRoute.RouteType.Primary);
mpView.addMapObject(mapRoutePrimary);
}
};

OnRecomputeStarted is listening for Router.recomputeRoute() method.
What you probably need is to listen for NavigationManager.OnRouteChangedListener.
So basicly this is the code:
NavigationManager.getInstance().addOnRouteChangedListener(new NavigationManager.OnRouteChangedListener() {
#Override
public void onRouteChanged(final RouteInfo newRouteInfo) {
mpView.removeMapObject(mapRoutePrimary);
// set newRouteInfo as new route for navigation...
}
});

Related

Android Yandex Mapkit search request by point or by name always return null values,why?

This is my example where I am tapping on the map to get the tapped point coordinates and to send a search request to know more details about that place, for example, city, street. But the response is always null values.
public class MainActivity extends AppCompatActivity implements CameraListener, InputListener, Session.SearchListener {
private ActivityMainBinding binding;
private SearchManager searchManager;
private Session searchSession;
private SearchOptions searchOptions;
private MapObjectCollection mapObjectCollection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapKitFactory.setApiKey("your api key");
MapKitFactory.initialize(this);
searchOptions = new SearchOptions();
searchOptions.setSearchTypes(SearchType.GEO.value);
searchOptions.setGeometry(true);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.mapview.getMap().setNightModeEnabled((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES);
searchManager = SearchFactory.getInstance().createSearchManager(SearchManagerType.COMBINED);
binding.mapview.getMap().addCameraListener(this);
binding.mapview.getMap().addInputListener(this);
mapObjectCollection = binding.mapview.getMap().getMapObjects();
binding.mapview.getMap().move(
new CameraPosition(new Point(55.751574, 37.573856), 11.0f, 0.0f, 0.0f),
new Animation(Animation.Type.SMOOTH, 0),
null);
}
#Override
protected void onStop() {
super.onStop();
binding.mapview.onStop();
MapKitFactory.getInstance().onStop();
}
#Override
protected void onStart() {
super.onStart();
binding.mapview.onStart();
MapKitFactory.getInstance().onStart();
}
public void submitQueryByName(String query) {
searchSession = searchManager.submit(
query,
Geometry.fromPoint(new Point(40.177200, 44.503490)),
searchOptions,
this);
}
public void submitQueryByPoint(Point point) {
searchSession = searchManager.submit(
point,
11,
searchOptions,
this);
}
#Override
public void onCameraPositionChanged(#NonNull Map map, #NonNull CameraPosition cameraPosition, #NonNull CameraUpdateReason cameraUpdateReason, boolean finished) {
Log.e("onCameraPositionChanged"," cameraPosition: "+cameraPosition+" cameraUpdateReason: "+cameraUpdateReason+" finished: "+finished);
}
#Override
public void onMapTap(#NonNull Map map, #NonNull Point point) {
MapObjectCollection mapObjects = binding.mapview.getMap().getMapObjects();
mapObjects.clear();
PlacemarkMapObject placemarkMapObject = mapObjectCollection.addPlacemark(new Point(point.getLatitude(), point.getLongitude()),
ImageProvider.fromResource(this, R.mipmap.marker_flag));
submitQueryByPoint(point);
Log.e("onMapTap", "point lat - lang: " + point.getLatitude() + " : " + point.getLongitude());
}
#Override
public void onMapLongTap(#NonNull Map map, #NonNull Point point) {
Log.e("onMapLongTap","onMapLongTap");
}
#Override
public void onSearchResponse(#NonNull Response response) {
try {
Log.e("Search", "Response: " + response);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
#Override
public void onSearchError(#NonNull Error error) {
String errorMessage = "unknown_error_message";
if (error instanceof RemoteError) {
errorMessage = "remote_error_message";
} else if (error instanceof NetworkError) {
errorMessage = "network_error_message";
}
Log.e("Response error", " error: " + errorMessage);
}
}
In the onMapTap method, I get the tapped point coordinates and send a search request by point
#Override
public void onMapTap(#NonNull Map map, #NonNull Point point) {
MapObjectCollection mapObjects = binding.mapview.getMap().getMapObjects();
mapObjects.clear();
PlacemarkMapObject placemarkMapObject = mapObjectCollection.addPlacemark(new Point(point.getLatitude(), point.getLongitude()),
ImageProvider.fromResource(this, R.mipmap.marker_flag));
submitQueryByPoint(point);
Log.e("onMapTap", "point lat - lang: " + point.getLatitude() + " : " + point.getLongitude());
}
**Response is always null values. What I do wrong?
This is a GitHub whole project for this example https://github.com/davmehrabyan/YandexMapSearch **

How to provide two Integer values and emit one String

I am learning RxAndroid api, so I created an example where the input is two integers and the output should be a string containing these integers. for example,
for 1 and two the output should be "1,2" and so on.
in the below code is my attempts to achieve what I am planning to do, but I need guiding and help please.
code:
public class MainActivity extends AppCompatActivity {
private final static String TAG = MainActivity.class.getSimpleName();
private EditText mEditTextValue1 = null;
private EditText mEditTextValue2 = null;
private Button mButtonStartAsyncTask = null;
private rx.Observable<Integer> mAsyncObservable = null;
private TextView mTextViewProcessedValue = null;
Subscriber<String> mAsyncSubscriber = new Subscriber<String>() {
#Override
public void onCompleted() {
Log.w(TAG, "onCompleted(mAsyncSubscriber)");
}
#Override
public void onError(Throwable e) {
Log.w(TAG, "onError(mAsyncSubscriber)");
}
#Override
public void onNext(String next) {
Log.w(TAG, "onNext(mAsyncSubscriber)");
mTextViewProcessedValue.setText();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
mEditTextValue1 = (EditText) findViewById(R.id.editTextValue1);
mEditTextValue2 = (EditText) findViewById(R.id.editTextValue2);
mButtonStartAsyncTask = (Button) findViewById(R.id.buttonStartAsyncTask);
mButtonStartAsyncTask.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Integer value1 = Integer.valueOf(mEditTextValue1.getText().toString());
Integer value2 = Integer.valueOf(mEditTextValue2.getText().toString());
mAsyncObservable = rx.Observable.just(value1, value2)
.delay(3, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.doOnNext(items-> {
mTextViewProcessedValue = (TextView) findViewById(R.id.textViewProcessedValue);
return value1 + ", " + value2;
})
.doOnCompleted(new Action0() {
#Override
public void call() {
Log.w(TAG, "doOnCompleted");
}
})
//.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe((Action1<? super Integer>) mAsyncSubscriber);
}
});
}
}
The operator you want to use really depends on how many numbers you will have, how many products you want, and what you want to do with the final answer. For this example, we'll use scan(...)
apply a function to each item emitted by an Observable, sequentially, and emit each successive value
Observable.just(value1, value2)
.delay(3, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.scan("", (string, integer) -> string + "," + integer)
The above will emit once: "{value1},{value2}".
If you add a third value, it will emit twice : "{value1},{value2}" and "{value1},{value2},{value3}"
i'm new with RxJava too ... this might be what you want
io.reactivex.Observable.range(1, 100).subscribe(new DisposableObserver<Integer>() {
List<Integer> list = new ArrayList<>(2);
#Override
public void onNext(Integer integer) {
list.add(integer);
if (list.size() % 2 == 0) {
Log.i(TAG, "onNext: couple int :" + list.get(0) + " ," + list.get(1));
list.clear();
}
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
if you want to emit two values together you may emit a array or list or Pojo.
using zip operator example:
io.reactivex.Observable<Integer> s1 = io.reactivex.Observable.range(1, 100);
io.reactivex.Observable<Integer> s2 = io.reactivex.Observable.range(-100, 100);
io.reactivex.Observable.zip(s1, s2, new BiFunction<Integer, Integer, String >() {
#Override
public String apply(Integer i1, Integer i2) throws Exception {
return i1 + " ," + i2;
}})
.subscribe(System.out::println);
Looking on code what you trying achieve is reading from 2 fields on button click and emit them to observable, is it correct?
Please check this project to replace listener with rxjava bindings:
https://github.com/JakeWharton/RxBinding. Then code would be something like this:
RxView.clicks(button)
.map(event -> {
Integer value1 = Integer.valueOf(mEditTextValue1.getText().toString());
Integer value2 = Integer.valueOf(mEditTextValue2.getText().toString());
return value1 + "," + value2;
})
.subscribe(combinedIntegers ->
mTextViewProcessedValue.setText(combinedIntegers));

Android: Get current playing media on Chromecast?

I'm working on an app that controls the Chromecast and whatever's playing on it.
I don't want a sender app, I don't want to register anything to get an api key, none of that stuff.
I'm using so far MediaRouter to control the volume and to see if it's connected to anything.
But I want something like the Google Cast app:
Which knows what's playing and (or at least) the playback state.
Ideally I wouldn't want to use google play services, but if it's the only way, c'est la vie.
I finally figured it out. I had to use the google play services and the google cast sdk v2 but without registering the application.
Libraries included in the project:
compile 'com.android.support:mediarouter-v7:24.0.0'
compile 'com.google.android.gms:play-services-cast-framework:9.2.0'
Beware that in the code below onCreate() and onDestroy() aren't methods in an Activity, Fragment or Service, so don't copy/paste the code and expect it works. The code in those methods must pe copy/pasted in your own methods.
Here are the steps of what's happening:
You select a route either via the cast button either by calling getActiveMediaRoute() which checks for which Chromecast is active (it won't work if nobody is connected to the Chromecast). Override the method or getActiveChromecastRoute() to select based on your preferences
When onRouteSelected() is called a new Cast GoogleApiClient is instanced with options for the selected chromecast
When onApplicationMetadataChanged() is called the code will connect to the current application running on the Chromecast
After the application is successfully connected a new RemoteMediaPlayer is instanced and the MediaStatus is requested
You should get a callback in onStatusUpdated() and after that you can call mRemoteMediaPlayer.getMediaStatus() and it will contain the data about what's being played on the Chromecast.
public static final String CHROMECAST_SIGNATURE = "cast.media.CastMediaRouteProviderService";
private final MediaRouteSelector mSelector;
private final MediaRouter mMediaRouter;
private CastDevice mSelectedDevice;
private Cast.Listener mCastClientListener;
private RemoteMediaPlayer mRemoteMediaPlayer;
#Override
public void onCreate() {
mMediaRouter = MediaRouter.getInstance(context);
mSelector = new MediaRouteSelector.Builder()
// These are the framework-supported intents
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
mMediaRouter.addCallback(mSelector, mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
}
#Override
public void onDestroy() {
mMediaRouter.removeCallback(mMediaRouterCallback);
}
#UiThread
private boolean isChromecastActive() {
return getActiveChromecastRoute() != null;
}
#UiThread
private Boolean isChromecastPlaying() {
if (mRemoteMediaPlayer == null || mRemoteMediaPlayer.getMediaStatus() == null) {
return null;
}
// Here you can get the playback status and the metadata for what's playing
// But only after the onStatusUpdated() method is called in the mRemoteMediaPlayer callback
int state = mRemoteMediaPlayer.getMediaStatus().getPlayerState();
return (state == MediaStatus.PLAYER_STATE_BUFFERING || state == MediaStatus.PLAYER_STATE_PLAYING);
}
#UiThread
private MediaRouter.RouteInfo getActiveChromecastRoute() {
for (MediaRouter.RouteInfo route : mMediaRouter.getRoutes()) {
if (isCastDevice(route)) {
if (route.getConnectionState() == MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTED) {
return route;
}
}
}
return null;
}
private int getMediaRouteVolume(#NonNull MediaRouter.RouteInfo route) {
return route.getVolume();
}
private void setMediaRouteVolume(#NonNull MediaRouter.RouteInfo route, int volume) {
route.requestSetVolume(volume);
}
private int getMediaRouteMaxVolume(#NonNull MediaRouter.RouteInfo route) {
return route.getVolumeMax();
}
#UiThread
private MediaRouter.RouteInfo getActiveMediaRoute() {
if (isChromecastActive()) {
MediaRouter.RouteInfo route = getActiveChromecastRoute();
if (route != null) {
if (!route.isSelected()) {
mMediaRouter.selectRoute(route);
}
}
else if (mSelectedDevice != null) {
mSelectedDevice = null;
}
return route;
}
return null;
}
private boolean isCastDevice(MediaRouter.RouteInfo routeInfo) {
return routeInfo.getId().contains(CHROMECAST_SIGNATURE);
}
private MediaRouter.Callback mMediaRouterCallback = new MediaRouter.Callback() {
#Override
public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo route) {
if (isCastDevice(route)) {
Log.i("MediaRouter", "Chromecast found: " + route);
}
}
#Override
public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) {
if (isCastDevice(route)) {
Log.i("MediaRouter", "Chromecast changed: " + route);
}
}
#Override
public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
if (mSelectedDevice == null && isCastDevice(route)) {
Log.i("MediaRouter", "Chromecast selected: " + route);
mSelectedDevice = CastDevice.getFromBundle(route.getExtras());
mCastClientListener = new Cast.Listener() {
#Override
public void onApplicationStatusChanged() {
Log.i("MediaRouter", "Cast.Listener.onApplicationStatusChanged()");
}
#Override
public void onApplicationMetadataChanged(ApplicationMetadata applicationMetadata) {
Log.i("MediaRouter", "Cast.Listener.onApplicationMetadataChanged(" + applicationMetadata + ")");
if (applicationMetadata != null) {
LaunchOptions launchOptions = new LaunchOptions.Builder().setRelaunchIfRunning(false).build();
Cast.CastApi.launchApplication(mApiClient, applicationMetadata.getApplicationId(), launchOptions).setResultCallback(new ResultCallback<Cast.ApplicationConnectionResult>() {
#Override
public void onResult(#NonNull Cast.ApplicationConnectionResult applicationConnectionResult) {
Log.i("MediaRouter", "Cast.CastApi.joinApplication.onResult() " + applicationConnectionResult.getSessionId());
mRemoteMediaPlayer = new RemoteMediaPlayer();
mRemoteMediaPlayer.setOnStatusUpdatedListener( new RemoteMediaPlayer.OnStatusUpdatedListener() {
#Override
public void onStatusUpdated() {
MediaStatus mediaStatus = mRemoteMediaPlayer.getMediaStatus();
Log.i("MediaRouter", "Remote media player status " + mediaStatus.getPlayerState());
// TODO: you can call isChromecastPlaying() now
}
});
try {
Cast.CastApi.setMessageReceivedCallbacks(mApiClient, mRemoteMediaPlayer.getNamespace(), mRemoteMediaPlayer);
} catch(IOException e) {
Log.e("MediaRouter", "Exception while creating media channel ", e );
} catch(NullPointerException e) {
Log.e("MediaRouter", "Something wasn't reinitialized for reconnectChannels", e);
}
mRemoteMediaPlayer.requestStatus(mApiClient).setResultCallback(new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(#NonNull RemoteMediaPlayer.MediaChannelResult mediaChannelResult) {
Log.i("MediaRouter", "requestStatus() " + mediaChannelResult);
}
});
try {
Cast.CastApi.requestStatus(mApiClient);
} catch (IOException e) {
Log.e("MediaRouter", "Couldn't request status", e);
}
}
});
}
}
#Override
public void onApplicationDisconnected(int i) {
Log.i("MediaRouter", "Cast.Listener.onApplicationDisconnected(" + i + ")");
}
#Override
public void onActiveInputStateChanged(int i) {
Log.i("MediaRouter", "Cast.Listener.onActiveInputStateChanged(" + i + ")");
}
#Override
public void onStandbyStateChanged(int i) {
Log.i("MediaRouter", "Cast.Listener.onStandbyStateChanged(" + i + ")");
}
#Override
public void onVolumeChanged() {
Log.i("MediaRouter", "Cast.Listener.onVolumeChanged()");
}
};
Cast.CastOptions.Builder apiOptionsBuilder = new Cast.CastOptions.Builder(mSelectedDevice, mCastClientListener);
mApiClient = new GoogleApiClient.Builder(getContext())
.addApi( Cast.API, apiOptionsBuilder.build() )
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i("MediaRouter", "GoogleApiClient.onConnected()");
Log.i("MediaRouter", "Bundle " + bundle);
}
#Override
public void onConnectionSuspended(int i) {
Log.i("MediaRouter", "GoogleApiClient.onConnectionSuspended(" + i + ")");
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i("MediaRouter", "GoogleApiClient.onConnectionFailed()");
}
})
.build();
mApiClient.connect();
}
else {
mSelectedDevice = null;
mRemoteMediaPlayer = null;
}
}
#Override
public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo route) {
if (isCastDevice(route)) {
if (mSelectedDevice != null && mSelectedDevice.isSameDevice(CastDevice.getFromBundle(route.getExtras()))) {
mSelectedDevice = null;
}
Log.i("MediaRouter", "Chromecast lost: " + route);
}
}
};

Parse uploaded values are turning to 0 when I log out of current user and then log back in

This is a simple settings page for an app. When I click the applyButton, it will take the current seekerbar progress value and upload it to the cloud. It works completely fine as when I leave the settings page and then return, the values are saved. However when I log out of the current user and then log back in and go to the settings page, the value pulled from the cloud is 0 for some reason.
Near the bottom of my code I have a method called userIsLoggedIn(). I have log statements as follows:
Log.d(TAG, "got user settings from database");
Log.d(TAG, "desired work time: " + workFromDatabase);
Log.d(TAG, "desired rest time " + restFromDatabase);
Perhaps I'm unaware of something as my boolean value which I'm retrieving from the cloud is perfectly fine. It's only the int value that is giving me this problem.
public class SettingsScreen extends AppCompatActivity {
public static final String TAG = SettingsScreen.class.getSimpleName();
private static final String ACCESSEDSETTINGS = "accessed_settings";
#Bind(R.id.workText)
TextView workText;
#Bind(R.id.restText)
TextView restText;
#Bind(R.id.workSeekBar)
SeekBar workBar;
#Bind(R.id.restSeekBar)
SeekBar restBar;
#Bind(R.id.applyButton)
Button applyButton;
public static final int MAX_WORK = 60;
public static final int MIN_WORK = 5;
public static final int MAX_REST = 60;
public static final int MIN_REST = 1;
public static final String WORK = "work"; //these two will be the data uploaded to the database
public static final String REST = "rest";
public static final String LOCALWORK = "localwork"; //these two will be data sent back to main activity. only locally saved
public static final String LOCALREST = "localrest";
int workFromDatabase;
int restFromDatabase;
Boolean databaseHasValue = false;
private int mDesiredWorkTime;
private int mDesiredRestTime;
private ParseUser mUser;
Boolean isLoggedIn;
Boolean registeredUserAccessedSettings = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings_screen);
ButterKnife.bind(this);
Intent intent = getIntent();
isLoggedIn = intent.getBooleanExtra("currentUser", false);
if (isLoggedIn) {
userIsLoggedIn();
Log.d(TAG, "Database has value? " + databaseHasValue);
} else {
workBar.setMax(MAX_WORK - MIN_WORK);
workBar.setProgress(25 - MIN_WORK);
workBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mDesiredWorkTime = MIN_WORK + progress;
workText.setText("Current: " + mDesiredWorkTime + " minutes");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
restBar.setMax(MAX_REST - MIN_REST);
restBar.setProgress(5 - MIN_REST);
restBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mDesiredRestTime = MIN_REST + progress;
restText.setText("Current: " + mDesiredRestTime + " minutes");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
applyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isLoggedIn) {
mUser.put(WORK, mDesiredWorkTime);
mUser.put(REST, mDesiredRestTime);
mUser.put(ACCESSEDSETTINGS, true); //when user clicks apply, ACCESSEDSETTINGS will be true and so the if statement in the method below wont run
Log.d(TAG, "putting desired user settings into database");
Log.d(TAG, "desired work time: " + mDesiredWorkTime);
Log.d(TAG, "desired rest time " + mDesiredRestTime);
}
Intent intent = new Intent(SettingsScreen.this, MainActivity.class);
intent.putExtra(LOCALWORK, mDesiredWorkTime);
intent.putExtra(LOCALREST, mDesiredRestTime);
startActivity(intent);
}
});
}
public void userIsLoggedIn() {
if (isLoggedIn) {
mUser = ParseUser.getCurrentUser();
registeredUserAccessedSettings = mUser.getBoolean(ACCESSEDSETTINGS);
Log.d(TAG, "Has user accessed settings before? " + registeredUserAccessedSettings);
if (!registeredUserAccessedSettings) { //this code will run first time user accesses settings with parse
workFromDatabase = 25;
restFromDatabase = 5;
Log.d(TAG, "launched settings with account for first time");
} else {
workFromDatabase = mUser.getInt(WORK);
restFromDatabase = mUser.getInt(REST);
workText.setText("Current: " + workFromDatabase + " minutes");
restText.setText("Current: " + restFromDatabase + " minutes");
databaseHasValue = true;
Log.d(TAG, "got user settings from database");
Log.d(TAG, "desired work time: " + workFromDatabase);
Log.d(TAG, "desired rest time " + restFromDatabase);
}
workBar.setMax(MAX_WORK - MIN_WORK);
workBar.setProgress(workFromDatabase - MIN_WORK);
workBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mDesiredWorkTime = MIN_WORK + progress;
workText.setText("Current: " + mDesiredWorkTime + " minutes");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
restBar.setMax(MAX_REST - MIN_REST);
restBar.setProgress(restFromDatabase - MIN_REST);
restBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mDesiredRestTime = MIN_REST + progress;
restText.setText("Current: " + mDesiredRestTime + " minutes");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
}
The issue is really simple. You're not "uploading it to the cloud", you're just setting those values on your local ParseUser object.
For example:
mUser.put(WORK, mDesiredWorkTime);
is NOT saving anything to the remote database. It's just setting the field indicated by the WORK key with the value stored in mDesiredWorkTime in your local ParseUser object.
To fix your issue change this:
mUser.put(WORK, mDesiredWorkTime);
mUser.put(REST, mDesiredRestTime);
mUser.put(ACCESSEDSETTINGS, true);
to this:
mUser.put(WORK, mDesiredWorkTime);
mUser.put(REST, mDesiredRestTime);
mUser.put(ACCESSEDSETTINGS, true);
mUser.saveInBackground(); // <----------------------- THIS SAVES YOUR USER TO THE DATABASE
(instead of saveInBackground() you can also use saveInBackground(SaveCallback callback) or save(), depending on your actual needs...)

How to send composing / is typing (Chat states) event in Multiuser chat / Group chat & One to One chat in xmpp android?

I want send composing event in Group (Multiuser) chat in xmpp, I am using asmack library, I have done same functionality with One to One chat.
I am using below code:
mMessageEventManager = new MessageEventManager(XMPPConnectApplication.getInstance().getXmppConnection());
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
#Override
public void offlineNotification(String arg0, String arg1) {
}
#Override
public void displayedNotification(String arg0, String arg1) {
}
#Override
public void deliveredNotification(String arg0, String arg1) {
}
#Override
public void composingNotification(String from, String to) {
Log.e("Receiver-composingNotification",from + " is started typing......"+to);
}
#Override
public void cancelledNotification(String from, String to) {
Log.e("Receiver-cancelledNotification",from + " is stopped typing......"+to);
}
});
Please let me know if you have any idea for the same.
Any help will be appreciated.
Yes, I have idea about it and I have done just before 1 week.
I have used MessageEventManager to manage Chat States.
private MessageEventManager mMessageEventManager;
Add this method for Chat State Receiving Listener:
private void chatStateRecognizer(){
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
mMessageEventManager = new MessageEventManager(mXmppConnection);
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
#Override
public void offlineNotification(String arg0, String arg1) {
}
#Override
public void displayedNotification(String arg0, String arg1) {
}
#Override
public void deliveredNotification(String from, String arg1) {
}
#Override
public void composingNotification(String from, String to) {
Log.i("Receiver:Compose state",from + " is started typing......"+to);
}
#Override
public void cancelledNotification(String from, String to) {
Log.i("Receiver:Stop state",from + " is stopped typing......"+to);
}
});
}
});
thread.start();
}
Create one Model class name with GroupInfoModel.java:
public class GroupInfoModel implements Comparable<GroupInfoModel>, Serializable{
private static final long serialVersionUID = 1L;
private String memberId = "", memberName = "";
private boolean isAdmin;
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean isAdmin) {
this.isAdmin = isAdmin;
}
#Override
public int compareTo(GroupInfoModel another) {
return getMemberName().compareTo(another.getMemberName());
}
}
Now take ArrayList of GroupInfoModel.java class:
private ArrayList<GroupInfoModel> groupDetailsList = new ArrayList<GroupInfoModel>();
private boolean isComposingStarted;
on onCreate() of Activity / Fragment:
groupDetailsList.clear();
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(mXmppConnection);
DiscoverItems items = discoManager.discoverItems(mRoomId);
for (Iterator<Item> it = items.getItems(); it.hasNext();) {
DiscoverItems.Item item = (DiscoverItems.Item) it.next();
String occupant = item.getEntityID();
occupant = occupant.split("/")[1];
GroupInfoModel groupInfoModel = new GroupInfoModel();
groupInfoModel.setAdmin(false);
groupInfoModel.setMemberId(occupant+"#"+mServiceNameHere);
groupInfoModel.setMemberName(occupant);
groupDetailsList.add(groupInfoModel);
}
Now add TextWatcher on your EditText of Compose Message (Chat view) screen:
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString().length()==1&&!isComposingStarted){
isComposingStarted = true;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendComposingNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendComposingNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}else if(s.toString().length()==0){
isComposingStarted = false;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendCancelledNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendCancelledNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}
}
I strongly recommended that use above code in Application class, you can modify methods as your requirements.
Done.
// send multi user chat typing status
public static void sendMUCTypingStatus(ChatState state)
{
// check if you are connected to group
if(multiUserChat != null)
{
try{
// create packet
Message statusPacket = new Message();
// set body to null
statusPacket.setBody(null);
// set packet type to group chat
statusPacket.setType(Message.Type.groupchat);
// set subject to null
statusPacket.setSubject(null);
// set to the group name
statusPacket.setTo(multiUserChat.getRoom());
// set from my current jis example : me#domain.com
statusPacket.setFrom(new MyPrefrence(XmppBase.context).getUsername());
// get the chat state extension and pass our state
ChatStateExtension extension = new ChatStateExtension(state);
// add the extention to our packet
statusPacket.addExtension(extension);
// get the connection and send the packet
Utils.getConnection().sendStanza(statusPacket);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
Usage :
sendMucTypingStatus(ChatState.composing);
watch this : Quick overview of using
With RxJava and Jake Wharton's RxBinding, it's quite simple to do:
RxTextView.afterTextChangeEvents(editText)
.observeOn(Schedulers.io())
.skip(1)
.map({ input ->
// FIRE ChatState.composing EVENT HERE
input // just returning the argument here
})
.debounce(2, TimeUnit.SECONDS)
.observeOn(Schedulers.io())
.subscribe {
// FIRE ChatState.active EVENT HERE
}
Remember that we will have to write code to catch these events via smack stanzaListener and display it on the UI accordingly!
Code is written in Kotlin, but it is fairly straight forward.

Categories

Resources