Add PCloud support.
This commit is contained in:
@@ -81,6 +81,9 @@
|
|||||||
<Visible>False</Visible>
|
<Visible>False</Visible>
|
||||||
</XamarinComponentReference>
|
</XamarinComponentReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedReferenceJar Include="Jars\okhttp-digest-1.7.jar" />
|
<EmbeddedReferenceJar Include="Jars\okhttp-digest-1.7.jar" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -150,4 +153,4 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedReferenceJar Include="Jars\okio-1.13.0.jar" />
|
<EmbeddedReferenceJar Include="Jars\okio-1.13.0.jar" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.FtpClient.Androi
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCloudBindings", "PCloudBindings\PCloudBindings.csproj", "{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -283,6 +285,16 @@ Global
|
|||||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.Build.0 = Release|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
23
src/Kp2aBusinessLogic/Io/PCloudFileStorage.cs
Normal file
23
src/Kp2aBusinessLogic/Io/PCloudFileStorage.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Android.Content;
|
||||||
|
#if !EXCLUDE_JAVAFILESTORAGE
|
||||||
|
|
||||||
|
namespace keepass2android.Io
|
||||||
|
{
|
||||||
|
public partial class PCloudFileStorage: JavaFileStorage
|
||||||
|
{
|
||||||
|
private const string ClientId = "CkRWTQXY6Lm";
|
||||||
|
|
||||||
|
public PCloudFileStorage(Context ctx, IKp2aApp app) :
|
||||||
|
base(new Keepass2android.Javafilestorage.PCloudFileStorage(ctx, ClientId), app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override bool UserShouldBackup
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
@@ -117,6 +117,7 @@
|
|||||||
<Compile Include="Io\JavaFileStorage.cs" />
|
<Compile Include="Io\JavaFileStorage.cs" />
|
||||||
<Compile Include="Io\NetFtpFileStorage.cs" />
|
<Compile Include="Io\NetFtpFileStorage.cs" />
|
||||||
<Compile Include="Io\OfflineSwitchableFileStorage.cs" />
|
<Compile Include="Io\OfflineSwitchableFileStorage.cs" />
|
||||||
|
<Compile Include="Io\PCloudFileStorage.cs" />
|
||||||
<Compile Include="Io\SftpFileStorage.cs" />
|
<Compile Include="Io\SftpFileStorage.cs" />
|
||||||
<Compile Include="Io\OneDriveFileStorage.cs" />
|
<Compile Include="Io\OneDriveFileStorage.cs" />
|
||||||
<Compile Include="Io\WebDavFileStorage.cs" />
|
<Compile Include="Io\WebDavFileStorage.cs" />
|
||||||
@@ -215,4 +216,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
48
src/PCloudBindings/Additions/AboutAdditions.txt
Normal file
48
src/PCloudBindings/Additions/AboutAdditions.txt
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
Additions allow you to add arbitrary C# to the generated classes
|
||||||
|
before they are compiled. This can be helpful for providing convenience
|
||||||
|
methods or adding pure C# classes.
|
||||||
|
|
||||||
|
== Adding Methods to Generated Classes ==
|
||||||
|
|
||||||
|
Let's say the library being bound has a Rectangle class with a constructor
|
||||||
|
that takes an x and y position, and a width and length size. It will look like
|
||||||
|
this:
|
||||||
|
|
||||||
|
public partial class Rectangle
|
||||||
|
{
|
||||||
|
public Rectangle (int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
// JNI bindings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Imagine we want to add a constructor to this class that takes a Point and
|
||||||
|
Size structure instead of 4 ints. We can add a new file called Rectangle.cs
|
||||||
|
with a partial class containing our new method:
|
||||||
|
|
||||||
|
public partial class Rectangle
|
||||||
|
{
|
||||||
|
public Rectangle (Point location, Size size) :
|
||||||
|
this (location.X, location.Y, size.Width, size.Height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
At compile time, the additions class will be added to the generated class
|
||||||
|
and the final assembly will a Rectangle class with both constructors.
|
||||||
|
|
||||||
|
|
||||||
|
== Adding C# Classes ==
|
||||||
|
|
||||||
|
Another thing that can be done is adding fully C# managed classes to the
|
||||||
|
generated library. In the above example, let's assume that there isn't a
|
||||||
|
Point class available in Java or our library. The one we create doesn't need
|
||||||
|
to interact with Java, so we'll create it like a normal class in C#.
|
||||||
|
|
||||||
|
By adding a Point.cs file with this class, it will end up in the binding library:
|
||||||
|
|
||||||
|
public class Point
|
||||||
|
{
|
||||||
|
public int X { get; set; }
|
||||||
|
public int Y { get; set; }
|
||||||
|
}
|
24
src/PCloudBindings/Jars/AboutJars.txt
Normal file
24
src/PCloudBindings/Jars/AboutJars.txt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
This directory is for Android .jars.
|
||||||
|
|
||||||
|
There are 2 types of jars that are supported:
|
||||||
|
|
||||||
|
== Input Jar ==
|
||||||
|
|
||||||
|
This is the jar that bindings should be generated for.
|
||||||
|
|
||||||
|
For example, if you were binding the Google Maps library, this would
|
||||||
|
be Google's "maps.jar".
|
||||||
|
|
||||||
|
Set the build action for these jars in the properties page to "InputJar".
|
||||||
|
|
||||||
|
|
||||||
|
== Reference Jars ==
|
||||||
|
|
||||||
|
These are jars that are referenced by the input jar. C# bindings will
|
||||||
|
not be created for these jars. These jars will be used to resolve
|
||||||
|
types used by the input jar.
|
||||||
|
|
||||||
|
NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
|
||||||
|
based on the Target Framework selected.
|
||||||
|
|
||||||
|
Set the build action for these jars in the properties page to "ReferenceJar".
|
BIN
src/PCloudBindings/Jars/pcloud-sdk-android-1.0.1.aar
Normal file
BIN
src/PCloudBindings/Jars/pcloud-sdk-android-1.0.1.aar
Normal file
Binary file not shown.
BIN
src/PCloudBindings/Jars/pcloud-sdk-java-core-1.0.1.jar
Normal file
BIN
src/PCloudBindings/Jars/pcloud-sdk-java-core-1.0.1.jar
Normal file
Binary file not shown.
75
src/PCloudBindings/PCloudBindings.csproj
Normal file
75
src/PCloudBindings/PCloudBindings.csproj
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{6322E8A7-5C46-4E8C-8B19-448B7BC95DC1};{E1126D83-ADAB-4E4F-81F7-4B0A645A68C7}</ProjectTypeGuids>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>PCloudBindings</RootNamespace>
|
||||||
|
<AssemblyName>PCouldBindings</AssemblyName>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||||
|
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>0</WarningLevel>
|
||||||
|
<AndroidLinkMode>None</AndroidLinkMode>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseNoNet|AnyCPU'">
|
||||||
|
<OutputPath>bin\ReleaseNoNet\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Mono.Android" />
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Jars\AboutJars.txt" />
|
||||||
|
<None Include="Additions\AboutAdditions.txt" />
|
||||||
|
<LibraryProjectZip Include="Jars\pcloud-sdk-android-1.0.1.aar" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<TransformFile Include="Transforms\Metadata.xml" />
|
||||||
|
<TransformFile Include="Transforms\EnumFields.xml" />
|
||||||
|
<TransformFile Include="Transforms\EnumMethods.xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedReferenceJar Include="Jars\pcloud-sdk-java-core-1.0.1.jar" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
30
src/PCloudBindings/Properties/AssemblyInfo.cs
Normal file
30
src/PCloudBindings/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Android.App;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("PCloudBindings")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("PCloudBindings")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
14
src/PCloudBindings/Transforms/EnumFields.xml
Normal file
14
src/PCloudBindings/Transforms/EnumFields.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<enum-field-mappings>
|
||||||
|
<!--
|
||||||
|
This example converts the constants Fragment_id, Fragment_name,
|
||||||
|
and Fragment_tag from android.support.v4.app.FragmentActivity.FragmentTag
|
||||||
|
to an enum called Android.Support.V4.App.FragmentTagType with values
|
||||||
|
Id, Name, and Tag.
|
||||||
|
|
||||||
|
<mapping jni-class="android/support/v4/app/FragmentActivity$FragmentTag" clr-enum-type="Android.Support.V4.App.FragmentTagType">
|
||||||
|
<field jni-name="Fragment_name" clr-name="Name" value="0" />
|
||||||
|
<field jni-name="Fragment_id" clr-name="Id" value="1" />
|
||||||
|
<field jni-name="Fragment_tag" clr-name="Tag" value="2" />
|
||||||
|
</mapping>
|
||||||
|
-->
|
||||||
|
</enum-field-mappings>
|
13
src/PCloudBindings/Transforms/EnumMethods.xml
Normal file
13
src/PCloudBindings/Transforms/EnumMethods.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<enum-method-mappings>
|
||||||
|
<!--
|
||||||
|
This example changes the Java method:
|
||||||
|
android.support.v4.app.Fragment.SavedState.writeToParcel (int flags)
|
||||||
|
to be:
|
||||||
|
android.support.v4.app.Fragment.SavedState.writeToParcel (Android.OS.ParcelableWriteFlags flags)
|
||||||
|
when bound in C#.
|
||||||
|
|
||||||
|
<mapping jni-class="android/support/v4/app/Fragment.SavedState">
|
||||||
|
<method jni-name="writeToParcel" parameter="flags" clr-enum-type="Android.OS.ParcelableWriteFlags" />
|
||||||
|
</mapping>
|
||||||
|
-->
|
||||||
|
</enum-method-mappings>
|
9
src/PCloudBindings/Transforms/Metadata.xml
Normal file
9
src/PCloudBindings/Transforms/Metadata.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<metadata>
|
||||||
|
<!--
|
||||||
|
This sample removes the class: android.support.v4.content.AsyncTaskLoader.LoadTask:
|
||||||
|
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='AsyncTaskLoader.LoadTask']" />
|
||||||
|
|
||||||
|
This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
|
||||||
|
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
|
||||||
|
-->
|
||||||
|
</metadata>
|
@@ -35,6 +35,8 @@ dependencies {
|
|||||||
compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
|
compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
|
||||||
transitive = false
|
transitive = false
|
||||||
}
|
}
|
||||||
|
compile 'com.pcloud.sdk:java-core:1.0.1'
|
||||||
|
compile 'com.pcloud.sdk:android:1.0.1'
|
||||||
compile 'com.google.code.gson:gson:2.3.1'
|
compile 'com.google.code.gson:gson:2.3.1'
|
||||||
compile 'com.microsoft.services.msa:msa-auth:0.8.6'
|
compile 'com.microsoft.services.msa:msa-auth:0.8.6'
|
||||||
compile 'com.microsoft.aad:adal:1.14.0'
|
compile 'com.microsoft.aad:adal:1.14.0'
|
||||||
|
@@ -132,7 +132,7 @@ public class FileEntry {
|
|||||||
|
|
||||||
public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception;
|
public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception;
|
||||||
|
|
||||||
public String getCurrentFileVersionFast(String path);
|
public String getCurrentFileVersionFast(String path) throws Exception;
|
||||||
|
|
||||||
public InputStream openFileForRead(String path) throws Exception;
|
public InputStream openFileForRead(String path) throws Exception;
|
||||||
|
|
||||||
@@ -157,4 +157,4 @@ public class FileEntry {
|
|||||||
public void onActivityResult(FileStorageSetupActivity activity, int requestCode, int resultCode, Intent data);
|
public void onActivityResult(FileStorageSetupActivity activity, int requestCode, int resultCode, Intent data);
|
||||||
public void onRequestPermissionsResult(FileStorageSetupActivity activity, int requestCode, String[] permissions, int[] grantResults);
|
public void onRequestPermissionsResult(FileStorageSetupActivity activity, int requestCode, String[] permissions, int[] grantResults);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,402 @@
|
|||||||
|
package keepass2android.javafilestorage;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.pcloud.sdk.ApiClient;
|
||||||
|
import com.pcloud.sdk.ApiError;
|
||||||
|
import com.pcloud.sdk.Authenticators;
|
||||||
|
import com.pcloud.sdk.AuthorizationActivity;
|
||||||
|
import com.pcloud.sdk.AuthorizationResult;
|
||||||
|
import com.pcloud.sdk.Call;
|
||||||
|
import com.pcloud.sdk.DataSource;
|
||||||
|
import com.pcloud.sdk.PCloudSdk;
|
||||||
|
import com.pcloud.sdk.RemoteEntry;
|
||||||
|
import com.pcloud.sdk.RemoteFile;
|
||||||
|
import com.pcloud.sdk.RemoteFolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileStorage implementation for PCloud provider.
|
||||||
|
* https://www.pcloud.com/
|
||||||
|
*/
|
||||||
|
public class PCloudFileStorage extends JavaFileStorageBase
|
||||||
|
{
|
||||||
|
final static private int PCLOUD_AUTHORIZATION_REQUEST_CODE = 1001845497;
|
||||||
|
|
||||||
|
final static private String SHARED_PREF_NAME = "PCLOUD";
|
||||||
|
final static private String SHARED_PREF_AUTH_TOKEN = "AUTH_TOKEN";
|
||||||
|
|
||||||
|
private final Context ctx;
|
||||||
|
|
||||||
|
private ApiClient apiClient;
|
||||||
|
private String clientId;
|
||||||
|
|
||||||
|
public PCloudFileStorage(Context ctx, String clientId) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.apiClient = createApiClientFromSharedPrefs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresSetup(String path) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startSelectFile(FileStorageSetupInitiatorActivity activity, boolean isForSave, int requestCode) {
|
||||||
|
String path = getProtocolId() + "://";
|
||||||
|
activity.startSelectFileProcess(path, isForSave, requestCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareFileUsage(Context appContext, String path) throws Throwable {
|
||||||
|
if (!isConnected()) {
|
||||||
|
throw new UserInteractionRequiredException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepareFileUsage(FileStorageSetupInitiatorActivity activity, String path, int requestCode, boolean alwaysReturnSuccess) {
|
||||||
|
if (isConnected()) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(EXTRA_PATH, path);
|
||||||
|
activity.onImmediateResult(requestCode, RESULT_FILEUSAGE_PREPARED, intent);
|
||||||
|
} else {
|
||||||
|
activity.startFileUsageProcess(path, requestCode, alwaysReturnSuccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProtocolId() {
|
||||||
|
return "pcloud";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName(String path) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFilename(String path) {
|
||||||
|
return path.substring(path.lastIndexOf("/") + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception {
|
||||||
|
if (previousFileVersion == null || "".equals(previousFileVersion)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = this.cleanPath(path);
|
||||||
|
|
||||||
|
RemoteFile remoteFile = this.getRemoteFileByPath(path);
|
||||||
|
|
||||||
|
return !remoteFile.hash().equals(previousFileVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCurrentFileVersionFast(String path) throws Exception {
|
||||||
|
path = this.cleanPath(path);
|
||||||
|
|
||||||
|
RemoteFile remoteFile = this.getRemoteFileByPath(path);
|
||||||
|
|
||||||
|
return remoteFile.hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream openFileForRead(String path) throws Exception {
|
||||||
|
path = this.cleanPath(path);
|
||||||
|
|
||||||
|
RemoteFile remoteFile = this.getRemoteFileByPath(path);
|
||||||
|
|
||||||
|
return remoteFile.byteStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uploadFile(String path, byte[] data, boolean writeTransactional) throws Exception {
|
||||||
|
path = this.cleanPath(path);
|
||||||
|
|
||||||
|
DataSource dataSource = DataSource.create(data);
|
||||||
|
String filename = path.substring(path.lastIndexOf("/") + 1);
|
||||||
|
String filePath = path.substring(0, path.lastIndexOf("/") + 1);
|
||||||
|
RemoteFolder remoteFolder = this.getRemoteFolderByPath(filePath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.apiClient.createFile(remoteFolder, filename, dataSource).execute();
|
||||||
|
} catch (ApiError e) {
|
||||||
|
throw convertApiError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createFolder(String parentPath, String newDirName) throws Exception {
|
||||||
|
String parentPathWithoutProtocol = this.cleanPath(parentPath);
|
||||||
|
|
||||||
|
RemoteFolder remoteFolder = this.getRemoteFolderByPath(parentPathWithoutProtocol);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.apiClient.createFolder(remoteFolder, newDirName).execute();
|
||||||
|
} catch (ApiError e) {
|
||||||
|
throw convertApiError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createFilePath(parentPath, newDirName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createFilePath(String parentPath, String newFileName) throws Exception {
|
||||||
|
return (
|
||||||
|
this.getProtocolId() + "://" +
|
||||||
|
this.cleanPath(parentPath) +
|
||||||
|
("".equals(newFileName) ? "" : "/") + newFileName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FileEntry> listFiles(String parentPath) throws Exception {
|
||||||
|
parentPath = this.cleanPath(parentPath);
|
||||||
|
|
||||||
|
ArrayList<FileEntry> fileEntries = new ArrayList<>();
|
||||||
|
|
||||||
|
RemoteFolder remoteFolder = this.getRemoteFolderByPath(parentPath);
|
||||||
|
|
||||||
|
for (RemoteEntry remoteEntry : remoteFolder.children()) {
|
||||||
|
fileEntries.add(this.convertRemoteEntryToFileEntry(remoteEntry, parentPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileEntry getFileEntry(String path) throws Exception {
|
||||||
|
path = this.cleanPath(path);
|
||||||
|
|
||||||
|
RemoteEntry remoteEntry = this.getRemoteEntryByPath(path);
|
||||||
|
|
||||||
|
return this.convertRemoteEntryToFileEntry(
|
||||||
|
remoteEntry,
|
||||||
|
path.substring(0, path.lastIndexOf("/"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String path) throws Exception {
|
||||||
|
path = this.cleanPath(path);
|
||||||
|
|
||||||
|
RemoteEntry remoteEntry = this.getRemoteFileByPath(path);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.apiClient.delete(remoteEntry).execute();
|
||||||
|
} catch (ApiError e) {
|
||||||
|
throw convertApiError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(FileStorageSetupActivity activity, Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume(FileStorageSetupActivity activity) {
|
||||||
|
if (activity.getProcessName().equals(PROCESS_NAME_SELECTFILE)) {
|
||||||
|
activity.getState().putString(EXTRA_PATH, activity.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isConnected()) {
|
||||||
|
finishActivityWithSuccess(activity);
|
||||||
|
} else if (!activity.getState().getBoolean("hasStartedAuth", false)) {
|
||||||
|
Activity castedActivity = (Activity)activity;
|
||||||
|
Intent authIntent = AuthorizationActivity.createIntent(castedActivity, this.clientId);
|
||||||
|
castedActivity.startActivityForResult(authIntent, PCLOUD_AUTHORIZATION_REQUEST_CODE);
|
||||||
|
activity.getState().putBoolean("hasStartedAuth", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(FileStorageSetupActivity activity, int requestCode, int resultCode, Intent data) {
|
||||||
|
if (requestCode == PCLOUD_AUTHORIZATION_REQUEST_CODE && data != null) {
|
||||||
|
activity.getState().putBoolean("hasStartedAuth", false);
|
||||||
|
AuthorizationResult result = (AuthorizationResult)(
|
||||||
|
data.getSerializableExtra(AuthorizationActivity.KEY_AUTHORIZATION_RESULT)
|
||||||
|
);
|
||||||
|
this.handleAuthResult(activity, result, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleAuthResult(FileStorageSetupActivity activity, AuthorizationResult authorizationResult,
|
||||||
|
Intent data) {
|
||||||
|
if (authorizationResult == AuthorizationResult.ACCESS_GRANTED) {
|
||||||
|
String authToken = data.getStringExtra(AuthorizationActivity.KEY_ACCESS_TOKEN);
|
||||||
|
setAuthToken(authToken);
|
||||||
|
finishActivityWithSuccess(activity);
|
||||||
|
} else {
|
||||||
|
Activity castedActivity = (Activity)activity;
|
||||||
|
Intent resultData = new Intent();
|
||||||
|
resultData.putExtra(EXTRA_ERROR_MESSAGE, "Authentication failed.");
|
||||||
|
castedActivity.setResult(Activity.RESULT_CANCELED, resultData);
|
||||||
|
castedActivity.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart(FileStorageSetupActivity activity) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiClient createApiClientFromSharedPrefs() {
|
||||||
|
SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
|
||||||
|
String authToken = prefs.getString(SHARED_PREF_AUTH_TOKEN, null);
|
||||||
|
return this.createApiClient(authToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiClient createApiClient(String authToken) {
|
||||||
|
if (authToken == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
PCloudSdk.newClientBuilder()
|
||||||
|
.authenticator(Authenticators.newOAuthAuthenticator(authToken))
|
||||||
|
.create()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isConnected() {
|
||||||
|
return (this.apiClient != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearAuthToken() {
|
||||||
|
this.apiClient = null;
|
||||||
|
SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor edit = prefs.edit();
|
||||||
|
edit.clear();
|
||||||
|
edit.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAuthToken(String authToken) {
|
||||||
|
this.apiClient = this.createApiClient(authToken);
|
||||||
|
SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor edit = prefs.edit();
|
||||||
|
edit.putString(SHARED_PREF_AUTH_TOKEN, authToken);
|
||||||
|
edit.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cleanPath(String path) {
|
||||||
|
return (
|
||||||
|
"/" + path.replaceAll("^(" + Pattern.quote(this.getProtocolId()) + "://)?/*", "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RemoteFile getRemoteFileByPath(String path) throws Exception {
|
||||||
|
RemoteEntry remoteEntry = this.getRemoteEntryByPath(path);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return remoteEntry.asFile();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
throw new FileNotFoundException(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RemoteFolder getRemoteFolderByPath(String path) throws Exception {
|
||||||
|
RemoteEntry remoteEntry = this.getRemoteEntryByPath(path);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return remoteEntry.asFolder();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
throw new FileNotFoundException(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RemoteEntry getRemoteEntryByPath(String path) throws Exception {
|
||||||
|
Call<RemoteFolder> call = this.apiClient.listFolder(RemoteFolder.ROOT_FOLDER_ID, true);
|
||||||
|
|
||||||
|
RemoteFolder folder;
|
||||||
|
try {
|
||||||
|
folder = call.execute();
|
||||||
|
} catch (ApiError apiError) {
|
||||||
|
throw convertApiError(apiError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("/".equals(path)) {
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] fileNames = path.substring(1).split("/");
|
||||||
|
RemoteFolder currentFolder = folder;
|
||||||
|
Iterator<String> fileNamesIterator = Arrays.asList(fileNames).iterator();
|
||||||
|
while (true) {
|
||||||
|
String fileName = fileNamesIterator.next();
|
||||||
|
|
||||||
|
Iterator<RemoteEntry> entryIterator = currentFolder.children().iterator();
|
||||||
|
while (true) {
|
||||||
|
RemoteEntry remoteEntry;
|
||||||
|
try {
|
||||||
|
remoteEntry = entryIterator.next();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
throw new FileNotFoundException(e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentFolder.folderId() == remoteEntry.parentFolderId() && fileName.equals(remoteEntry.name())) {
|
||||||
|
if (!fileNamesIterator.hasNext()) {
|
||||||
|
return remoteEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
currentFolder = remoteEntry.asFolder();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
throw new FileNotFoundException(e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Exception convertApiError(ApiError e) {
|
||||||
|
String strErrorCode = String.valueOf(e.errorCode());
|
||||||
|
if (strErrorCode.startsWith("1") || "2000".equals(strErrorCode)) {
|
||||||
|
this.clearAuthToken();
|
||||||
|
return new UserInteractionRequiredException("Unlinked from PCloud! User must re-link.", e);
|
||||||
|
} else if (strErrorCode.startsWith("2")) {
|
||||||
|
return new FileNotFoundException(e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileEntry convertRemoteEntryToFileEntry(RemoteEntry remoteEntry, String parentPath) {
|
||||||
|
FileEntry fileEntry = new FileEntry();
|
||||||
|
fileEntry.canRead = true;
|
||||||
|
fileEntry.canWrite = true;
|
||||||
|
fileEntry.path = (
|
||||||
|
this.getProtocolId() + "://" +
|
||||||
|
("/".equals(parentPath) ? "" : parentPath) +
|
||||||
|
"/" + remoteEntry.name()
|
||||||
|
);
|
||||||
|
fileEntry.displayName = remoteEntry.name();
|
||||||
|
fileEntry.isDirectory = !remoteEntry.isFile();
|
||||||
|
fileEntry.lastModifiedTime = remoteEntry.lastModified().getTime();
|
||||||
|
|
||||||
|
if (remoteEntry.isFile()) {
|
||||||
|
fileEntry.sizeInBytes = remoteEntry.asFile().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileEntry;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 861 B |
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
@@ -528,6 +528,7 @@
|
|||||||
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A folder)</string>
|
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A folder)</string>
|
||||||
<string name="filestoragehelp_dropboxKP2A">If you do not want to give KP2A access to your full Dropbox, you may select this option. It will request only access to the folder Apps/Keepass2Android. This is especially suited when creating a new database. If you already have a database, click this option to create the folder, then place your file inside the folder (from your PC) and then select this option again for opening the file.</string>
|
<string name="filestoragehelp_dropboxKP2A">If you do not want to give KP2A access to your full Dropbox, you may select this option. It will request only access to the folder Apps/Keepass2Android. This is especially suited when creating a new database. If you already have a database, click this option to create the folder, then place your file inside the folder (from your PC) and then select this option again for opening the file.</string>
|
||||||
<string name="filestoragename_gdrive">Google Drive</string>
|
<string name="filestoragename_gdrive">Google Drive</string>
|
||||||
|
<string name="filestoragename_pcloud">PCloud</string>
|
||||||
<string name="filestoragename_onedrive">OneDrive</string>
|
<string name="filestoragename_onedrive">OneDrive</string>
|
||||||
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
|
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
|
||||||
<string name="filestoragename_content">System file picker</string>
|
<string name="filestoragename_content">System file picker</string>
|
||||||
|
@@ -45,6 +45,7 @@ using KeePassLib.Utility;
|
|||||||
#if !NoNet
|
#if !NoNet
|
||||||
using Keepass2android.Javafilestorage;
|
using Keepass2android.Javafilestorage;
|
||||||
using GoogleDriveFileStorage = keepass2android.Io.GoogleDriveFileStorage;
|
using GoogleDriveFileStorage = keepass2android.Io.GoogleDriveFileStorage;
|
||||||
|
using PCloudFileStorage = keepass2android.Io.PCloudFileStorage;
|
||||||
#endif
|
#endif
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@@ -588,6 +589,7 @@ namespace keepass2android
|
|||||||
new SftpFileStorage(this),
|
new SftpFileStorage(this),
|
||||||
new NetFtpFileStorage(Application.Context, this),
|
new NetFtpFileStorage(Application.Context, this),
|
||||||
new WebDavFileStorage(this),
|
new WebDavFileStorage(this),
|
||||||
|
new PCloudFileStorage(Application.Context, this),
|
||||||
//new LegacyWebDavStorage(this),
|
//new LegacyWebDavStorage(this),
|
||||||
//new LegacyFtpStorage(this),
|
//new LegacyFtpStorage(this),
|
||||||
#endif
|
#endif
|
||||||
|
@@ -488,6 +488,7 @@
|
|||||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_androidsend.png" />
|
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_androidsend.png" />
|
||||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_content.png" />
|
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_content.png" />
|
||||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_dropbox.png" />
|
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_dropbox.png" />
|
||||||
|
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_pcloud.png" />
|
||||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_dropboxKP2A.png" />
|
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_dropboxKP2A.png" />
|
||||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_file.png" />
|
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_file.png" />
|
||||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_ftp.png" />
|
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_ftp.png" />
|
||||||
@@ -831,6 +832,10 @@
|
|||||||
<Project>{48574278-4779-4B3A-A9E4-9CF1BC285D0B}</Project>
|
<Project>{48574278-4779-4B3A-A9E4-9CF1BC285D0B}</Project>
|
||||||
<Name>JavaFileStorageBindings</Name>
|
<Name>JavaFileStorageBindings</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj">
|
||||||
|
<Project>{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}</Project>
|
||||||
|
<Name>PCloudBindings</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
||||||
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
|
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
|
||||||
<Name>KeePassLib2Android</Name>
|
<Name>KeePassLib2Android</Name>
|
||||||
@@ -1146,6 +1151,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_dropboxKP2A.png" />
|
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_dropboxKP2A.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_pcloud.png" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_file.png" />
|
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_file.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -1909,4 +1917,4 @@
|
|||||||
<Import Project="..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Animated.Vector.Drawable.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Animated.Vector.Drawable.targets')" />
|
<Import Project="..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Animated.Vector.Drawable.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Animated.Vector.Drawable.targets')" />
|
||||||
<Import Project="..\packages\Xamarin.Android.Support.v7.AppCompat.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.v7.AppCompat.targets" Condition="Exists('..\packages\Xamarin.Android.Support.v7.AppCompat.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.v7.AppCompat.targets')" />
|
<Import Project="..\packages\Xamarin.Android.Support.v7.AppCompat.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.v7.AppCompat.targets" Condition="Exists('..\packages\Xamarin.Android.Support.v7.AppCompat.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.v7.AppCompat.targets')" />
|
||||||
<Import Project="..\packages\Xamarin.Android.Support.Design.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Design.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Design.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Design.targets')" />
|
<Import Project="..\packages\Xamarin.Android.Support.Design.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Design.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Design.26.1.0.1\build\MonoAndroid80\Xamarin.Android.Support.Design.targets')" />
|
||||||
</Project>
|
</Project>
|
||||||
|
Reference in New Issue
Block a user