mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-14 21:45:14 -05:00
implement GUI for NetFtpStorage
store user/password for ftp connection in "path" string for compatiblity with file chooser
This commit is contained in:
parent
fe3da55e0d
commit
113d693f7a
@ -87,22 +87,45 @@ namespace keepass2android.Io
|
||||
{
|
||||
public FtpEncryptionMode EncryptionMode {get; set; }
|
||||
|
||||
public string Username
|
||||
{
|
||||
get;set;
|
||||
}
|
||||
public string Password
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public static ConnectionSettings FromIoc(IOConnectionInfo ioc)
|
||||
{
|
||||
string path = ioc.Path;
|
||||
int schemeLength = path.IndexOf("://", StringComparison.Ordinal);
|
||||
path = path.Substring(schemeLength + 3);
|
||||
string settings = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal));
|
||||
string settings = path.Substring(0, path.IndexOf(SettingsPostFix, StringComparison.Ordinal));
|
||||
if (!settings.StartsWith(SettingsPrefix))
|
||||
throw new Exception("unexpected settings in path");
|
||||
settings = settings.Substring(SettingsPrefix.Length);
|
||||
var tokens = settings.Split(Separator);
|
||||
return new ConnectionSettings()
|
||||
{
|
||||
EncryptionMode = (FtpEncryptionMode) int.Parse(settings)
|
||||
EncryptionMode = (FtpEncryptionMode) int.Parse(tokens[2]),
|
||||
Username = tokens[0],
|
||||
Password = tokens[1]
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public string ToString()
|
||||
public const string SettingsPrefix = "SET";
|
||||
public const string SettingsPostFix = "%";
|
||||
public const char Separator = ':';
|
||||
public override string ToString()
|
||||
{
|
||||
return ((int) EncryptionMode).ToString();
|
||||
return SettingsPrefix +
|
||||
System.Net.WebUtility.UrlEncode(Username) + Separator +
|
||||
WebUtility.UrlEncode(Password) + Separator +
|
||||
(int) EncryptionMode;
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +143,10 @@ namespace keepass2android.Io
|
||||
|
||||
public IEnumerable<string> SupportedProtocols
|
||||
{
|
||||
get { yield return "ftp"; }
|
||||
get
|
||||
{
|
||||
yield return "ftp";
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
@ -160,9 +186,11 @@ namespace keepass2android.Io
|
||||
|
||||
internal FtpClient GetClient(IOConnectionInfo ioc, bool enableCloneClient = true)
|
||||
{
|
||||
var settings = ConnectionSettings.FromIoc(ioc);
|
||||
|
||||
FtpClient client = new RetryConnectFtpClient();
|
||||
if ((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
|
||||
client.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
|
||||
if ((settings.Username.Length > 0) || (settings.Password.Length > 0))
|
||||
client.Credentials = new NetworkCredential(settings.Username, settings.Password);
|
||||
else
|
||||
client.Credentials = new NetworkCredential("anonymous", ""); //TODO TEST
|
||||
|
||||
@ -176,7 +204,7 @@ namespace keepass2android.Io
|
||||
args.Accept = _app.CertificateValidationCallback(control, args.Certificate, args.Chain, args.PolicyErrors);
|
||||
};
|
||||
|
||||
client.EncryptionMode = ConnectionSettings.FromIoc(ioc).EncryptionMode;
|
||||
client.EncryptionMode = settings.EncryptionMode;
|
||||
|
||||
client.Connect();
|
||||
return client;
|
||||
@ -192,7 +220,7 @@ namespace keepass2android.Io
|
||||
int schemeLength = path.IndexOf("://", StringComparison.Ordinal);
|
||||
string scheme = path.Substring(0, schemeLength);
|
||||
path = path.Substring(schemeLength + 3);
|
||||
string settings = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal));
|
||||
string settings = path.Substring(0, path.IndexOf(ConnectionSettings.SettingsPostFix, StringComparison.Ordinal));
|
||||
path = path.Substring(settings.Length + 1);
|
||||
return new Uri(scheme + "://" + path);
|
||||
}
|
||||
@ -203,10 +231,10 @@ namespace keepass2android.Io
|
||||
int schemeLength = basePath.IndexOf("://", StringComparison.Ordinal);
|
||||
string scheme = basePath.Substring(0, schemeLength);
|
||||
basePath = basePath.Substring(schemeLength + 3);
|
||||
string baseSettings = basePath.Substring(0, basePath.IndexOf("/", StringComparison.Ordinal));
|
||||
string baseSettings = basePath.Substring(0, basePath.IndexOf(ConnectionSettings.SettingsPostFix, StringComparison.Ordinal));
|
||||
basePath = basePath.Substring(baseSettings.Length+1);
|
||||
string baseHost = basePath.Substring(0, basePath.IndexOf("/", StringComparison.Ordinal));
|
||||
return scheme + "://" + baseSettings + "/" + baseHost + uri.AbsolutePath; //TODO does this contain Query?
|
||||
return scheme + "://" + baseSettings + ConnectionSettings.SettingsPostFix + baseHost + uri.AbsolutePath; //TODO does this contain Query?
|
||||
}
|
||||
|
||||
|
||||
@ -261,7 +289,7 @@ namespace keepass2android.Io
|
||||
|
||||
public bool RequiresCredentials(IOConnectionInfo ioc)
|
||||
{
|
||||
return ioc.CredSaveMode != IOCredSaveMode.SaveCred;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CreateDirectory(IOConnectionInfo ioc, string newDirName)
|
||||
@ -340,16 +368,19 @@ namespace keepass2android.Io
|
||||
|
||||
var uri = IocPathToUri(ioc.Path);
|
||||
string path = uri.PathAndQuery;
|
||||
return new FileDescription()
|
||||
if (!client.FileExists(path) && (!client.DirectoryExists(path)))
|
||||
throw new FileNotFoundException();
|
||||
var fileDesc = new FileDescription()
|
||||
{
|
||||
CanRead = true,
|
||||
CanWrite = true,
|
||||
Path = ioc.Path,
|
||||
LastModified = client.GetModifiedTime(path),
|
||||
SizeInBytes = client.GetFileSize(path),
|
||||
DisplayName = UrlUtil.GetFileName(path),
|
||||
IsDirectory = false
|
||||
DisplayName = UrlUtil.GetFileName(path)
|
||||
};
|
||||
fileDesc.IsDirectory = fileDesc.Path.EndsWith("/");
|
||||
return fileDesc;
|
||||
}
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
@ -457,6 +488,34 @@ namespace keepass2android.Io
|
||||
throw ConvertException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetDefaultPort(FtpEncryptionMode encryption)
|
||||
{
|
||||
return new FtpClient() { EncryptionMode = encryption}.Port;
|
||||
}
|
||||
|
||||
public string BuildFullPath(string host, int port, string initialPath, string user, string password, FtpEncryptionMode encryption)
|
||||
{
|
||||
var connectionSettings = new ConnectionSettings()
|
||||
{
|
||||
EncryptionMode = encryption,
|
||||
Username = user,
|
||||
Password = password
|
||||
};
|
||||
|
||||
string scheme = "ftp";
|
||||
|
||||
string fullPath = scheme + "://" + connectionSettings.ToString() + ConnectionSettings.SettingsPostFix + host;
|
||||
if (port != GetDefaultPort(encryption))
|
||||
fullPath += ":" + port;
|
||||
|
||||
if (!initialPath.StartsWith("/"))
|
||||
initialPath = "/" + initialPath;
|
||||
fullPath += initialPath;
|
||||
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TransactedWrite : IWriteTransaction
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.FtpClient;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
@ -62,13 +63,49 @@ namespace keepass2android
|
||||
#endif
|
||||
}
|
||||
|
||||
private void ShowFtpDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel)
|
||||
{
|
||||
#if !NoNet
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.ftpcredentials, null);
|
||||
builder.SetView(dlgContents);
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok,
|
||||
(sender, args) =>
|
||||
{
|
||||
string host = dlgContents.FindViewById<EditText>(Resource.Id.ftp_host).Text;
|
||||
string portText = dlgContents.FindViewById<EditText>(Resource.Id.ftp_port).Text;
|
||||
FtpEncryptionMode encryption =
|
||||
(FtpEncryptionMode) dlgContents.FindViewById<Spinner>(Resource.Id.ftp_encryption).SelectedItemPosition;
|
||||
int port = NetFtpFileStorage.GetDefaultPort(encryption);
|
||||
if (!string.IsNullOrEmpty(portText))
|
||||
int.TryParse(portText, out port);
|
||||
string user = dlgContents.FindViewById<EditText>(Resource.Id.ftp_user).Text;
|
||||
string password = dlgContents.FindViewById<EditText>(Resource.Id.ftp_password).Text;
|
||||
string initialPath = dlgContents.FindViewById<EditText>(Resource.Id.ftp_initial_dir).Text;
|
||||
string ftpPath = new NetFtpFileStorage(_activity, App.Kp2a).BuildFullPath(host, port, initialPath, user,
|
||||
password, encryption);
|
||||
onStartBrowse(ftpPath);
|
||||
});
|
||||
EventHandler<DialogClickEventArgs> evtH = new EventHandler<DialogClickEventArgs>((sender, e) => onCancel());
|
||||
|
||||
builder.SetNegativeButton(Android.Resource.String.Cancel, evtH);
|
||||
builder.SetTitle(activity.GetString(Resource.String.enter_sftp_login_title));
|
||||
Dialog dialog = builder.Create();
|
||||
|
||||
dialog.Show();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public void PerformManualFileSelect(string defaultPath)
|
||||
{
|
||||
if (defaultPath.StartsWith("sftp://"))
|
||||
ShowSftpDialog(_activity, StartFileChooser, ReturnCancel);
|
||||
else if ((defaultPath.StartsWith("ftp://")) || (defaultPath.StartsWith("ftps://")))
|
||||
ShowFtpDialog(_activity, StartFileChooser, ReturnCancel);
|
||||
else
|
||||
{
|
||||
Func<string, Dialog, bool> onOpen = (filename, dialog) => OnOpenButton(filename, dialog);
|
||||
Func<string, Dialog, bool> onOpen = OnOpenButton;
|
||||
Util.ShowFilenameDialog(_activity,
|
||||
!_isForSave ? onOpen : null,
|
||||
_isForSave ? onOpen : null,
|
||||
@ -202,7 +239,6 @@ namespace keepass2android
|
||||
public bool StartFileChooser(string defaultPath)
|
||||
{
|
||||
#if !EXCLUDE_FILECHOOSER
|
||||
Kp2aLog.Log("FSA: defaultPath=" + defaultPath);
|
||||
string fileProviderAuthority = FileChooserFileProvider.TheAuthority;
|
||||
if (defaultPath.StartsWith("file://"))
|
||||
{
|
||||
|
@ -40,46 +40,46 @@ namespace keepass2android
|
||||
|
||||
private readonly FileStorageSelectionActivity _context;
|
||||
|
||||
private readonly List<string> _protocolIds = new List<string>();
|
||||
private readonly List<string> _displayedProtocolIds = new List<string>();
|
||||
|
||||
public FileStorageAdapter(FileStorageSelectionActivity context)
|
||||
{
|
||||
_context = context;
|
||||
//show all supported protocols:
|
||||
foreach (IFileStorage fs in App.Kp2a.FileStorages)
|
||||
_protocolIds.AddRange(fs.SupportedProtocols);
|
||||
_displayedProtocolIds.AddRange(fs.SupportedProtocols);
|
||||
|
||||
//special handling for local files:
|
||||
if (!Util.IsKitKatOrLater)
|
||||
{
|
||||
//put file:// to the top
|
||||
_protocolIds.Remove("file");
|
||||
_protocolIds.Insert(0, "file");
|
||||
_displayedProtocolIds.Remove("file");
|
||||
_displayedProtocolIds.Insert(0, "file");
|
||||
|
||||
//remove "content" (covered by androidget)
|
||||
//On KitKat, content is handled by AndroidContentStorage taking advantage
|
||||
//of persistable permissions and ACTION_OPEN/CREATE_DOCUMENT
|
||||
_protocolIds.Remove("content");
|
||||
_displayedProtocolIds.Remove("content");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_protocolIds.Remove("file");
|
||||
_displayedProtocolIds.Remove("file");
|
||||
}
|
||||
|
||||
|
||||
if (context.Intent.GetBooleanExtra(AllowThirdPartyAppGet, false))
|
||||
_protocolIds.Add("androidget");
|
||||
_displayedProtocolIds.Add("androidget");
|
||||
if (context.Intent.GetBooleanExtra(AllowThirdPartyAppSend, false))
|
||||
_protocolIds.Add("androidsend");
|
||||
_displayedProtocolIds.Add("androidsend");
|
||||
#if NoNet
|
||||
_protocolIds.Add("kp2a");
|
||||
_displayedProtocolIds.Add("kp2a");
|
||||
#endif
|
||||
}
|
||||
|
||||
public override Object GetItem(int position)
|
||||
{
|
||||
return _protocolIds[position];
|
||||
return _displayedProtocolIds[position];
|
||||
}
|
||||
|
||||
public override long GetItemId(int position)
|
||||
@ -121,7 +121,7 @@ namespace keepass2android
|
||||
btn = (Button)convertView;
|
||||
}
|
||||
|
||||
var protocolId = _protocolIds[position];
|
||||
var protocolId = _displayedProtocolIds[position];
|
||||
btn.Tag = protocolId;
|
||||
|
||||
|
||||
@ -143,7 +143,7 @@ namespace keepass2android
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get { return _protocolIds.Count; }
|
||||
get { return _displayedProtocolIds.Count; }
|
||||
}
|
||||
}
|
||||
|
||||
|
75
src/keepass2android/Resources/layout/ftpcredentials.xml
Normal file
75
src/keepass2android/Resources/layout/ftpcredentials.xml
Normal file
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="12dip"
|
||||
>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/ftp_host"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="85.13.147.153"
|
||||
android:layout_weight="1"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:hint="@string/hint_sftp_host" />
|
||||
<TextView
|
||||
android:id="@+id/portsep"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=":" />
|
||||
<EditText
|
||||
android:id="@+id/ftp_port"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="4"
|
||||
android:singleLine="true"
|
||||
android:inputType="number"
|
||||
android:text=""
|
||||
android:hint="@string/hint_sftp_port" />
|
||||
</LinearLayout>
|
||||
<Spinner
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/ftp_encryption_modes"
|
||||
android:id="@+id/ftp_encryption" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/ftp_user"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="f00c530c"
|
||||
android:hint="@string/hint_username" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/ftp_password"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword"
|
||||
android:text="2C4vsSt8MhNEaqv5"
|
||||
android:singleLine="true"
|
||||
android:hint="@string/hint_pass" />
|
||||
|
||||
<TextView android:id="@+id/initial_dir"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:layout_marginTop="4dip"
|
||||
android:text="@string/initial_directory" />
|
||||
<EditText
|
||||
android:id="@+id/ftp_initial_dir"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="/"
|
||||
/>
|
||||
|
||||
|
||||
</LinearLayout>
|
@ -944,8 +944,12 @@ Initial public release
|
||||
</string-array>
|
||||
|
||||
<string name="design_title">Design</string>
|
||||
|
||||
<string-array name="cred_remember_modes">
|
||||
<string-array name="ftp_encryption_modes">
|
||||
<item>No encryption (FTP)</item>
|
||||
<item>Implicit encryption (FTP over TLS, FTPS)</item>
|
||||
<item>Explicit encryption (FTP over TLS, FTPS)</item>
|
||||
</string-array>
|
||||
<string-array name="cred_remember_modes">
|
||||
<item>Do not remember username and password</item>
|
||||
<item>Remember username only</item>
|
||||
<item>Remember username and password</item>
|
||||
|
@ -319,36 +319,7 @@ namespace keepass2android
|
||||
|
||||
public delegate bool FileSelectedHandler(string filename);
|
||||
|
||||
public static void ShowSftpDialog(Activity activity, FileSelectedHandler onStartBrowse, Action onCancel)
|
||||
{
|
||||
#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.sftpcredentials, null);
|
||||
builder.SetView(dlgContents);
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok,
|
||||
(sender, args) =>
|
||||
{
|
||||
string host = dlgContents.FindViewById<EditText>(Resource.Id.sftp_host).Text;
|
||||
string portText = dlgContents.FindViewById<EditText>(Resource.Id.sftp_port).Text;
|
||||
int port = Keepass2android.Javafilestorage.SftpStorage.DefaultSftpPort;
|
||||
if (!string.IsNullOrEmpty(portText))
|
||||
int.TryParse(portText, out port);
|
||||
string user = dlgContents.FindViewById<EditText>(Resource.Id.sftp_user).Text;
|
||||
string password = dlgContents.FindViewById<EditText>(Resource.Id.sftp_password).Text;
|
||||
string initialPath = dlgContents.FindViewById<EditText>(Resource.Id.sftp_initial_dir).Text;
|
||||
string sftpPath = new Keepass2android.Javafilestorage.SftpStorage().BuildFullPath(host, port, initialPath, user,
|
||||
password);
|
||||
onStartBrowse(sftpPath);
|
||||
});
|
||||
EventHandler<DialogClickEventArgs> evtH = new EventHandler<DialogClickEventArgs>( (sender, e) => onCancel());
|
||||
|
||||
builder.SetNegativeButton(Android.Resource.String.Cancel, evtH);
|
||||
builder.SetTitle(activity.GetString(Resource.String.enter_sftp_login_title));
|
||||
Dialog dialog = builder.Create();
|
||||
|
||||
dialog.Show();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public class DismissListener: Java.Lang.Object, IDialogInterfaceOnDismissListener
|
||||
{
|
||||
|
@ -511,7 +511,7 @@ namespace keepass2android
|
||||
new GoogleDriveFileStorage(Application.Context, this),
|
||||
new SkyDriveFileStorage(Application.Context, this),
|
||||
new SftpFileStorage(this),
|
||||
new NetFtpFileStorage(Application.Context),
|
||||
new NetFtpFileStorage(Application.Context, this),
|
||||
#endif
|
||||
#endif
|
||||
new LocalFileStorage(this)
|
||||
@ -684,7 +684,7 @@ namespace keepass2android
|
||||
|
||||
public void ClearOfflineCache()
|
||||
{
|
||||
new CachingFileStorage(new BuiltInFileStorage(this), Application.Context.CacheDir.Path, this).ClearCache();
|
||||
new CachingFileStorage(new LocalFileStorage(this), Application.Context.CacheDir.Path, this).ClearCache();
|
||||
}
|
||||
|
||||
public IFileStorage GetFileStorage(string protocolId)
|
||||
@ -700,7 +700,7 @@ namespace keepass2android
|
||||
{
|
||||
|
||||
if (iocInfo.IsLocalFile())
|
||||
return new BuiltInFileStorage(this);
|
||||
return new LocalFileStorage(this);
|
||||
else
|
||||
{
|
||||
IFileStorage innerFileStorage = GetCloudFileStorage(iocInfo);
|
||||
|
@ -66,7 +66,6 @@ namespace keepass2android
|
||||
{
|
||||
try
|
||||
{
|
||||
Kp2aLog.Log("Provider.GetFileEntry " + filename);
|
||||
return ConvertFileDescription(App.Kp2a.GetFileStorage(filename).GetFileDescription(ConvertPathToIoc(filename)));
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -80,14 +79,12 @@ namespace keepass2android
|
||||
protected override void ListFiles(int taskId, string dirName, bool showHiddenFiles, int filterMode, int limit, string positiveRegex,
|
||||
string negativeRegex, IList<FileEntry> fileList, bool[] hasMoreFiles)
|
||||
{
|
||||
Kp2aLog.Log("Provider.ListFiles " + dirName);
|
||||
try
|
||||
{
|
||||
var dirContents = App.Kp2a.GetFileStorage(dirName).ListContents(ConvertPathToIoc(dirName));
|
||||
foreach (FileDescription e in dirContents)
|
||||
{
|
||||
fileList.Add(ConvertFileDescription(e)
|
||||
);
|
||||
fileList.Add(ConvertFileDescription(e));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -678,7 +678,9 @@
|
||||
<AndroidResource Include="Resources\layout\QuickUnlock.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
<AndroidResource Include="Resources\layout\url_credentials.xml" />
|
||||
<AndroidResource Include="Resources\layout\url_credentials.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
<AndroidResource Include="Resources\drawable\section_header.xml" />
|
||||
<AndroidResource Include="Resources\drawable\extra_string_header.xml" />
|
||||
<AndroidResource Include="Resources\layout\entry_edit_section.xml">
|
||||
@ -771,6 +773,10 @@
|
||||
<Project>{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}</Project>
|
||||
<Name>Kp2aKeyboardBinding</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj">
|
||||
<Project>{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}</Project>
|
||||
<Name>System.Net.FtpClient.Android</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PluginSdkBinding\PluginSdkBinding.csproj">
|
||||
<Project>{3DA3911E-36DE-465E-8F15-F1991B6437E5}</Project>
|
||||
<Name>PluginSdkBinding</Name>
|
||||
@ -1683,6 +1689,11 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_fp_40px.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\ftpcredentials.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\packages\Xamarin.Insights.1.11.3\build\MonoAndroid10\Xamarin.Insights.targets" Condition="Exists('..\packages\Xamarin.Insights.1.11.3\build\MonoAndroid10\Xamarin.Insights.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
Loading…
Reference in New Issue
Block a user