How can I connect my Unity android app to a 000webhost database? - c#

I'm making a Unity Android app that displays info from a database.
For that I used 000WebHost to make a website and a sql server. When I test the app with Unity in my computer, it works fine, a bit of loading time required, but it works perfectly.
But, when I build the apk and test it on my phone, it doesn't work. It gets stuck in the "loading text" screen I made and never loads the text from the database.
I have a log error in Unity that activates when the connection fails, and I suppose the same is happening here.
Is there a way to solve it or is it because i'm a free user?
Here are the codes:
WebTextLoader.cs (Unity/Displays text from the database)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class WebTextLoader : MonoBehaviour
{
[Serializable]
public class PlaceInfo
{
public string Titulo = "";
public string Texto = "";
}
public string URL; //example: https://arguidetest.000webhostapp.com/pruebaMedieval.php
public Text TituloUI;
public Text TextoUI;
public PlaceInfo placeInfo;
public void Start()
{
if (Debug.isDebugBuild)
{
StartCoroutine(GetRequest(URL));
}
}
IEnumerator GetRequest(string uri)
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
// Request and wait for the desired page.
yield return webRequest.SendWebRequest();
string jsonForm = uri;
if (webRequest.isNetworkError)
{
Debug.Log("Error loading");
}
else
{
try
{
placeInfo = JsonUtility.FromJson<PlaceInfo>(webRequest.downloadHandler.text);
TituloUI.text = placeInfo.Titulo;
TextoUI.text = placeInfo.Texto;
}
catch
{
Debug.Log("Error in connection");
}
}
}
}
}
pruebaMedieval.php (000webhost / turns an array of title and text into a JSon)
<?php
$server = ***;
$usuario = ***;
$pass = ***;
$database= ***;
$mysqli = new mysqli($server, $usuario, $pass, $database);
$query = $mysqli -> query("SELECT * FROM INFORMACION_EVENTOS where id = 1");
while ($valores = mysqli_fetch_array($query)) {
$titulo = $valores["titulo"];
$info = $valores["informacion"];
$array = array(
"Titulo" => $titulo,
"Texto" => $info
);
}
$result = json_encode($array);
echo $result;
?>
Also, in Unity player settings I have the internet connection as Require.
Sorry for the wall of text

Related

Custom Vision returns "NotFoundIteration" "Invalid iteration" when a UnityWebRequest is sent

Apparently, this has been an issue before, but still hasn't been fixed. I am using the code below to send a request from inside Unity.
using System.Collections;
using UnityEngine;
using System.Linq;
using Newtonsoft.Json;
using UnityEngine.Networking;
using UnityEngine.UI;
using System;
using CustomVison;
using UnityEngine.Windows;
public class APIscript : MonoBehaviour
{
[SerializeField]
private string _liveDataUrl = "https://rpscustomvision03-prediction.cognitiveservices.azure.com/customvision/v3.0/Prediction/17803eb0-ad74-4d89-adac-a438de3e7b23/detect/iterations/Iteration1/image";
[SerializeField]
private string _predictionKey = "c10307f68f45426c9c081c433b552ef7";
public WebCamTexture camTexture;
public string imgfilepath = #"E:\photo.png";
private void Start()
{
//var trainingApi = new TrainingApi { ApiKey |};
}
public void Request()
{
Texture2D tex = null;
byte[] fileData;
if (File.Exists(imgfilepath))
{
fileData = File.ReadAllBytes(imgfilepath);
tex = new Texture2D(2, 2);
tex.LoadImage(fileData); //..this will auto-resize the texture dimensions.
}
StartCoroutine(OnResponse(tex));
}
public IEnumerator OnResponse(Texture2D img)
{
using (UnityWebRequest req = new UnityWebRequest(_liveDataUrl, "POST")) //This is a new object.
{
req.SetRequestHeader("Prediction-Key", _predictionKey);
req.SetRequestHeader("Content-Type", "application/octet-stream");
req.SetRequestHeader("Iteration", "5718f089-1bf7-4441-b6b9-3b540ac00394");
Byte[] byteFromImage = File.ReadAllBytes(imgfilepath);
File.WriteAllBytes(#"E:\" + "test.jpg", byteFromImage);
req.uploadHandler = new UploadHandlerRaw(byteFromImage);
req.downloadHandler = new DownloadHandlerBuffer();
yield return req.SendWebRequest();
var text = req.downloadHandler.text;
//var result = JsonConvert.DeserializeObject<CustomVisionResult>(text);
if (text != null)
{
Debug.Log("#Predictions = " + text);
}
}
}
}
The debug log responds with:
#Predictions = {"code":"NotFoundIteration","message":"Invalid iteration"}
UnityEngine.Debug:Log (object)
APIscript/d__6:MoveNext () (at Assets/Scripts/APIscript.cs:65)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)
I am not sure what the issue is. I understand that something is preventing Unity from reaching the published Object Detection Iteration, but I have no idea what I should be checking.

HoloLens 2 throwing NotSupportedException on System.Net.Http.WebRequestHandler

I am trying to use Azure Cognitive Services (OCR) on the HoloLens 2. I'm using their .NET demo application with Nuget for Unity and importing all the necessary libraries. Everything compiles the way it should, but in runtime on the HoloLens, the code fails to execute the authentication part, saying there's a NotSupportedException. I've checked Internet/Client capabilities in Unity and I'm using the .NET 2.0 API (using the .NET 4.x doesn't help either). The scripting backend is IL2CPP because it's a UWP app. I'm using Unity 2020.3.13. I've gone through Azure's services and double-checked my endpoints and keys and those all work fine. It works through the Unity editor but fails on the HoloLens side. I've tried adding in a 'using' statement for System.Net.Http and double-checked the .dll is included in my editor folder, but I'm not sure how to make the HoloLens support this call. How do I get the device to access the API from within the code? I am new to networking and POST/GET calls.
Here's the part from UnityPlayer.log that details the exception:
NotSupportedException: System.Net.Http.WebRequestHandler::.ctor
at System.Net.Http.WebRequestHandler..ctor () [0x00000] in <00000000000000000000000000000000>:0
at Microsoft.Rest.ServiceClient`1[T].CreateRootHandler () [0x00000] in <00000000000000000000000000000000>:0
at Microsoft.Rest.ServiceClient`1[T]..ctor (System.Net.Http.DelegatingHandler[] handlers) [0x00000] in <00000000000000000000000000000000>:0
at Microsoft.Azure.CognitiveServices.Vision.ComputerVision.ComputerVisionClient..ctor (Microsoft.Rest.ServiceClientCredentials credentials, System.Net.Http.DelegatingHandler[] handlers) [0x00000] in <00000000000000000000000000000000>:0
at MainController.Start () [0x00000] in <00000000000000000000000000000000>:0
Here's my main program (I've shortened the unnecessary + working methods):
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision;
using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.WebCam;
using System.Net.Http;
using TMPro;
public class MainController : MonoBehaviour
{
PhotoCapture photoCaptureObject = null;
public TextMeshPro debugText;
private ComputerVisionClient client;
private static string subscriptionKey = "<key>";
private static string endpoint = "<endpoint>";
private string photoFilePath;
// Start is called before the first frame update
void Start()
{
debugText.text = "In start" + "\n";
ComputerVisionClient client = Authenticate(endpoint, subscriptionKey);
// fails here, in the HL, doesn't even go into the if block
if (client == null)
{
debugText.text += "client is null" + "\n";
}
else
{
debugText.text += "client is not null" + "\n";
}
}
// Update is called once per frame
void Update()
{
}
public static ComputerVisionClient Authenticate(string endpoint, string key)
{
ComputerVisionClient client =
new ComputerVisionClient(new ApiKeyServiceClientCredentials(key))
{ Endpoint = endpoint };
return client;
}
public void CaptureImage()
{
// called from ImageCapture button in app
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
...
// code for use in the HL to capture an image from what the user is seeing
}
void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
...
// save photo as .jpg and store on device
}
void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
{
...
// check success result and stop photo mode
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
ReadFileLocal(client, photoFilePath).Wait();
}
public async Task ReadFileLocal(ComputerVisionClient client, string localFile)
{
debugText.text += "reading file from local" + "\n";
string operationLocation = "";
string operationId = "";
if (!File.Exists(localFile))
{
debugText.text += "file does not exist in the path" + "\n";
}
else
{
debugText.text += "file exists, continuing" + "\n";
}
try
{
// Read text from URL
var textHeaders = await client.ReadInStreamAsync(File.OpenRead(localFile));
// After the request, get the operation location (operation ID)
operationLocation = textHeaders.OperationLocation;
Thread.Sleep(2000);
}
catch (Exception e)
{
debugText.text += "reading file failed" + "\n";
debugText.text += "Exception: " + e + "\n";
}
// <snippet_extract_response>
// Retrieve the URI where the recognized text will be stored from the Operation-Location header.
// We only need the ID and not the full URL
const int numberOfCharsInOperationId = 36;
operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);
// Extract the text
ReadOperationResult results;
do
{
results = await client.GetReadResultAsync(System.Guid.Parse(operationId));
}
while ((results.Status == OperationStatusCodes.Running ||
results.Status == OperationStatusCodes.NotStarted));
// </snippet_extract_response>
// <snippet_extract_display>
// Display the found text.
var textUrlFileResults = results.AnalyzeResult.ReadResults;
foreach (ReadResult page in textUrlFileResults)
{
foreach (Line line in page.Lines)
{
debugText.text += line + "\n";
}
}
}
}

How can i create a private message from telegram bot?

I'm connecting to telegram bot with webhook and i wanted to respond in private chat through telegram but if i send UID it doesn't send any message to the user from the bot.
this is what i did.
I created a Web API Project with .net framework to connect to webhook with telegram bot.
As a user, i wrote a command that will return some list of objects.
From the WebAPI i got the command and processed correctly
on sending response back i passed this {"method":"sendMessage","chat_id":"[user's UID who sent the command]", "text":"[returning list converted as string]", "reply_to_message_id":"[message id for the command]"}
This is the actual code that i'm sending
return new TelegramResponseModel
{ method = "sendMessage", chat_id = newUpdate.message.chat.id.ToString(),
text = text, reply_to_message_id = newUpdate.message.message_id };
on telegram nothing happens!!
You can use Nuget package library for implementing integration with Telegram called Telegram.Bot. Also there is few examples how you can use this library.
For example this short program shows how you can use WebHook's
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Owin.Hosting;
using Owin;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using File = System.IO.File;
namespace Telegram.Bot.Examples.WebHook
{
public static class Bot
{
public static readonly TelegramBotClient Api = new TelegramBotClient("Your API Key");
}
public static class Program
{
public static void Main(string[] args)
{
// Endpoint must be configured with netsh:
// netsh http add urlacl url=https://+:8443/ user=<username>
// netsh http add sslcert ipport=0.0.0.0:8443 certhash=<cert thumbprint> appid=<random guid>
using (WebApp.Start<Startup>("https://+:8443"))
{
// Register WebHook
// You should replace {YourHostname} with your Internet accessible hosname
Bot.Api.SetWebhookAsync("https://{YourHostname}:8443/WebHook").Wait();
Console.WriteLine("Server Started");
// Stop Server after <Enter>
Console.ReadLine();
// Unregister WebHook
Bot.Api.DeleteWebhookAsync().Wait();
}
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
var configuration = new HttpConfiguration();
configuration.Routes.MapHttpRoute("WebHook", "{controller}");
app.UseWebApi(configuration);
}
}
public class WebHookController : ApiController
{
public async Task<IHttpActionResult> Post(Update update)
{
var message = update.Message;
Console.WriteLine("Received Message from {0}", message.Chat.Id);
if (message.Type == MessageType.Text)
{
// Echo each Message
await Bot.Api.SendTextMessageAsync(message.Chat.Id, message.Text);
}
else if (message.Type == MessageType.Photo)
{
// Download Photo
var file = await Bot.Api.GetFileAsync(message.Photo.LastOrDefault()?.FileId);
var filename = file.FileId + "." + file.FilePath.Split('.').Last();
using (var saveImageStream = File.Open(filename, FileMode.Create))
{
await Bot.Api.DownloadFileAsync(file.FilePath, saveImageStream);
}
await Bot.Api.SendTextMessageAsync(message.Chat.Id, "Thx for the Pics");
}
return Ok();
}
}
}
here you have a functional code on php:
<?php
$token = 'yout_boot_tocken';
$website = 'https://api.telegram.org/bot'.$token;
$input = file_get_contents('php://input');
$update = json_decode($input, TRUE);
$chatId = $update['message']['chat']['id'];
$message = $update['message']['text'];
$messageCode = strtoupper($message);
switch($messageCode) {
case 'hello':
$response = 'Hello my friend... how are you?';
sendMessage($chatId, $response);
break;
case 'address':
$response = 'Your Addres is Rosent wallet 245';
sendMessage($chatId, $response);
break;
case '/INFO':
$response = 'Hi, i am a Boot';
sendMessage($chatId, $response);
break;
case 'bye':
$response = 'it was a pleasure chat with you';
sendMessage($chatId, $response);
break;
default:
$response = 'I dont understand what do you mean with '.$messageCode;
sendMessage($chatId, $response);
break;
}
function sendMessage($chatId, $response) {
$url = $GLOBALS['website'].'/sendMessage?
chat_id='.$chatId.'&parse_mode=HTML&text='.urlencode($response);
file_get_contents($url);
}
?>

opening sap and then proceeding to login screen through c# Automation

I am trying to open sap and connect to the gui using the following code . I Had to remove the earlier post due to some mistakes in post . I want to open sap logon 730 screen and then proceed to logon screen where i want to login using some credentials.I am getting some errors of connection entry point not found in the first code named opensap . login is working now. BUt still i cant make the SapBOX screen automatically process to the login screen. Please help in the code . Any help will be highly appreciated . Thanks
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SAPFEWSELib;
using SapROTWr;
using AVTAR.SAPLibrary;
using AVTAR.CustomLibrary;
namespace AvatarTest1 {
public class Sap {
public static GuiApplication SapGuiApp { get; set; }
public static GuiConnection SapConnection { get; set; }
public static GuiSession SapSession { get; set; }
public static void openSap(string env) {
Sap.SapGuiApp = new GuiApplication();
string connectString = null;
if (env.ToUpper().Equals("DEFAULT")) {
connectString = "1.0 Test ERP (DEFAULT)";
//connectString = "ASHOST = n7p.naan.as.com SYSNR = N7P
CLIENT =
460 _USER = ***** PASSWD = ****";*******";
} else {
connectString = env;
}
Sap.SapConnection = Sap.SapGuiApp.OpenConnection(connectString,
Sync: true); //creates connection
//Sap.SapSession = (GuiSession)Sap.SapConnection.Sessions.Item(0);
//creates the Gui session off the connection you made
}
public void Login(string userId,string pass,string clientid) {
try {
for (int i = 0; i <= 50; i++) {
Sap.SapSession = SapGuiApp.ActiveSession;
}
// System.Diagnostics.Process.Start(#"C:\Program
Files\SAP\FrontEnd\SAPgui\saplogon.exe");
GuiTextField Clientfield =
(GuiTextField)SapSession.ActiveWindow.FindById("wnd[0] / usr / txtRSYST -
MANDT");
GuiTextField UserIDField =
(GuiTextField)SapSession.ActiveWindow.FindById("wnd[0]/usr/txtRSYST-BNAME");
GuiTextField PassField =
(GuiTextField)SapSession.ActiveWindow.FindById("wnd[0]/usr/pwdRSYST-BCODE");
//GuiTextField LanguageField =
(GuiTextField)SapSession.ActiveWindow.FindById("wnd[0]/usr/txtRSYST-BNAME");
Clientfield.SetFocus();
Clientfield.Text = clientid;
UserIDField.SetFocus();
UserIDField.Text = userId;
PassField.SetFocus();
PassField.Text = pass;
//Sap.SapSession ssn= new SapSession.FindById("wnd[0]")
GuiButton enter =
(GuiButton)SapSession.ActiveWindow.FindById("wnd[0]");
enter.Press();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
In your Code you commented out "System.Diagnostics.Process.Start(#"C:\Program
Files\SAP\FrontEnd\SAPgui\saplogon.exe");"
Go with this aproach, but use "sapshcut.exe" from the same Folder instead!
(this will be available on the most systems)
In this case it could be as simple as that:
string strProg="C:\Program Files\SAP\FrontEnd\SAPgui\sapshcut.exe";
string strParam="-system=N7P -client=460 -user=youruser -password=yourpassword -language=EN";
System.Diagnostics.Process.Start(strProg,strParam);
Find an (VBA)Examle with some pre-Tests on the Commanline at trouble using excel macro for access to sap
Hope this will do ist for you!

WWW/UnityWebRequest POST/GET request won't return the latest data from server/url

I am creating a HoloLens app using Unity which has to take data from a REST API and display it.
I am currently using WWW datatype to get the data and yield return statement in a coroutine that will be called from the Update() function. When I try to run the code, I get the latest data from the API but when someone pushes any new data onto the API, it does not automatically get the latest data in real time and I have to restart the app to see the latest data.
My Code:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
public class TextChange : MonoBehaviour {
// Use this for initialization
WWW get;
public static string getreq;
Text text;
bool continueRequest = false;
void Start()
{
StartCoroutine(WaitForRequest());
text = GetComponent<Text>();
}
// Update is called once per frame
void Update()
{
}
private IEnumerator WaitForRequest()
{
if (continueRequest)
yield break;
continueRequest = true;
float requestFrequencyInSec = 5f; //Update after every 5 seconds
WaitForSeconds waitTime = new WaitForSeconds(requestFrequencyInSec);
while (continueRequest)
{
string url = "API Link goes Here";
WWW get = new WWW(url);
yield return get;
getreq = get.text;
//check for errors
if (get.error == null)
{
string json = #getreq;
List<MyJSC> data = JsonConvert.DeserializeObject<List<MyJSC>>(json);
int l = data.Count;
text.text = "Data: " + data[l - 1].content;
}
else
{
Debug.Log("Error!-> " + get.error);
}
yield return waitTime; //Wait for requestFrequencyInSec time
}
}
void stopRequest()
{
continueRequest = false;
}
}
public class MyJSC
{
public string _id;
public string author;
public string content;
public string _v;
public string date;
}
This is happening because resources caching is enabled on the Server.
Three possible solutions I know about:
1.Disable resources caching on the server. Instructions are different for every web server. Usually done in .htaccess.
2.Make each request with unique timestamp. The time should in Unix format.
This method will not work on iOS. You are fine since this is for HoloLens.
For example, if your url is http://url.com/file.rar, append ?t=currentTime at the end. currentTime is the actual time in Unix Format.
Full example url: http://url.com/file.rar?t=1468475141
Code:
string getUTCTime()
{
System.Int32 unixTimestamp = (System.Int32)(System.DateTime.UtcNow.Subtract(new System.DateTime(1970, 1, 1))).TotalSeconds;
return unixTimestamp.ToString();
}
private IEnumerator WaitForRequest()
{
string url = "API Link goes Here" + "?t=" + getUTCTime();
WWW get = new WWW(url);
yield return get;
getreq = get.text;
//check for errors
if (get.error == null)
{
string json = #getreq;
List<MyJSC> data = JsonConvert.DeserializeObject<List<MyJSC>>(json);
int l = data.Count;
text.text = "Data: " + data[l - 1].content;
}
else
{
Debug.Log("Error!-> " + get.error);
}
}
3.Disable Cache on the client side by supplying and modifying the Cache-Control and Pragma headers in the request.
Set Cache-Control header to max-age=0, no-cache, no-store then set Pragma header to no-cache.
I suggest you do this with UnityWebRequest instead of the WWW class. First, Include using UnityEngine.Networking;.
Code:
IEnumerator WaitForRequest(string url)
{
UnityWebRequest www = UnityWebRequest.Get(url);
www.SetRequestHeader("Cache-Control", "max-age=0, no-cache, no-store");
www.SetRequestHeader("Pragma", "no-cache");
yield return www.Send();
if (www.isError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Received " + www.downloadHandler.text);
}
}

Categories

Resources