Проблема в том, что пакет google_maps_flutter требует разрешения для доступа к вашему местоположению, но в пакете нет собственных кодов для запроса этого разрешения.
Так что вам нужно написать собственный код или просто установить другой пакет, который может получить это разрешение.
Установите это: https://pub.dartlang.org/packages/location
Затем:
getLocationPermission() async {
final Location location = new Location();
try {
location.requestPermission(); //to lunch location permission popup
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
print('Permission denied');
}
}
}
Или, если вы хотите более твердый код, это мой код для какого-то проекта (с пакетом местоположения):
//Show some loading indicator depends on this boolean variable
bool askingPermission = false;
@override
void initState() {
this.getLocationPermission();
super.initState();
}
Future getLocationPermission() async {
setState(() {
this.askingPermission = true;
});
bool result;
final Location location = Location();
try {
if (await location.hasPermission())
result = true;
else {
result = await location.requestPermission();
}
print('getLocationPermission: '
'${result ? 'Access Allowed' : 'Access Denied'}');
} catch (log, trace) {
result = false;
print('getLocationPermission/log: $log');
print('getLocationPermission/trace: $trace');
} finally {
setState(() {
this.askingPermission = false;
});
}
return result;
}
Я экспериментировал с этим только что, но к сожалению забыл, как все это совместилось... для моей цели, это оказалось горестно медленным, таким образом, я отключил C# и вернулся ко всему C++. Когда Вы говорите, что Вы - прежде всего, разработчик C#, я надеюсь, что Вы понимаете указатели, потому что, если Вы не делаете, нет никакого способа быть нежным.
Передача массивов в основном свелась к использованию семейства CoTaskMemAlloc функций на стороне C++ (http://msdn.microsoft.com/en-us/library/ms692727 (По сравнению с 85) .aspx) и класс Маршала на стороне C# (http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx - который имеет методы как AllocCoTaskMem). Для C# я закончил со служебным классом:
public class serviceUtils
{
unsafe public long stringToCoTaskPtr( ref str thestring )
{
return (long)Marshal.StringToCoTaskMemAnsi(thestring.theString).ToPointer();//TODO : what errors occur from here? handle them
}
unsafe public long bytesToCoTaskPtr( ref bytes thebytes, ref short byteCnt)
{
byteCnt = (short)thebytes.theArray.Length;
IntPtr tmpptr = new IntPtr();
tmpptr = Marshal.AllocCoTaskMem(byteCnt);
Marshal.Copy(thebytes.theArray, 0, tmpptr, byteCnt);
return (long)tmpptr.ToPointer();
}
public void freeCoTaskMemPtr(long ptr)
{
Marshal.FreeCoTaskMem(new IntPtr(ptr));//TODO : errors from here?
}
public string coTaskPtrToString(long theptr)
{
return Marshal.PtrToStringAnsi(new IntPtr(theptr));
}
public byte[] coTaskPtrToBytes(long theptr, short thelen)
{
byte[] tmpbytes = new byte[thelen];
Marshal.Copy(new IntPtr(theptr), tmpbytes, 0, thelen);
return tmpbytes;
}
}
Только бросить еще некоторый код в Вас: этот C++
#import "..\COMClient\bin\Debug\COMClient.tlb" named_guids raw_interfaces_only
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL); //Initialize all COM Components
COMClient::IComCalculatorPtr pCalc;
// CreateInstance parameters
HRESULT hRes = pCalc.CreateInstance(COMClient::CLSID_ComCalculator);
if (hRes == S_OK) {
long size = 5;
LPVOID ptr = CoTaskMemAlloc( size );
if( ptr != NULL )
{
memcpy( ptr, "12345", size );
short ans = 0;
pCalc->changeBytes( (__int64*)&ptr, &size, &ans );
CoTaskMemFree(ptr);
}
}
CoUninitialize (); //DeInitialize all COM Components
return 0;
}
названный этим c#
public short changeBytes(ref long ptr, ref int arraysize)
{
try
{
IntPtr interopPtr = new IntPtr(ptr);
testservice.ByteArray bytes = new testservice.ByteArray();
byte[] somebytes = new byte[arraysize];
Marshal.Copy(interopPtr, somebytes, 0, arraysize);
bytes.theArray = somebytes;
CalculatorClient client = generateClient();
client.takeArray(ref bytes);
client.Close();
if (arraysize < bytes.theArray.Length)
{
interopPtr = Marshal.ReAllocCoTaskMem(interopPtr, bytes.theArray.Length);//TODO : throws an exception if fails... deal with it
}
Marshal.Copy(bytes.theArray, 0, interopPtr, bytes.theArray.Length);
ptr = interopPtr.ToInt64();
arraysize = bytes.theArray.Length;
//TODO : do we need to free IntPtr? check all code for memory leaks... check for successful allocation
}
catch(Exception e)
{
return 3;
}
return 2;
}
Извините, но у меня нет времени, чтобы разработать все это и объяснить это правильно, надо надеяться, это даст Вам подсказки в правильном направлении, по крайней мере некоторые вещи погуглить.Удачи
PS: Я заставил всю информацию писать этот материал от сети, таким образом, это там.
Я думаю, что могу использовать C ++\CLI DLL для внешнего приложения поэтому, если это будет легче, чем прямой COM затем, то я буду готов посмотреть на это.
Если у Вас не будет большого опыта COM (и массивы значительно не просты в COM), затем, то C++ / обертка CLI вокруг третьей стороны, вероятно, будет легче.
Это также только включит единственный этап маршалинга (собственный компонент <-> управляемый), а не дополнительный шаг необходимая Обертка для COM-вызовов, в которой Вы будете нуждаться для управляемого <-> COM, взаимодействующий через интерфейс).
Это тоже сработает?
В C # 1. Позвоните в Marshal.PtrToStructure. 2. Измените значение 3. Позвоните в Marshal.StructureToPtr
.