This question already has answers here:
How do you connect localhost in the Android emulator? [duplicate]
(7 answers)
Closed 1 year ago.
first of all I'd like to say that I've been looking for answers in a lot of places, but I just can't seem to find any that work for me. At the end I'll list all the options I've tried already. I'm new to Android and this is driving me nuts.
What I'm trying to do is submit a simple GET request to a local Laravel database running on my Mac. I'm trying to call this request from an Android app on an emulator.
My Laravel server is running on 127.0.0.1:8000 and it is turned on. In the .env file it states that DB_PORT=3306, but when changing the port in the request it doesn't matter.
What I'm doing in Android:
String url = "http://127.0.0.1:8000/api/recipes"; // More on the IP at the end
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("heeftGewerkt", response.substring(30));
errorMessage = "Succesful register";
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("heeftNietGewerkt", error.getMessage());
errorMessage = "Unsuccesful register";
}
});
My androidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.a1114049_1090780_iiatimd_app">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="#style/Theme.1114049_1090780_iiatimd_app">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I understand that when sending a request to 127.0.0.1 it might look for a server on the android device, which it obviously can't find. So I've tried to replace 127.0.0.1:8000 with localhost:8000, local-ip:8000 and public-ip:8000. None of these seem to work.
When I make a request to the Laravel server using Postman (http://127.0.0.1:8000/api/recipes) it works and I get all the recipes in my database. Can anyone clear this up for me?
EDIT:
The error I get is 'Failed to connect to /127.0.0.1:8000'. Looking at this it might be because I'm not passing in any DB credentials anywhere, but I'm also not sure if I should.
Use 10.0.2.2 to access your actual machine instead of localhost/127.0.0.1
When inside the emulator local host is referring to the emulator itself. However the emulator supports forwarding to the host machine on ip address 10.0.2.2
So you db server address with be
10.0.2.2:8000
Related
Ive been playing with .net Maui and had some success doing Bluetooth LE but for reasons I've gone ahead and changed my implementation to use wifi and a restful API. I am building for both android and IoS. I am testing with a real device, running android 12.
I am trying to make a basic http(s) (tried both http and https) request to a local server (an esp32). My url is:
const string url = "https://192.168.4.1/api";
My manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="31" />
<application android:allowBackup="true" android:icon="#mipmap/appicon" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
My initialisation function, which gets called when my page is loaded - MainPage()
private void init_network()
{
client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
}
and finally, my send function which gets called by a button pressed event
private bool SendCommand(string command)
{
try
{
var msg = new HttpRequestMessage(HttpMethod.Post, url);
msg.Content = JsonContent.Create(command);
HttpResponseMessage response = client.Send(msg); // line where the code throws exception
if (response.IsSuccessStatusCode)
{
return true;
}
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
return false;
}
I also have a runtime permissions section which asks for location_fine_access, which I've given access for.
When running through the request function, I get an exception thrown with the message:
[DOTNET] Operation is not supported on this platform.
I thought this was a permissions issue, and so android isn't letting me make the request but now I'm not so sure. Anyone else had and resolved this issue?
Looks as though .net maui doesnt hook into the android http client properly and is an issue on github. https://github.com/dotnet/maui/issues/1260
the suggested work around, which I have tested and works for me, is to instantiate your HttpClient with the native android handler like this as a workaround:
new HttpClient(new Xamarin.Android.Net.AndroidMessageHandler()).
I'm trying to implement Amazon IAP in a xamarin project following the documentation here.
So here's how my manifest looks like:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="87" android:versionName="8.7" package="XXXXXXXXXXXX">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<application android:icon="#mipmap/ic_launcher" android:label="XXXXXXXXXXXX">
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="XXXXXXXXXXXX" />
<receiver android:name="com.amazon.device.iap.ResponseReceiver" android:permission="com.amazon.inapp.purchasing.Permission.NOTIFY" >
<intent-filter>
<action android:name="com.amazon.inapp.purchasing.NOTIFY" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
And here's my code which is in the Android Project of my solution:
public async Task<bool> MyMethod()
{
try
{
var iapService = AmazonIapV2Impl.Instance;
var tcs = new TaskCompletionSource<bool>();
var skus = new SkusInput { Skus = new List<string>() { "XXXXXXXXX" } };
var requestId = iapService.GetProductData(skus).RequestId;
GetProductDataResponseDelegator delegator = null;
delegator = new GetProductDataResponseDelegator(async response =>
{
await Task.Run(() =>
{
DoSomething();
tcs.SetResult(result);
});
});
iapService.AddGetProductDataResponseListener(delegator.responseDelegate);
await tcs.Task;
}
catch(Exception ex)
{
}
return true;
}
This doesn't throw exceptions but the method DoSomething(); is never called and the last line return true; is never reached. Also the line tcs.Task is stuck on WaitingActivation status. It's like the listener/reciever wasn't working. So my code endlessly wait for the answer.
Any idea how to fix this?
I'm using Xamarin Form version: 5.0.0
Running on Mac, through Visual Studio and debugging on a simulator or a real device (Xiaomi mi9)
Thanks
So first of all the code await Task.Run(() => wasn't necessary to make it work. Secondly, the problem was that my app wasn't submitted yet on the Amazon AppStore and so to test a non-submit app you need to download on your testing phone the app:Amazon App Tester.
In case you have issue to download the Amazon App Tester read this:
In the past, I've tried to download the Amazon App Tester but for some reason my phone didn't want it. I finally "bought" it (it's $0.00 anyway) from my computer on amazon website. Once bought, I was able to find the app in the tab "my app" in the Amazon AppStore on my phone.
I am receiving an error just trying to set up an initial connection between the android client and my local socket server running Node.js but keep getting this xhr poll error, I have been trying to resolve this for the past few hours but not having much luck, any help would be appreciated. I have added the correct perms to the manifest and also made sure to use the private IP of the server (local machine), I can browse / telnet to this port, I have tried this on both the emulator and Physical device but receive the same error.
Client Connection
#Synchronized
fun setSocket() {
try {
Log.d("socketHandler", "setting Socket" )
mSocket = IO.socket("http://192.168.1.156:3000")
mSocket.on(Socket.EVENT_CONNECT_ERROR){
Log.d("SocketHandler" ,"Connection Error : ${it}")
it.forEach { item ->
val exception = item as EngineIOException
print(exception.message + " " + exception.code + " " + exception.cause)
}
}
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT){
Log.d("SocketHandler", "TimeOut Error : $it")
}
establishConnection()
} catch (e: Exception) {
when(e){
is URISyntaxException -> e.printStackTrace()
is EngineIOException -> {
Log.d("EngineException", "${e.code}, ${e.transport}, ${e.message}")
e.printStackTrace()
}
else -> e.printStackTrace()
}
}
}
Mainifest
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="#style/Theme.AirHockeyCompose">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="#string/app_name"
android:theme="#style/Theme.AirHockeyCompose.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Server
const { Server } = require("socket.io");
const io = new Server({ /* options */ });
io.on("connection", (socket) => {
console.log("connection")
console.log(socket)
});
io.listen(3000);
Error (this is received in Socket.EVENT_CONNECT_ERROR)
xhr poll error null java.io.IOException: 400io.socket.engineio.client.EngineIOException: xhr poll error
I am no expert on this but I did it some time back in a task. What I had was a nodejs server containing some images and an android that connects to it through socket to display them.
The connection was going fine I had no errors on it and you are free to check them here if it helps you in anyway https://github.com/aliosman21/Minly-Task .
As for your given snippets the only thing I noticed is that the server IP on emulators should be 10.0.2.2 (if memory serves) but since you already tried it on physical device I am not so sure.
I believe we both used the same client library https://socketio.github.io/socket.io-client-java/initialization.html
Another thing to make sure about is if you are using a self signed certificate on the server you have to pass {rejectUnauthorized: false} in the options
I am trying to run the sample application according to the starter guide: https://developer.here.com/documentation/android-premium/dev_guide/topics/app-run-simple.html
My problem is that, the requested URLs don't contain the appropriate app_id and app_code, as they exist in the manifest:
<meta-data
android:name="com.here.android.maps.appid" android:value="asdfghjklp098" />
<meta-data
android:name="com.here.android.maps.apptoken" android:value="123poiiuyttrrwq" />
When I try to read the manifest values in code, using the following:
try {
ApplicationInfo app = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
Bundle bundle = app.metaData;
Log.d("MetaDataLog", bundle.getString("com.here.android.maps.appid"));
//prints asdfghjklp098
Log.d("MetaDataLog", bundle.getString("com.here.android.maps.apptoken"));
//prints 123poiiuyttrrwq
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
The manifest meta-data is loaded correctly.
The tile URLs request look like this:
E/a.a.a.a.a.z0$d: IOException : while creating server connection. | failed to connect to 2.base.maps.api.here.com/2.18.232.228 (port 443) from /10.0.2.16 (port 55900) after 5000ms for URL: https://2.base.maps.api.here.com/maptile/2.1/maptile/newest/normal.day/11/324/701/512/png8?app_id={APP_ID}&app_code={APP_CODE}&lg=ENG&lg2=def&pview=DEF&ppi=320
Any idea what could be the issue ?
Solved the issue. The problem was, I was running on emulator.
I tested on another physical device, and the app was running fine.
Tip: DO NOT use emulators, even if the documentation states that they are supported. https://developer.here.com/documentation/android-premium/dev_guide/topics/system-requirements.html
Azure Active Directory
Google+ Auth
Xamarin Forms, PCL (NuGet 2.4.0.282)
Microsoft.Azure.Mobile.Client 4.0.0 & 4.0.2
After I successfully Login my phone does not return to my app. I have two test phones and one emulator, they display different info, after login.
Phone 1 (AAD Auth):
Phone 1 (Google Auth it greys out and just keeps "loading")
Phone 2 (AAD and Google Auth):
Emulator (AAD and Google Auth):
I have done everything I found here on Stack OverFlow, that makes sense and seems to be applicable to current versions of NuGets.
This person seems to be having a similar issue to me but with Google Log in
Azure not redirecting after loginenter link description here
I have tried integrating code into my project. And then I input my Azure info into Xamarin's sample: https://github.com/xamarin/xamarin-forms-samples/tree/master/WebServices/TodoAzureAuth
And I get the same results. I have tried both AAD and Google+ Auth. After login it just stays at the browser. So I feel like the client side code has to be correct. But I cant find any mess up on my Azure server code. I have tried this with projects that have a C# and Node.Js backend.(For one of my projects) My ALLOWED EXTERNAL REDIRECT URLS is ToDoList53172://easyauth.callback and in my AndroidManifest.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.xamarin.sample.TodoAzure">
<uses-sdk android:minSdkVersion="15" />
<application android:label="TodoAzure" android:icon="#drawable/icon">
<activity android:name="com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity" android:launchMode="singleTop" android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ToDoList53172" android:host="easyauth.callback" />
</intent-filter>
</activity>
</application>
</manifest>
OLD:
And I don't feel like I should post all the other code. It is all in the Xamarin sample project posted above. If people think I should I will.
NEW:
I am adding more code just to help people out. I did not want to overload, but better to have all the info in one place. So here is my MainActivity.cs Code
using System;
using System.Threading.Tasks;
using Android.App;
using Android.Content.PM;
using Android.OS;
using Microsoft.WindowsAzure.MobileServices;
using Android.Webkit;
namespace TodoAzure.Droid
{
[Activity(Label = "TodoAzure.Droid",
Icon = "#drawable/icon",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
Theme = "#android:style/Theme.Holo.Light")]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity, IAuthenticate
{
MobileServiceUser user;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
Microsoft.WindowsAzure.MobileServices.CurrentPlatform.Init();
App.Init((IAuthenticate)this);
LoadApplication(new App());
}
public async Task<bool> AuthenticateAsync()
{
bool success = false;
try
{
if (user == null)
{
// The authentication provider could also be Facebook, Twitter, or Microsoft
user = await TodoItemManager.DefaultManager.CurrentClient.LoginAsync(this, MobileServiceAuthenticationProvider.Google, Constants.URLScheme);
if (user != null)
{
CreateAndShowDialog(string.Format("You are now logged in - {0}", user.UserId), "Logged in!");
}
}
success = true;
}
catch (Exception ex)
{
CreateAndShowDialog(ex.Message, "Authentication failed");
}
return success;
}
public async Task<bool> LogoutAsync()
{
bool success = false;
try
{
if (user != null)
{
CookieManager.Instance.RemoveAllCookie();
await TodoItemManager.DefaultManager.CurrentClient.LogoutAsync();
CreateAndShowDialog(string.Format("You are now logged out - {0}", user.UserId), "Logged out!");
}
user = null;
success = true;
}
catch (Exception ex)
{
CreateAndShowDialog(ex.Message, "Logout failed");
}
return success;
}
void CreateAndShowDialog(string message, string title)
{
var builder = new AlertDialog.Builder(this);
builder.SetMessage(message);
builder.SetTitle(title);
builder.SetNeutralButton("OK", (sender, args) => { });
builder.Create().Show();
}
}
}
And Like I said above I have tried this with AAD as well. The code above is for Google.
Here is my Azure Auth setup
Here is the info I get after logging in with "https://todolistjbb.azurewebsites.net/.auth/login/aad" and then visiting
"https://todolistjbb.azurewebsites.net/.auth/me"
I feel like I have tried SO many things. I have recorded 66.68 hours working on just trying to get Authentication in my app.... please... someone tell me what I am doing wrong! I am losing it over here :'(
The way to solve this problem is do not start with a capitalized letter for your Url Scheme. It took me over 2 weeks to figure it out. I don't think this sis written anywhere, but I am sure it is.
So yeah to fix this i switched "ToDoList53172" to "todolist53172"
That's it... Oy vey!
According to your description, I assumed that you are using the Server-managed authentication provided by Azure App Service authentication/authorization. Since you are using the Microsoft.Azure.Mobile.Client >= 4.0.0, for your mobile client, you would leverage the following code snippet for logging via the server-flow:
var user = await client.LoginAsync(this, provider, "{url_scheme_of_your_app}");
Details you could follow Add authentication to the app. Moreover, you need to Add your app to the Allowed External Redirect URLs.
Based on the error message from your phone 2:
todolistjbbservice://easyauth.callback/#authorization_code=xxxxx
It seems that you did not configured the Authorized Redirect URI correctly. For the Azure Active Directory provider, you could follow here for registering your Web App / API or Native application. For the Google provider, you could follow here.
After correctly configured your preferred identity provider(s), you need to add your app to the Allowed External Redirect URLs:
Log into Azure Portal, choose your App Service
Click the Authentication / Authorization,
enter ToDoList53172://easyauth.callback in the Allowed External Redirect URLs, and save your changes.