I am using the above mention method like
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
mFusedLocationClient.getCurrentLocation(LocationRequest.PRIORITY_HIGH_ACCURACY,null).addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location != null) {
userCurrentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
getAddress(userCurrentLatLng);
}
}
});
in the cancellation token parameter i am passing null so is this going make any difference or i have to pass cancellation token in here. still i am getting the current location.
please suggest do i have to pass the parameter or null will be ok.
You can do like this,i have tried its working fine
`mFusedLocationClient.getCurrentLocation(
PRIORITY_HIGH_ACCURACY,
object : CancellationToken() {
override fun isCancellationRequested(): Boolean {
return false
}
override fun onCanceledRequested(onTokenCanceledListener: OnTokenCanceledListener): CancellationToken {
return this
}
}).addOnSuccessListener { location: Location ->
//handle your location here
}`
Related
I'm pretty new with concurency and I'v hit the wall several times already.
Code pretty much describes everything, but just to clarify: user press the button, application send query to db and in the meantime statusLabel is set to:
Veryfing.
200ms
Veryfing..
200ms
Veryfing...
200ms
Result of query
I'v managed to achieve that, but now, I need to use result of query in another class (if it succeed, another window is opened), but It never does. I came to conclusion that it just checks the result before Task is finished so result is always false, I have no idea how to work around this, so another class checks condition once Task is done.
First, my Authorization class
public class Authorization {
private static String query = "";
private static boolean isValid;
private static Task<Void> task;
public static void verifyLogin(String username, String password) throws SQLException{
Status.get().unbind();
isValid = false;
task = new Task<Void>() {
#Override
protected Void call() throws SQLException {
while(!isCancelled()) {
try {
updateMessage("Weryfikacja.");
Thread.sleep(200);
updateMessage("Weryfikacja..");
Thread.sleep(200);
updateMessage("Weryfikacja...");
Thread.sleep(200);
if(username.equals("") || password.equals("")) {
task.cancel();
updateMessage("Pola nie mogą być puste");
} else {
query = "SELECT login FROM users WHERE login = ?";
Query.execute(query, username);
if(!Query.resultSet.next()) {
task.cancel();
updateMessage("Nie ma takiego użytkownika");
} else {
query = "SELECT password FROM users WHERE login = ?";
Query.execute(query, username);
if(Query.resultSet.next()) {
String passwordValue = Query.resultSet.getString(1);
if(!password.equals(passwordValue)) {
task.cancel();
updateMessage("Podane hasło jest błędne");
} else {
task.cancel();
updateMessage("");
isValid = true;
}
}
}
}
} catch(InterruptedException e) {
if(isCancelled()) {
break;
}
}
}
return null;
}
};
Status.get().bind(task.messageProperty());
new Thread(task).start();
}
public static boolean isValid() {
return isValid;
}
}
called from another class
private void login() {
if( SqlConnection.isConnected()) {
try{
Authorization.verifyLogin(String.valueOf(loginInput.getText()), String.valueOf(passwordInput.getText()));
if(Authorization.isValid()) {
//should go to next menu
//but never does
}
} catch (SQLException e) {
e.printStackTrace();
Debug.log(e.toString());
}
}
}
edit#
Sorry for polish in updateMessage().
Your verifyLogin() method simply starts the verification process in another thread, and then exits immediately. The isValid flag will not be changed until that thread completes, which happens quite a lot later. If you want to do the verification process and then do something else, it doesn't really make sense to manage the threads in verifyLogin().
I don't really understand a lot of what your code is supposed to be doing; you have a while(...) loop, which as far as I can tell can only be executed once (so is redundant). You also seem to execute two SQL queries which are essentially the same. (The first checks to see if there is a row with a certain condition, then if there is, the second retrieves that row. Why not just retrieve the row and check if it is there?)
I would refactor this so that the validateLogin() method doesn't handle the threading at all, and just returns the result of the validation (e.g. a status string, but maybe something else would be appropriate).
/**
* #return An empty string if the login is valid, or an error message otherwise
*/
public static String verifyLogin(String username, String password) throws SQLException{
isValid = false ;
if(username.equals("") || password.equals("")) {
return "Pola nie mogą być puste";
}
query = "SELECT login, password FROM users WHERE login = ?";
Query.execute(query, username);
if(!Query.resultSet.next()) {
return "Nie ma takiego użytkownika";
}
String passwordValue = Query.resultSet.getString(2);
if(!password.equals(passwordValue)) {
return "Podane hasło jest błędne" ;
}
isValid = true;
return "" ;
}
Now I would manage the threads from the login() method. That way you can use the task's onSucceeded handler to execute code when the task completes:
private void login() {
if( SqlConnection.isConnected()) {
Task<String> verifyTask = new Task<String>() {
#Override
protected String call() throws SQLException {
return Authorization.verifyLogin(loginInput.getText(), passwordInput.getText());
}
};
// probably better to use a progress indicator or similar here, but:
Animation animation = new Timeline(
new KeyFrame(Duration.ZERO, e -> Status.get().set("Weryfikacja.")),
new KeyFrame(Duration.millis(200), e -> Status.get().set("Weryfikacja..")),
new KeyFrame(Duration.millis(400), e -> Status.get().set("Weryfikacja...")),
new KeyFrame(Duration.millis(600)));
animation.setCycleCount(Animation.INDEFINITE);
verifyTask.setOnSucceeded(event -> {
animation.stop();
Status.get().set(verifyTask.getValue());
if(Authorization.isValid()) { // or if (verifyTask.getValue().isEmpty())
// go to next menu
}
});
verifyTask.setOnFailed(event -> {
animation.stop();
verifyTask.getException().printStackTrace();
Debug.log(verifyTask.getException().toString());
}
animation.play();
new Thread(verifyTask()).start();
}
}
I'm writing a coded ui package extension, and have it hooked up like this:
public override object GetService(Type serviceType)
{
if (!_initialized)
{
_initialized = true;
UITestClass.Saving += OnUiTestSave;
}
return null;
}
Then inside that method:
private void OnUiTestSave(object sender, UITestEventArgs e)
{
if (e.UITest != null && e.UITest.Maps != null && e.UITest.Maps.Count == 1)
{
foreach (TopLevelElement topLevelElement in e.UITest.Maps[0].TopLevelWindows)
{
LoopThroughAll(topLevelElement, topLevelElement.Id);
}
}
}
Notice in the above code e.UITest.Maps[0] actually exists and is totally valid, but I need to get the filename. The property exists but it's always null.
Is this a Microsoft bug?
I have an extremely odd error and wondered if anyone knew the reason for this.
When I create a new DataObject and TableController called Content and ContentController respectively, it doesn't register the tablecontroller and the help documentation it automatically generates has lost its styling.
I can't connect to the controller at all but all other controllers work as expected.
If I just rename it to DataController and that's just the name of the controller, not the dataobject everything works perfectly.
Is ContentController a reserved word of some kind or is this just specifically happening on my machine?
public class DataController : TableController<Content>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileContext context = new MobileContext();
DomainManager = new EntityDomainManager<Content>(context, Request, Services);
}
// GET tables/Content
public IQueryable<Content> GetAllContent()
{
return Query();
}
// GET tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Content> GetContent(string id)
{
return Lookup(id);
}
// PATCH tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Content> PatchContent(string id, Delta<Content> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<IHttpActionResult> PostContent(Content item)
{
Content current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/Content/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteContent(string id)
{
return DeleteAsync(id);
}
}
An MVC project will create an application directory called Content. This will override your route mapping to the ContentController.
You can get around this if desired through changing RouteMaps and other trickery although probably the simpliest answer is to change the name of the controller...
In my MVC 2 project, I originally used Ninject 2 and wrote this version of the NinjectControllerFactory:
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel kernel = new StandardKernel(new HandiGamerServices());
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
{
return base.GetControllerInstance(requestContext, controllerType);
// return null;
}
}
catch (HttpException ex)
{
if (ex.GetHttpCode() == 404)
{
IController errorController = kernel.Get<ErrorController>();
((ErrorController)errorController).InvokeHttp404(requestContext.HttpContext);
return errorController;
}
else
{
throw ex;
}
}
return (IController)kernel.Get(controllerType);
}
Of most importance is the retrieval of my ErrorController, which allows me to gracefully handle a multitude of HTTP errors.
The problem is that I upgraded to the MVC 2 extension via Nuget, so a NinjectControllerFactory is already provided. Would it be possible to use my own override of GetControllerInstance? If so, how?
I do exactly this, and for precisely the same reason. In Global.asax.cs, I add this to my OnApplicationStarted override (declared virtual in NinjectHttpApplication):
ControllerBuilder.Current.SetControllerFactory(
new MyControllerFactory(ControllerBuilder.Current.GetControllerFactory()));
This means you're creating your own controller factory, but providing it with the default implementation to do the heavy lifting.
Then define your controller factory like so:
public class MyControllerFactory : IControllerFactory
{
private IControllerFactory defaultFactory;
public MyControllerFactory(IControllerFactory defaultFactory)
{
this.defaultFactory = defaultFactory;
}
public IController CreateController(RequestContext requestContext, string controllerName)
{
try
{
var controller = defaultFactory.CreateController(requestContext, controllerName);
return controller;
}
catch (HttpException e)
{
// Pasted in your exception handling code here:
if (ex.GetHttpCode() == 404)
{
IController errorController = kernel.Get<ErrorController>();
((ErrorController)errorController).InvokeHttp404(requestContext.HttpContext);
return errorController;
}
else
{
throw ex;
}
}
}
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
return defaultFactory.GetControllerSessionBehavior(requestContext, controllerName);
}
public void ReleaseController(IController controller)
{
defaultFactory.ReleaseController(controller);
}
}
As you can see, we're just using the default (Ninject) controller factory for most purposes unless it can't find the page. For obtaining the error controller, you can either pass in the kernel as you were already doing, or just call defaultFactory.CreateController using the error controller name.
I'm trying to get windows workflows working, and I've become a little stumped.
I've gotten a single workflow working, but now I am trying to do something a little more complex: start a workflow, where each activity itself contains a workflow. (Picture something like the main program starts the activities "Input, logic, and output", and then each of those have additional activities like "prompt user, get input, etc.")
I've had it working fine, with the example from here (http://msdn.microsoft.com/en-us/magazine/gg535667.aspx), when I am not passing any parameters from the main program to the activites. My question is, how exactly does the 'Variables' and 'metadata.SetVariablesCollection' work in the NativeActivity, and how to I get the parameters to the low level activities?
This is what I am currently trying:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Collections.ObjectModel;
using System.Activities.Statements;
namespace Project1
{
internal class MainProgram
{
internal static void Main(string[] args)
{
try
{
var act = new SimpleSequence();
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Activities.Add((Activity)(new WriteSomeText()));
act.Variables.Add(new Variable<string> ("stringArg", "TEXT"));
WorkflowInvoker.Invoke(act);
}
catch (Exception ex)
{
System.Console.WriteLine("EXCEPTION: {0}", ex);
}
}
public class WriteSomeText : CodeActivity
{
[RequiredArgument]
public InArgument<string> stringArg { get; set; }
protected override void Execute(CodeActivityContext context)
{
string output = context.GetValue(stringArg);
System.Console.WriteLine(output);
}
}
public class SimpleSequence : NativeActivity
{
Collection<Activity> activities;
Collection<Variable> variables;
Variable<int> current = new Variable<int> { Default = 0 };
public Collection<Activity> Activities
{
get
{
if (this.activities == null)
this.activities = new Collection<Activity>();
return this.activities;
}
set
{
this.activities = value;
}
}
public Collection<Variable> Variables
{
get
{
if (this.variables == null)
this.variables = new Collection<Variable>();
return this.variables;
}
set
{
this.variables = value;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.SetChildrenCollection(this.activities);
metadata.SetVariablesCollection(this.variables);
metadata.AddImplementationVariable(this.current);
}
protected override void Execute(NativeActivityContext context)
{
if (this.Activities.Count > 0)
context.ScheduleActivity(this.Activities[0], onChildComplete);
}
void onChildComplete(NativeActivityContext context, ActivityInstance completed)
{
int currentExecutingActivity = this.current.Get(context);
int next = currentExecutingActivity + 1;
if (next < this.Activities.Count)
{
context.ScheduleActivity(this.Activities[next], this.onChildComplete);
this.current.Set(context, next);
}
}
}
}
}
This ends up throwing the following exception:
EXCEPTION: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree:
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
'WriteSomeText': Value for a required activity argument 'stringArg' was not supplied.
at System.Activities.Validation.ActivityValidationServices.ThrowIfViolationsExist(IList`1 validationErrors)
at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.Hosting.WorkflowInstance.RegisterExtensionManager(WorkflowInstanceExtensionManager extensionManager)
at System.Activities.WorkflowApplication.EnsureInitialized()
at System.Activities.WorkflowApplication.RunInstance(WorkflowApplication instance)
at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow)
at Project1.MainProgram.Main(String[] args) in c:\users\user\documents\visual studio 2010\Projects\ModelingProject1\Project1\MainProgram.cs:line 25
I know, I only pass 1 parameter, but the exception still says that I am missing 3 parameters. I am missing something as to how to do this properly.
You're correctly declaring stringArg as an InArgument but you're not passing any value to it when calling it inside SimpleSequence.
You can pass something using the constructor, while constructing the all activity itself, like this:
public class WriteSomeText : CodeActivity
{
[RequiredArgument]
public InArgument<string> stringArg { get; set; }
public WriteSomeText(string stringArg)
{
this.stringArg = stringArg;
}
protected override void Execute(CodeActivityContext context
{
string output = context.GetValue(stringArg);
System.Console.WriteLine(output);
}
}
// Calling the activity like this:
internal static void Main(string[] args)
{
var act = new SimpleSequence()
{
Activities =
{
new WriteSomeText("hello"),
new WriteSomeText("world"),
new WriteSomeText("!")
}
};
WorkflowInvoker.Invoke(act);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Also notice that is a best practice to use the constructor to initialize collections:
public SimpleSequence()
{
activities = new Collection<Activity>();
variables = new Collection<Variable>();
}
This way is even more intuitive to initialize the activity:
var act = new SimpleSequence()
{
Activities =
{
new WriteSomeText("hello"),
new WriteSomeText("world"),
new WriteSomeText("!")
},
Variables =
{
new Variable<int>("myNewIntVar", 10),
// ....
}
};
EDIT:
There are a couple of other ways to approach the problem. This is your best friend while starting in the WF4 world.
Check WF\Basic\CustomActivities\Code-Bodied for a little push with this particular case.