I've succeeded to add a Marker on Google Maps by using the public void onMapClick(LatLng point).
I stored the value of " point " into a private LatLng mLatLngHOME = point; ( which will be used for the method initFlightController() to set Home location).
private void initFlightController() {
if (isFlightControllerSupported()) {
mFlightController = ((Aircraft) DJISDKManager.getInstance().getProduct()).getFlightController();
mFlightController.setStateCallback(new FlightControllerState.Callback() {
#Override
public void onUpdate(FlightControllerState djiFlightControllerCurrentState) {
djiFlightControllerCurrentState.setHomeLocation(new LocationCoordinate2D(mLatLngHOME.latitude, mLatLngHOME.longitude));
}
});
}
}
private boolean isFlightControllerSupported() {
return DJISDKManager.getInstance().getProduct() != null &&
DJISDKManager.getInstance().getProduct() instanceof Aircraft &&
((Aircraft) DJISDKManager.getInstance().getProduct()).getFlightController() != null;
}
Using a DJI Demo Application (DJIDemoApplication.java & MApplication.java), I created a Broadcast Receiver in the MainActivity.java.
In the Broadcast, I call a method updateFlightController() where I'm displaying some Toast message :
private void updateFlightController() {
if (isFlightControllerSupported()) {
mFlightController = ((Aircraft) DJISDKManager.getInstance().getProduct()).getFlightController();
mFlightController.setStateCallback(new FlightControllerState.Callback() {
#Override
public void onUpdate(FlightControllerState djiFlightControllerCurrentState) {
// TEST
showToast("mLatLngHOME = " + mLatLngHOME);
showToast("Latitude / Longitude = " + mLatLngHOME.latitude + " / " + mLatLngHOME.longitude);
}
});
}
}
The issue is, they display mLatLngHOME = null and Latitude / Longitude = NaN / NaN.
As if in the updateFlightController() method, it stays into a loop
and keep some old values.
Did I miss something ?
This doesn't appear to be an issue with DJI's SDK since the class and points you are using do not originate with DJI's products.
The mLatLngHOME variable is never updated in the onUpdate() method of the FlightController's setStateCallback , so it's definitely keep the old values. Please check the code below for reference:
if (mFlightController != null) {
mFlightController.setStateCallback(new FlightControllerState.Callback() {
#Override
public void onUpdate(FlightControllerState djiFlightControllerCurrentState) {
droneLocationLat = djiFlightControllerCurrentState.getAircraftLocation().getLatitude();
droneLocationLng = djiFlightControllerCurrentState.getAircraftLocation().getLongitude();
updateDroneLocation();
}
});
}
For more details of using DJIFlightController, you can check this tutorial: https://developer.dji.com/mobile-sdk/documentation/android-tutorials/GSDemo-Google-Map.html#locating-aircraft-on-google-map
I had the same issue. It means It can not get the location and I faced with it when I was using DJI Assistant 2 for a simulation drone flight in my room.
To solve it just set a location for your drone in the simulator and also turn off the RTK if your drone has it.
By doing this your problem will be solved.
Related
I am trying to create a bot that checks if a user attempts to enter a new voice channel, but when trying to override the onVoiceChannelUpdate method, it stays grayed out and gives me error that I don't have the parameters class.
This is the code I have for this method:
#Override
public void onVoiceChannelUpdate(VoiceChannelUpdateEvent event) {
User user = event.getUser();
VoiceChannel oldVoiceChannel = event.getOldVoiceChannel();
VoiceChannel newVoiceChannel = event.getNewVoiceChannel();
if (checkUserVoiceChannelRequest(user, oldVoiceChannel)) {
System.out.println(user.getName() + " has left the voice channel " + oldVoiceChannel.getName() + " and entered " + newVoiceChannel.getName() + ".");
}
}
I tried multiple ways of doing it, but all the methods have the exact same problem. I have some methods from before that check messages and all that and they work, but for any of the other methods that I use, the parameter class is not existent.
Errors showing:
Tried with onGuildVoiceUpdate method also, but it has the same issue:
can you try
public class Test extends ListenerAdapter {
#Override
public void onGuildVoiceUpdate(GuildVoiceUpdateEvent event) {
AudioChannel oldChannel = event.getChannelLeft();
AudioChannel newChannel = event.getChannelJoined();
}
}
Using JDA 5.0.0-beta.2.
If that does not work it might be an issue with your IDE so try to invalidate your cache.
You're looking for the GuildVoiceUpdateEvent instead.
#Override
public void onGuildVoiceUpdate(GuildVoiceUpdateEvent event) {
AudioChannel oldChannel = event.getChannelLeft();
AudioChannel newChannel = event.getChannelJoined();
...
}
Okay, so I am working on an app that will auto accept lyft request, but I am having a problem with my code not using performAction(AccessibilityNodeInfo.ACTION_CLICK); correctly.
public class AutoService extends AccessibilityService {
private static LyftAdapter lyftAdapter = new LyftAdapter();
// Automated Service (onAccessibilityEvent)
#TargetApi(16)
#Override
public void onAccessibilityEvent(AccessibilityEvent event)
{
AccessibilityNodeInfo source = event.getSource();
String lyftPackage = "com.lyft.android.driver";
String packageName = Tools.getPackage(source);
if (!packageName.equals(lyftPackage))
{
event.recycle();
return;
}
if (source == null)
{
event.recycle();
return;
}
processUI(event.getSource());
}
public void processUI(AccessibilityNodeInfo source)
{
source = getRootInActiveWindow();
if (Tools.getPackage(source).equals("com.lyft.android.driver") || Tools.getPackage(source).equals("me.lyft.android"))
{
if (!Lyft_Status.equals("OFFLINE"))
{
lyftAdapter.processEvent(source);
}
else
{
Log.v(TAG, "Can't process UI: " + Lyft_Status);
}
}
if (source != null)
source.recycle();
}
}
public abstract class RideshareAdapter {
public void processEvent(final AccessibilityNodeInfo source)
{
final StringBuilder sb = new StringBuilder();
processSubEvent(source, 0, sb);
final String string = sb.toString();
if (string == null)
{
Log.v(TAG, "String is NULL");
return;
}
processUIText(source, string.toLowerCase());
}
// PROCESS SECONDARY EVENT
private void processSubEvent(final AccessibilityNodeInfo source, final int n, final StringBuilder sb) {
for (int i = 0; i < n; ++i) {
sb.append("\t");
}
if (source != null)
{
sb.append(Tools.getText(source));
sb.append("\n");
final int childCount = source.getChildCount();
for (int j = 0; j < childCount; ++j) {
final AccessibilityNodeInfo child = source.getChild(j);
processSubEvent(child, n + 1, sb);
if (child != null) {
child.recycle();
}
}
}
}
// CLICK THE SCREEN
protected void clickScreen(AccessibilityNodeInfo source, final String text)
{
final AccessibilityNodeInfo s = source;
new Handler().postDelayed(new Runnable() {
List<AccessibilityNodeInfo> list = s.findAccessibilityNodeInfosByText(text);
#Override
public void run() {
for (final AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}, 1000);
}
}
public class LyftAdapter
extends RideshareAdapter
{
// LYFT ADAPTER
protected void processUIText(AccessibilityNodeInfo source, String text)
{
// RIDE REQUEST
if (text.contains("tap here to accept"))
{
clickScreen(source, "Tap here to accept");
{
}
The string comes out as (Just like it is shown):
Lyft
11 mins
away
Passenger Name
New
Tap here to accept
But for some reason, it triggers saying it is going to click on "Tap here to accept" textview, but it never actually does it. Any suggestions?
To be completely honest, your post is very difficult to read. You have functions that you have defined purely for organizational purposes and not because they are meant to be re-used. It makes it very difficult to parse and understand over the course of a StackOverflow post... Yet you did not provide enough for me to copy and paste and make sense of in Android Studio.
When you post code on StackOverflow you should go for a minimal replicating example and you ABSOLUTELY should remove your random Log calls. You may need them to help you understand what's happening, but hopefully WE do not :) and they just clutter things and make it more difficult to read your code. THIS BEING SAID, allow me to focus on one bit,
Note that I have cleaned up some of the poor style and debugging statements. Answers are in the code comments!
protected void clickScreen(final AccessibilityNodeInfo source, final String text)
{
new Handler().postDelayed(new Runnable() {
//Find ALL of the nodes that match the "text" argument.
List<AccessibilityNodeInfo> list = source.findAccessibilityNodeInfosByText(text);
#Override
public void run() {
//Non discrliminintly click them, whether they're buttons, or text fields or links... just click them and hope they do something.
for (final AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
//Delay it for a second AFTER the function has been called for no particularly good reason besides perhaps invalidating all of the nodes in the heirarchy... GOOD CALL!
}, 1000);
}
Given the above issues and the aforementioned generic code quality issues, it is difficult to provide a concise answer. This post leaves too many potential issues. Any provided answer would be a stab in the dark. I find it MOST likely that the problem is covered in my code comments, but it could most definitely be elsewhere. Also, my apologies for the sass!
All this being said, you might try this version of the function!
static void clickFirstMatchingNode(AccessibilityService service, final String text) {
final List<AccessibilityNodeInfo> list = service.getRootInActiveWindow().findAccessibilityNodeInfosByText(text);
for (AccessibilityNodeInfo node : list) {
//Check if the action completely successfully. Also, only click one of them. This is kind of an assumption, it also simplifies the logic. You can certainly write a version of this that clicks everything that matches!
if (node.performAction(AccessibilityNodeInfo.ACTION_CLICK)) return;
}
//If no node is successfully clicked Log some stuff!
Log.wtf(YourService.class.getName(), "Failed to click any nodes! WTF?: " + text);
}
NOTE: None of the above mentioned anything to do with your use of Accessibility APIs! I think that that is interesting.
I have written a Deferred task to be executed when the server starts. Here is the ContextListener where the endpoints eventually execute the task:
public class ServerSetupListenerVer1 implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
//Endpoint service
final LearnerProfileVer2PersistenceEndpoint learnerEndpoint = new LearnerProfileVer2PersistenceEndpoint();
final TutorProfileVer2PersistenceEndpoint tutorEndpoint = new TutorProfileVer2PersistenceEndpoint();
//Retrieve the dummy profile data
final LearnerProfileVer1[] learnerProfiles = (LearnerProfileVer1[]) ProfileUtils.getJSONToProfiles(STATUS_LEARNER);
final TutorProfileVer1[] tutorProfiles = (TutorProfileVer1[]) ProfileUtils.getJSONToProfiles(STATUS_TUTOR);
//Insert this data into the datastore
ObjectifyService.run(new VoidWork() {
#Override
public void vrun() {
for(LearnerProfileVer1 profile : learnerProfiles){
learnerEndpoint.insert(profile);
}
for(TutorProfileVer1 profile : tutorProfiles){
tutorEndpoint.insert(profile);
}
}
});
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
You can see that there are 2 endpoints that I am keeping references to here. Both of these endpoints have the Deferred task in common to execute. Following is the deferred task:
static class LocationTask implements DeferredTask {
private Account acc;
private LatLng geoCoordinates;
private int retries = 0;
public LocationTask(final Account acc, final LatLng geoCoordinates) {
logger.info("Profile at the time of task creation: " + acc.getProfile());
this.acc = acc;
this.geoCoordinates = geoCoordinates;
}
#Override
public void run() {
logger.info("Profile at the time of DeferredTask.run() call " + acc.getProfile());
String response = LocationUtil.getFormattedAddress(geoCoordinates);
if((response = checkResponseCode(response)) != null){
// Stash the address into the Datastore
logger.info("Profile to be updated with location-info: " + acc.getProfile());
acc.setLocationInfo(new Account.LocationInfo(response));
ofy().save().entity(acc).now();
}
}
private String checkResponseCode(String response){
if(response == null){
return null;
}
if(response.equals("ZERO_RESULTS")){
return null;
}
else if(response.equals("OVER_QUERY_LIMIT")){
// We can re-request without any GET params except the LatLng
if(retries ++ == 1){
return null;
}
return checkResponseCode(LocationUtil.getFormattedAddress(geoCoordinates, null));
}
else if(response.equals("REQUEST_DENIED")){
return null;
}
else if(response.equals("INVALID_REQUEST")){
return null;
}
else if(response.equals("UNKNOWN_ERROR")){
return null;
}
else{
return response;
}
}
}
Basically, these endpoints insert an Account into the Datastore using Objectify but just before insertion of Account, I wanted that to calculate the address from {Latitude, Longitude} using a deferred task. The problem is that the reference to the profile inside of the Account class vanishes at the time the task is executed. I confirmed this through the log statements. The log statement in the constructor of Deferred task prints the contents of the profile but the same profile is null when the logged from the run() method.
Surprising thing is that the LatLng geoCoordinates param is alive and it was retrieved from inside of the profile itself. Only the fields that I am not directly referencing(through params) are not alive. I was wondering if this has to do with serialization of the task...
Also note that the tasks start executing after the endpoint requests(1500 at once) are taken care of.
Also, a new task is created for each Account creation as follows:
void scheduleLocationInfoUpdation(final Account acc, final LatLng geoCoordinates){
if(geoCoordinates == null){
return;
}
//Using a deferred task
Queue queue = QueueFactory.getDefaultQueue();
queue.addAsync(TaskOptions.Builder.withPayload(new LocationTask(acc, geoCoordinates)));
}
This is a really weird scenario. Does anyone know what's wrong?
Yes, it turns out its because of Serialization. I made all my model classes implement Serializable and now the references are alive.
In my application I have autocompleteTextField. I need to get id of player when text in input changed. I am trying to play with models which are recommended by this question: using AutoCompleteTextField in wicket without String as the generic type but with no success. Behaviour stop working when I use PropertyModel or when I set class Player.class instead of null. I dont understand why.
final AutoCompleteTextField<Player> playersField = new AutoCompleteTextField<Player>("players",
new Model<Player>(selectedPlayer), null, new AbstractAutoCompleteRenderer<Player>() {
#Override
protected void renderChoice(Player player, Response response, String criteria) {
response.write(getTextValue(player));
}
#Override
protected String getTextValue(Player player) {
return player.getName() + " " + player.getSurname() + " "
+ player.getPlayerDiscriminator();
}
}
, settings) {
#Override
protected Iterator<Player> getChoices(String prefix) {
List<Player> choices = getPlayers();
return choices.iterator();
}
};
add(playersField);
playersField.add(new AjaxFormComponentUpdatingBehavior("onchange") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
System.out.println("do something");
// All I need here is just Id of player
}
}
});
From the question you linked to:
You probably already know this but if your custom class is really custom, you'll also need an IConverter that handles the String<->Someclass conversions: you can either register it with the application or override your component's getConverter(Class clazz ) method to return it.
Did you do that?
Also, if this doesn't fix the problem, please describe how it "stops working" in more details.
I currently have code to share a variable between two entry points in my application. The variable is the iconCount variable used to indicate how many notices the user has which is displayed on the home screen beside the icon. The way I've managed to do this is with a singleton and it (seems) to work fine at the moment. The issue is now that I do not want those notices to reset to zero when I completely turn off and turn on the phone. Should there be 7 notifications, I want there to be 7 notifications even after a device restart. For this I apparently need a persistent store integration which I've researched for a while.
So far my code for the bare singleton is:
public class MyAppIndicator{
public ApplicationIndicator _indicator;
public static MyAppIndicator _instance;
MyAppIndicator () {
setupIndicator();
}
public static MyAppIndicator getInstance() {
if (_instance == null) {
_instance = new MyAppIndicator ();
}
return(_instance);
}
public void setupIndicator() {
//Setup notification
if (_indicator == null) {
ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry.getInstance();
_indicator = reg.getApplicationIndicator();
if(_indicator == null) {
ApplicationIcon icon = new ApplicationIcon(EncodedImage.getEncodedImageResource ("notificationsdemo_jde.png"));
_indicator = reg.register(icon, false, true);
_indicator.setValue(0);
_indicator.setVisible(false);
}
}
}
public void setVisible1(boolean visible, int count) {
if (_indicator != null) {
if (visible) {
_indicator.setVisible(true);
_indicator.setValue(count); //UserInterface.incrementCount()
} else {
_indicator.setVisible(false);
}
}
}
}
I have been using the blackberry tutorial to figure out how to implement the persistable storage: http://supportforums.blackberry.com/t5/Java-Development/Storing-persistent-data/ta-p/442747
Now before I go any further I must stress I'm very new to java development so my coding might be completely wrong, but here is what I've tried to do:
public void setVisible1(boolean visible, int count) {
if (_indicator != null) {
if (visible) {
_indicator.setVisible(true);
_indicator.setValue(count); //UserInterface.incrementCount()
StoreInfo info = new StoreInfo();
info.incElement();
synchronized (persistentCount) {
//persistentCount.setContents(_data);
persistentCount.commit();
}
} else {
_indicator.setVisible(false);
}
}
}
static {
persistentCount = PersistentStore.getPersistentObject(0xdec6a67096f833cL);
synchronized (persistentCount) {
if (persistentCount.getContents() == null) {
persistentCount.setContents(new Vector()); //don't know what to do with this?
persistentCount.commit();
}
}
}
private static final class StoreInfo implements Persistable{
private int iconCount;
public StoreInfo(){}
public int getElement(){
return (int)iconCount;
}
public void incElement(){
iconCount++; //persistently increment icon variable
}
public void resetElement(){
iconCount=0; //when user checks application
}
}
The code above doesn't work which I'd expect somehow because I'm having trouble implementing the persistent portion. If anyone has any idea or input on how to accomplish this any assistance would be helpful. And of course thanks in advance.
In the example they have a variable called _data that holds the StoreInfo class, so first of all you should be keeping the StoreInfo in some variable. To do this have something like the following in your static initializer:
persistentCount = PersistentStore.getPersistentObject(0xdec6a67096f833cL);
synchronized (persistentCount) {
if (persistentCount.getContents() == null) {
persistentCount.setContents(new StoreInfo());
persistentCount.commit();
}
}
_data = (StoreInfo)persistentCount.getContents();
Now when you want to update it and save to the PersistentStore you can have something like:
_data.incElement();
synchronized(persistentCount) {
persistentCount.setContents(_data);
persistentCount.commit();
}
Assuming you're going to only ever have one instance of StoreInfo it could be better to put the commit code into the modifier methods so you don't forget to save the new values to the PersistentStore.