Wish you a Very Happy New Year!!
Has anyone used Google Places API for Unity3D? I am trying to make an augmented reality app using Places API in Unity3D. I followed all the steps mentioned here
I have first fetched the device coordinates and fed those lat-lon to the places api url for a JSON response (creating an API key for Android). Following is my Unity3D C# code,
#define ANDROID
using UnityEngine;
using System.Collections;
using System.Timers;
using SimpleJSON;
public class Places : MonoBehaviour
{
static int Neversleep;
LocationInfo currentGPSPosition;
string gpsString;
public GUIStyle locStyle;
int wait;
float radarRadius;
string radarType, APIkey, radarSensor;
string googleRespStr;
void Start ()
{
Screen.sleepTimeout = SleepTimeout.NeverSleep;
radarRadius = 1000f;
radarType = "restaurant";
APIkey = "MyAPIkey";
radarSensor = "false";
}
void RetrieveGPSData()
{
currentGPSPosition = Input.location.lastData;
gpsString = "Lat: " + currentGPSPosition.latitude + " Lon: " + currentGPSPosition.longitude + " Alt: " + currentGPSPosition.altitude +
" HorAcc: " + Input.location.lastData.horizontalAccuracy + " VerAcc: " + Input.location.lastData.verticalAccuracy + " TS: " + Input.location.lastData.timestamp;
}
void OnGUI ()
{
GUI.Box (ScaleRect.scaledRect(25,25,700,100), "");
GUI.Label (ScaleRect.scaledRect(35,25,700,100), gpsString, locStyle);
GUI.Box (ScaleRect.scaledRect(25,130,700,800), "");
GUI.Label (ScaleRect.scaledRect(35,135,700,800), "" +googleRespStr, locStyle);
#if PC
Debug.Log("On PC / Don't have GPS");
#elif !PC
Input.location.Start(10f,1f);
int wait = 1000;
if(Input.location.isEnabledByUser)
{
while(Input.location.status == LocationServiceStatus.Initializing && wait>0)
{
wait--;
}
if (Input.location.status == LocationServiceStatus.Failed)
{}
else
{
RetrieveGPSData();
StartCoroutine(Radar());
}
}
else
{
GameObject.Find("gps_debug_text").guiText.text = "GPS not available";
}
#endif
}
IEnumerator Radar ()
{
string radarURL = "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=" + currentGPSPosition.latitude + "," + currentGPSPosition.longitude + "&radius=" + radarRadius + "&types=" + radarType + "&sensor=false" + radarSensor + "&key=" + APIkey;
WWW googleResp = new WWW(radarURL);
yield return googleResp;
googleRespStr = googleResp.text;
print (googleRespStr);
}
}
I am getting correct latitude and longitude coordinates but for place, all I get is this,
{
"debug_info" : [],
"html_attributions" : [],
"results" : [],
"status" : "REQUEST_DENIED"
}
It would be great if someone could help me out with this...
Thanks in advance!
Edit:
Download the JSON files from here and extract and put the folder in Assets folder of your Unity3d project. Refer the above code.
got it working. turns out, if you leave the SHA-1 fingerprint field empty, then also google create API key which can be used in the app.
Related
I'm attempting to integrate a ZKTEco U650-C with my company's systems to automatically fetch attendance logs but I'm having trouble connecting to the device using C#.
I managed to download the SDK from their website which includes the ZKHID, ZKCamera DLL files, and the SDK wrapper so I could import and use the functions from them.
In Visual Studio, I couldn't reference the ZKHID and ZKCamera DLL files because they are unmanaged. Although, I was able to reference the ZKBioModuleSDKWrapper because it uses PInvoke.
Some operations such as connecting to the device using the TcpClient class, initializing, and terminating the device were successful. However, using other operations such as opening the device and getting the device configuration couldn't be made because I don't know how to get the device handle.
Am I using the wrong set of SDK or is it something else? Any help would be appreciated.
It turns out I was using the wrong set of SDK. ZKTEco took down the SDK download link from their official website so I had to downloaded the correct SDK from a private server.
I added the zkemkeeper.dll reference as normal in Visual Studio, made some changes to the code, and I managed to receive the attendance logs.
using zkemkeeper;
namespace ZKTEco_Biometric_Device_Integration
{
internal class Program
{
public Program()
{
}
public enum CONSTANTS
{
PORT = 4370,
}
static void Main(string[] args)
{
Console.WriteLine("Connecting...");
CZKEM objCZKEM = new CZKEM();
if (objCZKEM.Connect_Net("192.168.1.11", (int)CONSTANTS.PORT))
{
objCZKEM.SetDeviceTime2(objCZKEM.MachineNumber, DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
Console.WriteLine("Connection Successful!");
Console.WriteLine("Obtaining attendance data...");
}
else
{
Console.WriteLine("Connection Failed!");
}
if (objCZKEM.ReadGeneralLogData(objCZKEM.MachineNumber))
{
//ArrayList logs = new ArrayList();
string log;
string dwEnrollNumber;
int dwVerifyMode;
int dwInOutMode;
int dwYear;
int dwMonth;
int dwDay;
int dwHour;
int dwMinute;
int dwSecond;
int dwWorkCode = 1;
int AWorkCode;
objCZKEM.GetWorkCode(dwWorkCode, out AWorkCode);
//objCZKEM.SaveTheDataToFile(objCZKEM.MachineNumber, "attendance.txt", 1);
while (true)
{
if (!objCZKEM.SSR_GetGeneralLogData(
objCZKEM.MachineNumber,
out dwEnrollNumber,
out dwVerifyMode,
out dwInOutMode,
out dwYear,
out dwMonth,
out dwDay,
out dwHour,
out dwMinute,
out dwSecond,
ref AWorkCode
))
{
break;
}
log = "User ID:" + dwEnrollNumber + " " + verificationMode(dwVerifyMode) + " " + InorOut(dwInOutMode) + " " + dwDay + "/" + dwMonth + "/" + dwYear + " " + time(dwHour) + ":" + time(dwMinute) + ":" + time(dwSecond);
Console.WriteLine(log);
//logs.Add(log);
}
}
//Console.ReadLine();
}
static void getAttendanceLogs(CZKEM objCZKEM)
{
string log;
string dwEnrollNumber;
int dwVerifyMode;
int dwInOutMode;
int dwYear;
int dwMonth;
int dwDay;
int dwHour;
int dwMinute;
int dwSecond;
int dwWorkCode = 1;
int AWorkCode;
objCZKEM.GetWorkCode(dwWorkCode, out AWorkCode);
//objCZKEM.SaveTheDataToFile(objCZKEM.MachineNumber, "attendance.txt", 1);
while (true)
{
if (!objCZKEM.SSR_GetGeneralLogData(
objCZKEM.MachineNumber,
out dwEnrollNumber,
out dwVerifyMode,
out dwInOutMode,
out dwYear,
out dwMonth,
out dwDay,
out dwHour,
out dwMinute,
out dwSecond,
ref AWorkCode
))
{
break;
}
log = "User ID:" + dwEnrollNumber + " " + verificationMode(dwVerifyMode) + " " + InorOut(dwInOutMode) + " " + dwDay + "/" + dwMonth + "/" + dwYear + " " + time(dwHour) + ":" + time(dwMinute) + ":" + time(dwSecond);
Console.WriteLine(log);
}
}
static string time(int Time)
{
string stringTime = "";
if (Time < 10)
{
stringTime = "0" + Time.ToString();
}
else
{
stringTime = Time.ToString();
}
return stringTime;
}
static string verificationMode(int verifyMode)
{
String mode = "";
switch (verifyMode)
{
case 0:
mode = "Password";
break;
case 1:
mode = "Fingerprint";
break;
case 2:
mode = "Card";
break;
}
return mode;
}
static string InorOut(int InOut)
{
string InOrOut = "";
switch (InOut)
{
case 0:
InOrOut = "IN";
break;
case 1:
InOrOut = "OUT";
break;
case 2:
InOrOut = "BREAK-OUT";
break;
case 3:
InOrOut = "BREAK-IN";
break;
case 4:
InOrOut = "OVERTIME-IN";
break;
case 5:
InOrOut = "OVERTIME-OUT";
break;
}
return InOrOut;
}
}
}
Ok , I"m doing what looks like a simple Dapper query
but if I pass in my studId parameter, it blows up with this low level networking exception:
{"A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied."}
if I comment out the line of sql that uses it, fix the where clause, ,and comment out the line where it's added the the parameters object. It retrieves rows as expected.
I've spent the last 2.5 days trying everything I could think of, changing the names to match common naming patterns, changing type to a string (just gave a error converting string to number), yadda yadda yadda..
I'm at a complete loss as to why it doesn't like that parameter, I look at other code that works and they pass Id's just fine...
At this point I figure it has to be an ID-10-t that's staring me in the face and I'm just assuming my way right past it with out seeing it.
Any help is appreciated
public List<StudDistLearnSchedRawResponse> GetStudDistanceLearningScheduleRaw( StudDistLearnSchedQueryParam inputs )
{
var aseSqlConnectionString = Configuration.GetConnectionString( "SybaseDBDapper" );
string mainSql = " SELECT " +
" enrollment.stud_id, " +
" sched_start_dt, " +
" sched_end_dt, " +
" code.code_desc, " +
" student_schedule_dl.enrtype_id, " +
" student_schedule_dl.stud_sched_dl_id, " +
" dl_correspond_cd, " +
" course.course_name, " +
" stud_course_sched_dl.sched_hours, " +
" actual_hours, " +
" course_comments as staff_remarks, " + // note this column rename - EWB
" stud_course_sched_dl.sched_item_id , " +
" stud_course_sched_dl.stud_course_sched_dl_id " +
" from stud_course_sched_dl " +
" join student_schedule_dl on student_schedule_dl.stud_sched_dl_id = stud_course_sched_dl.stud_sched_dl_id " +
" join course on stud_course_sched_dl.sched_item_id = course.sched_item_id " +
" left join code on student_schedule_dl.dl_correspond_cd = code.code_id " +
" join enrollment_type on student_schedule_dl.enrtype_id = enrollment_type.enrtype_id " +
" join enrollment on enrollment_type.enr_id = enrollment.enr_id " +
" where enrollment.stud_id = #studId " +
" and sched_start_dt >= #startOfWeek" +
" and sched_end_dt <= #startOfNextWeek";
DapperTools.DapperCustomMapping<StudDistLearnSchedRawResponse>();
//string sql = query.ToString();
DateTime? startOfWeek = StartOfWeek( inputs.weekStartDateTime, DayOfWeek.Monday );
DateTime? startOfNextWeek = StartOfWeek( inputs.weekStartDateTime.Value.AddDays( 7 ) , DayOfWeek.Monday );
try
{
using ( IDbConnection db = new AseConnection( aseSqlConnectionString ) )
{
db.Open();
var arguments = new
{
studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
startOfWeek = startOfWeek.Value.ToShortDateString(),
startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
List<StudDistLearnSchedRawResponse> list = new List<StudDistLearnSchedRawResponse>();
list = db.Query<StudDistLearnSchedRawResponse>( mainSql, arguments ).ToList();
return list;
}
}
catch (Exception ex)
{
Trace.WriteLine(ex.ToString());
return null;
}
}
Here is the input object
public class StudDistLearnSchedQueryParam
{
public Int64 StudId;
public DateTime? weekStartDateTime;
}
Here is the dapper tools object which just abstracts some ugly code to look nicer.
namespace EricSandboxVue.Utilities
{
public interface IDapperTools
{
string ASEConnectionString { get; }
AseConnection _aseconnection { get; }
void ReportSqlError( ILogger DalLog, string sql, Exception errorFound );
void DapperCustomMapping< T >( );
}
public class DapperTools : IDapperTools
{
public readonly string _aseconnectionString;
public string ASEConnectionString => _aseconnectionString;
public AseConnection _aseconnection
{
get
{
return new AseConnection( _aseconnectionString );
}
}
public DapperTools( )
{
_aseconnectionString = Environment.GetEnvironmentVariable( "EIS_ASESQL_CONNECTIONSTRING" );
}
public void ReportSqlError( ILogger DalLog, string sql, Exception errorFound )
{
DalLog.LogError( "Error in Sql" );
DalLog.LogError( errorFound.Message );
//if (env.IsDevelopment())
//{
DalLog.LogError( sql );
//}
throw errorFound;
}
public void DapperCustomMapping< T >( )
{
// custom mapping
var map = new CustomPropertyTypeMap(
typeof( T ),
( type, columnName ) => type.GetProperties( ).FirstOrDefault( prop => GetDescriptionFromAttribute( prop ) == columnName )
);
SqlMapper.SetTypeMap( typeof( T ), map );
}
private string GetDescriptionFromAttribute( System.Reflection.MemberInfo member )
{
if ( member == null ) return null;
var attrib = (Dapper.ColumnAttribute) Attribute.GetCustomAttribute( member, typeof(Dapper.ColumnAttribute), false );
return attrib == null ? null : attrib.Name;
}
}
}
If I change the SQL string building to this(below), but leave everything else the same(Including StudId in the args struct)... it doesn't crash and retrieves rows, so it's clearly about the substitution of #studId...
// " where enrollment.stud_id = #studId " +
" where sched_start_dt >= #startOfWeek" +
" and sched_end_dt <= #startOfNextWeek";
You name your data members wrong. I had no idea starting a variable name with # was possible.
The problem is here:
var arguments = new
{
#studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
#startOfWeek = startOfWeek.Value.ToShortDateString(),
#startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
It should have been:
var arguments = new
{
studId = inputs.StudId, // it chokes and gives a low level networking error - EWB
startOfWeek = startOfWeek.Value.ToShortDateString(),
startOfNextWeek = startOfNextWeek.Value.ToShortDateString(),
};
The # is just a hint to Dapper, that it should replace with a corresponding member name.
## has special meaning in some SQL dialects, that's probably what makes the trouble.
So here's what I Found out.
The Sybase implementation has a hard time with Arguments.
It especially has a hard time with arguments of type int64 (this existed way pre .NetCore)
So If you change the type of the passed in argument from int64 to int32, everything works fine.
You can cast it, or just change the type of the method parameter
I'm very new at coding and I'm having some issues. I'd like to display the followers of followers of ..... of followers of some specific users in Twitter. I have coded this and I can set a limit for the depth. But, while running the code with a small sample, I saw that I run into the same users again and my code re-display the followers of these users. How can I avoid this and skip to the next user? You can find my code below:
By the way, while running my code, I encounter with a 401 error. In the list I'm working on, there's a private user, and when my code catches that user, it stops. Additionally, how can I deal with this issue? I'd like to skip such users and prevent my code to stop.
Thank you for your help in advance!
PS: I know that I'll encounter with a 429 error working with a large sample. After fixing these issues, I'm planning to review relevant discussions to deal with.
public class mainJava {
public static Twitter twitter = buildConfiguration.getTwitter();
public static void main(String[] args) throws Exception {
ArrayList<String> rootUserIDs = new ArrayList<String>();
Scanner s = new Scanner(new File("C:\\Users\\ecemb\\Desktop\\rootusers1.txt"));
while (s.hasNextLine()) {
rootUserIDs.add(s.nextLine());
}
s.close();
for (String rootUserID : rootUserIDs) {
User rootUser = twitter.showUser(rootUserID);
List<User> userList = getFollowers(rootUser, 0);
}
}
public static List<User> getFollowers(User parent, int depth) throws Exception {
List<User> userList = new ArrayList<User>();
if (depth == 2) {
return userList;
}
IDs followerIDs = twitter.getFollowersIDs(parent.getScreenName(), -1);
long[] ids = followerIDs.getIDs();
for (long id : ids) {
twitter4j.User child = twitter.showUser(id);
userList.add(child);
getFollowers(child, depth + 1);
System.out.println(depth + "th user: " + parent.getScreenName() + " Follower: " + child.getScreenName());
}
return userList;
}
}
I guess graph search algorithms can be implemented for this particular issue. I chose Breadth First Search algorithm because visiting root user's followers at first would be better. You can check this link to additional information about algorithm.
Here is my implementation for your problem:
public List<User> getFollowers(User parent, int startDepth, int finalDepth) {
List<User> userList = new ArrayList<User>();
Queue<Long> queue = new LinkedList<Long>();
HashMap<Long, Integer> discoveredUserId = new HashMap<Long, Integer>();
try {
queue.add(parent.getId());
discoveredUserId.put(parent.getId(), 0);
while (!queue.isEmpty()) {
long userId = queue.remove();
int discoveredDepth = discoveredUserId.get(userId);
if (discoveredDepth == finalDepth) {
continue;
}
User user = twitter.showUser(userId);
handleRateLimit(user.getRateLimitStatus());
if (user.isProtected()) {
System.out.println(user.getScreenName() + "'s account is protected. Can't access followers.");
continue;
}
IDs followerIDs = null;
followerIDs = twitter.getFollowersIDs(user.getScreenName(), -1);
handleRateLimit(followerIDs.getRateLimitStatus());
long[] ids = followerIDs.getIDs();
for (int i = 0; i < ids.length; i++) {
if (!discoveredUserId.containsKey(ids[i])) {
discoveredUserId.put(ids[i], discoveredDepth + 1);
User child = twitter.showUser(ids[i]);
handleRateLimit(child.getRateLimitStatus());
userList.add(child);
if (discoveredDepth >= startDepth && discoveredDepth < finalDepth) {
System.out.println(discoveredDepth + ". user: " + user.getScreenName() + " has " + user.getFollowersCount() + " follower(s) " + (i + 1) + ". Follower: " + child.getScreenName());
}
queue.add(ids[i]);
} else {//prints to console but does not check followers. Just for data consistency
User child = twitter.showUser(ids[i]);
handleRateLimit(child.getRateLimitStatus());
if (discoveredDepth >= startDepth && discoveredDepth < finalDepth) {
System.out.println(discoveredDepth + ". user: " + user.getScreenName() + " has " + user.getFollowersCount() + " follower(s) " + (i + 1) + ". Follower: " + child.getScreenName());
}
}
}
}
} catch (TwitterException e) {
e.printStackTrace();
}
return userList;
}
//There definitely are more methods for handling rate limits but this worked for me well
private void handleRateLimit(RateLimitStatus rateLimitStatus) {
//throws NPE here sometimes so I guess it is because rateLimitStatus can be null and add this conditional expression
if (rateLimitStatus != null) {
int remaining = rateLimitStatus.getRemaining();
int resetTime = rateLimitStatus.getSecondsUntilReset();
int sleep = 0;
if (remaining == 0) {
sleep = resetTime + 1; //adding 1 more second
} else {
sleep = (resetTime / remaining) + 1; //adding 1 more second
}
try {
Thread.sleep(sleep * 1000 > 0 ? sleep * 1000 : 0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
in this code HashMap<Long, Integer> discoveredUserId is used to prevent program checking same users repeatedly and storing in which depth we faced with this user.
and for private users, there is isProtected() method in twitter4j library.
Hope this implementation helps.
I have never wrote a script before and I was asked today to make a Visual SourceSafe script that returns all of the labels that are stored.
I have 0 idea on how to start this as I have never wrote a script before. Can anybody point me in the right direction with this please?
Thanks!
You can use the History command of SourceSafe to get the history info of an item and extract the label info you need.
Here is a simple sample for you:
private void GetItem(VSSItem vssItem)
{
if (vssItem.Type == 0) //Type == 0 means it's a project
{
bool bIncludeDeleted = false;
IVSSItems vssItems = vssItem.get_Items(bIncludeDeleted);
foreach (VSSItem vssitem in vssItems)
{
GetItem(vssitem);
foreach (IVSSVersion vssVersion in vssitem.get_Versions(0))
{
string vssItemName = "";
if (vssVersion.VSSItem.Name == "")
vssItemName = vssitem.Spec;
else
vssItemName = vssVersion.VSSItem.Spec;
if (vssVersion.Action.IndexOf("Label") > -1 )
{
if (vssitem.Spec == vssVersion.VSSItem.Spec)
{
MessageBox.Show("Item " + vssItemName + " in " + "Version " + vssVersion.VersionNumber.ToString() + " With the lable: " + vssVersion.Label);
}
}
}
}
}
I want to disable a User programmetically by using SOAP API. How can I do that? I am using Partner API and I have Developer edition. I have manage users persmissions set. I have gone through this link. I am looking for code which can help me disable/deactivate a User.
This is my code:
import com.sforce.soap.partner.Connector;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;
public class DeactivateUser {
public static void main(String[] args) {
ConnectorConfig config = new ConnectorConfig();
config.setUsername("waprau#waprau.com");
config.setPassword("sjjhggrhgfhgffjdgj");
PartnerConnection connection = null;
try {
connection = Connector.newConnection(config);
QueryResult queryResults = connection.query("SELECT Username, IsActive from User");
if (queryResults.getSize() > 0) {
for (SObject s : queryResults.getRecords()) {
if(s.getField("Username").equals("abcd#pqrs.com")){
System.out.println("Username: " + s.getField("Username"));
s.setField("IsActive", false);
}
System.out.println("Username: " + s.getField("Username") + " IsActive: " + s.getField("IsActive"));
}
}
} catch (ConnectionException ce) {
ce.printStackTrace();
}
}
}
This is output:
Username: waprau#waprau.com IsActive: true
Username: jsmith#ymail.net IsActive: false
Username: abcd#pqrs.com
Username: abcd#pqrs.com IsActive: false
However in UI when I go to My Name > Setup > Manage Users > Users, it always show 'Active' check box for user abcd#pqrs.com selected :-(
It doesn't look like you're actually sending the update back to Salesforce - you're just setting IsActive to false locally. You will need to use a call to PartnerConnection.update(SObject[] sObjects) in order for Salesforce to reflect your changes, like so:
try {
connection = Connector.newConnection(config);
QueryResult queryResults = connection.query("SELECT Id, Username, IsActive from User");
if ( queryResults.getSize() > 0 ) {
// keep track of which records you want to update with an ArrayList
ArrayList<SObject> updateObjects = new ArrayList<SObject>();
for (SObject s : queryResults.getRecords()) {
if ( s.getField("Username").equals("abcd#pqrs.com") ){
System.out.println("Username: " + s.getField("Username"));
s.setField("Id", null);
s.setField("IsActive", false);
}
updateObjects.add(s); // if you want to update all records...if not, put this in a conditional statement
System.out.println("Username: " + s.getField("Username") + " IsActive: " + s.getField("IsActive"));
}
// make the update call to Salesforce and then process the SaveResults returned
SaveResult[] saveResults = connection.update(updateObjects.toArray(new SObject[updateObjects.size()]));
for ( int i = 0; i < saveResults.length; i++ ) {
if ( saveResults[i].isSuccess() )
System.out.println("record " + saveResults[i].getId() + " was updated successfully");
else {
// There were errors during the update call, so loop through and print them out
System.out.println("record " + saveResults[i].getId() + " failed to save");
for ( int j = 0; j < saveResults[i].getErrors().length; j++ ) {
Error err = saveResults[i].getErrors()[j];
System.out.println("error code: " + err.getStatusCode().toString());
System.out.println("error message: " + err.getMessage());
}
}
}
}
} catch (ConnectionException ce) {
ce.printStackTrace();
}
It is possible to directly work with the user record without the SOQL query if you already know the Id.
SalesforceSession session = ...;
sObject userSObject = new sObject();
userSObject.Id = "00570000001V9NA";
userSObject.type = "User";
userSObject.Any = new System.Xml.XmlElement[1];
XmlDocument xmlDocument = new XmlDocument();
XmlElement fieldXmlElement = xmlDocument.CreateElement("IsActive");
fieldXmlElement.InnerText = bool.FalseString;
userSObject.Any[0] = fieldXmlElement;
SaveResult[] result = session.Binding.update(new sObject[] { userSObject });
foreach(SaveResult sr in result)
{
System.Diagnostics.Debug.WriteLine(sr.success + " " + sr.id);
if(!sr.success)
{
foreach(Error error in sr.errors)
{
System.Diagnostics.Debug.WriteLine(error.statusCode + " " + error.message);
}
}
}