Xamarin SqlServer cant get a connection - android

I'm building an app with the Entity Framework on Xamarin that lets me compare some data. But when I start my "fetchdata" function, I receive the Error:
System.Data.SqlClient.SqlException (0x80131904): Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)
I see many posts about Xamarin / Android & that it is not possible to get a connection to a SQL Server. Is there any way to fetch data from a SQL Server with .NET Core on Xamarin?

This is the string I put into SQL_Class folder with Sql_Common.cs
Fill up the brace brackets with actual parameters (removing the brace brakets too).
public static string SQL_connection_string = #"data source={server_address};initial catalog={database_name};user id={user_id};password={password};Connect Timeout={seconds}";
Then I access whenever I need it from any xamarin code just like we use in our asp.net c#
This works for me on my app without any issues.
using (SqlConnection Sql_Connection = new SqlConnection(Sql_Common.saralEHR_connection_string))
But as #Jason mentioned in his first reply, I too would get once again check the security part. I fexperienced before publishing Package to Google Play, they encrypt the App files with Hash Key Code and then only it gets upload to server

Yes it is possible (HuurrAYY!):
Im new in .net core, c# and so on and for me it was a hell of a work to get it working..
So here for the other noobs who are seeking for Help:
GuideĀ“s i used:
Building Android Apps with Entity Framework
https://medium.com/#yostane/data-persistence-in-xamarin-using-entity-framework-core-e3a58bdee9d1
https://blog.xamarin.com/building-android-apps-entity-framework/
Scaffolding
https://cmatskas.com/scaffolding-dbcontext-and-models-with-entityframework-core-2-0-and-the-cli/
How i did it:
Build your normal Xamarin app.
create new .net solution like in the tutorials (DONT WRITE YOUR Entity Framework CLASSES)
create a third solution what has to be a .net core console application
Scaffold your DB in your CONSOLE application move all created classes & folders in your "xamarin .net" solution & change the namespaces
Ready to Go!
Side Node: NuGets you need in every solution:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
[EDIT: NuGets you need in every solution]

I am doing this way (working snippet):
string connectionString = #"data source={server};initial catalog={database};user id={user};password={password};Connect Timeout=10";
string databaseTable = "{table name}";
string selectQuery = String.Format("SELECT count(*) as Orders FROM {0}", databaseTable);
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
//open connection
connection.Open();
SqlCommand command = new SqlCommand(selectQuery, connection);
command.Connection = connection;
command.CommandText = selectQuery;
var result = command.ExecuteScalar().ToString();
//check if there is result
if(result != null)
{
OrdersLabel.Text = result;
}
}
}
catch (Exception ex)
{
OrdersLabel.Text = ex.Message;
}
It is working fine, but API call more elegant.
I hope it helps.

Related

Google Sheets API access using Service Account from Android Device

Making app in Unity.
App works perfectly in Unity editor:
can access firebase for user login - this isnt the issue
can read and write from/to google sheet located in google drive using service account
When I build to android (apk file), and install on physical andoid device (Samsung S20 phone):
can access firebase for user login - so it is not an network/internet problem
CANT read/write from google sheet.
A portion of my code is here:
Authorisation - i am not sure if this bit works on the phone, or how to check.
public void Auth() // authorise access to the googlesheet online
{
//jsonKey = File.ReadAllText("Assets/Resources/Creds/beerhats-db-3***.json"); // location of key - read it - save to string
TextAsset txtAsset = (TextAsset)Resources.Load("beerhats-db-3***", typeof(TextAsset)); //i changed the file name here on stackoverflow just in case its a security thing
string jsonKey = txtAsset.text;
ServiceAccountCredential.Initializer initializer = new ServiceAccountCredential.Initializer(Secrets.serviceAccountID);
var jsonData = (JObject)JsonConvert.DeserializeObject(jsonKey);
if (jsonData != null) // the json file isnt moving or changing - so probably dont need an if statemet - remove later
{
string privateKey = jsonData["private_key"].Value<string>(); // specifically get the private key from all the data in the json file
ServiceAccountCredential credential = new ServiceAccountCredential(initializer.FromPrivateKey(privateKey));
service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
});
}
}
Part of my ReadFile code:
public async Task<string> ReadFile(string sheetName, string cellLocation) // for reading data only
{
// creates a string of location to write to
string whereToRead = sheetName + "!" + cellLocation;
SpreadsheetsResource.ValuesResource.GetRequest request = service.Spreadsheets.Values.Get(Secrets.spreadsheetID, whereToRead);
StringBuilder sb = new StringBuilder();
ValueRange response = await request.ExecuteAsync(); // run this on a separate thread as it takes long?
IList<IList<object>> values = response.Values;
On the phone, it executes the stringbuilder line, but not the executeasync() line.
Tried:
upgrade Unity version
change the min and target API levels
introduced keystore and project keys
introduced async incase it was a loading issue
change custom gradle template checkboxes
change read access on android sdk
update nuget installs of google apis
asking chatgpt for help
looking at various forums for similar issues
I am not running on an emulator, so no help with errors during run time. No errors in editor when built.
Expecting:
when installed on android device, the app to read/write from google sheet located in google drive
Requesting:
ideas to try to get this working! Thankyou :)

Different encoding using "android.util.Base64" and "org.apache.commons.codec.binary.Base64;"

I am programming an authentication service in Android and this one includes a server part written in java.
I do the same operations in both parts executing these two pieces of codes in Android and Server:
ANDROID:
String genChallengeResponse(String challenge, String message) {
String Hmac_ALG = "HmacSHA256";
SecretKey key = new SecretKeySpec(challenge.getBytes(), Hmac_ALG);
Mac m = Mac.getInstance(Hmac_ALG);
m.init(key);
m.update(password.getBytes());
byte[] mac = m.doFinal();
return new String(Base64.encode(mac, Base64.DEFAULT));
}
SERVER:
String genChallengeResponse(String challenge, String message) {
String Hmac_ALG = "HmacSHA256";
SecretKey key = new SecretKeySpec(challenge.getBytes(), Hmac_ALG);
Mac m = Mac.getInstance(Hmac_ALG);
m.init(key);
m.update(password.getBytes());
byte[] mac = m.doFinal();
return new String(Base64.encodeBase64(mac));
}
Starting from the same challenge and message these are the results:
Android: n2EaLpQr0uKgkZKhCQzwuIFeeLjzZKerZcETVNcfla4=
Server: n2EaLpQr0uKgkZKhCQzwuD9eeLjzZKerZcETVNcfla4=
^^
These are different just for TWO CHARACTERS.
The problem is that this strange behaviour does not appear in every pair of String passed to the functions...
I tried to use the UTF-8 in each system, but nothing changes...
Do someone knows what is the problem? If this is a known problem...
(is important to say that the problem is the same using Android 2.2 or also 4.0, then the problem is not the operating system, I think).
Can't comment yet therefore as answer:
I found out a few weeks ago that Android's Base64 uses different settings for the Linefeeds (check here: http://developer.android.com/reference/android/util/Base64.html )
I think in my case it was NO_WRAP missing.Perhaps one of the other options (NO_PADDING or URL-Safe, does the tested password contain + or - ?) could change your results...

PROPFIND Box.com and WebDav (JackRabbit)

In an attempt to bypass Box file/folder IDs and supporting a number of other services as well I decided to implement with WebDAV since I'm somewhat familiar with it on my linux box. I chose a library based on JackRabbit modified to work on Android which seemed to suit my needs. However, it wasn't long until I ran into a problem.
When attempting to list Box's root entries, multiStatus.getResponses() returns an empty array. When accessing another webdav server I get the responses as expected. Both servers return status code 207, as expected.
My code is below, any thoughts?
EDIT: I can move a file, though listing a directory's entries won't work :/
String host = "https://www.box.com/dav/";
//String host = "http://demo.sabredav.org/";
hostConfig = new HostConfiguration();
hostConfig.setHost(host);
HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
int maxHostConnections = 20;
params.setMaxConnectionsPerHost(hostConfig, maxHostConnections);
connectionManager.setParams(params);
client = new HttpClient(connectionManager);
Credentials creds = new UsernamePasswordCredentials("BOXEMAILADDRESS", "MYBOXPASSWORD");
//Credentials creds = new UsernamePasswordCredentials("testuser", "test");
client.getState().setCredentials(AuthScope.ANY, creds);
client.setHostConfiguration(hostConfig);
try
{
String propfindUri = host;
DavMethod method = new PropFindMethod(propfindUri, DavConstants.PROPFIND_ALL_PROP, DavConstants.DEPTH_1);
client.executeMethod(method);
Log.i("Status: " + method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
Log.i("Length: " + responses.length);
for(MultiStatusResponse response : responses)
{
Log.i("File: " + response.getHref());
}
}
catch (Exception e)
{
Log.printStackTrace(e);
}
While Box has some support for WebDAV, we only officially support it for iOS at the moment. Our testing has shown that our implementation of DAV works pretty well with the Windows native DAV client, as well as the Panic-Transmit Mac-specific client. Though the interactions there are not completely perfect.
Box WebDAV does not work well with the native osX (Mac) webDAV client. Expect huge delays as it looks like that client tries to load the whole tree before it displays anything.
Linux users may be able to tell you here on StackTrace which of the various OS webDAV clients/libs they've tried and which ones have worked better than others.
We do have plans to turn the crank and 10x improve our webDAV support sometime later this year, but we do not have a specific date, and just the nature of webDAV clients is such that even when we fix many of the issues with it, some client experiences on webDAV may still suck. For that reason we may only officially endorse a couple webDAV clients/libs per platform.
Hope that helps.

Challenge with Android communicating to GAE using restlet

I'm using Eclipse to (try to) build an Android client to get reuse a restlet service I developed using GAE and GWT.
My service is running at
http://127.0.0.1:8888/abc/audits
I can test this by going directly to this url, and by using my GWT client - both work.
However, the following code returns a communication error
private AuditsResource resource;
private Audits audits;
ClientResource cr = new ClientResource("http://127.0.0.1:8888/abc/audits");
resource = cr.wrap(AuditsResource.class);
try {
// Get the remote contact
audits = resource.retrieve();
// The task is over, let the parent conclude.
handler.sendEmptyMessage(0);
} catch (Exception e) {
Message msg = Message.obtain(handler, 2);
Bundle data = new Bundle();
data.putString("msg", "Cannot get the contact due to: "
+ e.getMessage());
msg.setData(data);
handler.sendMessage(msg);
}
I have no idea where to look next. I've instrumented the server implementation of AuditsResource, and it is never touched (by the Android application).
The AuditsResource class has one method, to keep things simple for now
#Get
public Audits retrieve();
It appears the problem is that the Andriod Emulator cannot connect to either 127.0.0.1 or 10.0.2.2. The solution is to use your PC's IP address.
I am able to connect from Android to my local Google App Engine through Android/Restlet using 10.0.2.2 instead of localhost.

getEntity call results in crash (using odata4j on a WCF service)

I am trying out odata4j in my android app to retrieve data from a DB that can be accessed from a WCF service.
ODataConsumer co = ODataConsumer.create("http://xxx.xx.xx.xxx:xxxx/Users");
for(OEntity user : co.getEntities("Users").execute())
{
// do stuff
}
However this crashes at the call to getEntities. I have tried a variety of other calls as well, such as
Enumerable<OEntity> eo = co.getEntities("Users").execute();
OEntity users = eo.elementAt(0);
However this also crashes at eo.elementAt(0).
The logcat doesn't tell me anything, and the callstack seems to be Suspended at ActivityThread.performLaunchActivity.
Entering "http://localhost:xxxx/Users" in my web browser on the other hand works as expected and returns the users in my DB in xml format.
Any ideas on how I can debug this?
To log all http requests/responses:
ODataConsumer.dump.all(true);
The uri passed to the consumer .create call should be the service root. e.g. .create("http://xxx.xx.xx.xxx:xxxx/"); Otherwise your code looks fine.
Note the Enumerable behaves like the .net type - enumeration is deferred until access. If you plan on indexing multiple times into the results, I'd suggest you call .toList() first.
Let me know what you find out.
Hope that helps,
- john
I guess the call should be:
ODataConsumer co = ODataConsumer.create("http://xxx.xx.xx.xxx:xxxx");
for(OEntity user : co.getEntities("Users").execute())
{
// do stuff
}
create defines service you want to connect but Users is the resource you want to query.
Can you try this way.
OEntity oEntity;
OQueryRequest<OEntity> oQueryRequest= oDataJerseyConsumer.getEntities(entityName);
List<OEntity> list= oQueryRequest.execute().toList();
for (OEntity o : list) {
List<OProperty<?>> props = o.getProperties();
for (OProperty<?> prop : props) {
System.out.println(prop.getValue().toString());
}
}

Categories

Resources