feature: save location
This commit is contained in:
parent
b46b150f6a
commit
60f7824cb5
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Billing.Languages;
|
using Billing.Languages;
|
||||||
@ -14,15 +13,19 @@ namespace Billing
|
|||||||
{
|
{
|
||||||
public class App : Application
|
public class App : Application
|
||||||
{
|
{
|
||||||
|
private const string SaveLocationKey = nameof(SaveLocationKey);
|
||||||
|
|
||||||
public static AppTheme CurrentTheme { get; private set; }
|
public static AppTheme CurrentTheme { get; private set; }
|
||||||
public static PlatformCulture CurrentCulture { get; private set; }
|
public static PlatformCulture CurrentCulture { get; private set; }
|
||||||
public static List<Bill> Bills => bills ??= new List<Bill>();
|
public static List<Bill> Bills => bills ??= new List<Bill>();
|
||||||
public static List<Account> Accounts => accounts ??= new List<Account>();
|
public static List<Account> Accounts => accounts ??= new List<Account>();
|
||||||
public static List<Category> Categories => categories ??= new List<Category>();
|
public static List<Category> Categories => categories ??= new List<Category>();
|
||||||
|
public static bool SaveLocation => saveLocation;
|
||||||
|
|
||||||
private static List<Bill> bills;
|
private static List<Bill> bills;
|
||||||
private static List<Account> accounts;
|
private static List<Account> accounts;
|
||||||
private static List<Category> categories;
|
private static List<Category> categories;
|
||||||
|
private static bool saveLocation;
|
||||||
|
|
||||||
private string initialUrl;
|
private string initialUrl;
|
||||||
|
|
||||||
@ -48,15 +51,6 @@ namespace Billing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task InitializeData()
|
|
||||||
{
|
|
||||||
var instance = await StoreHelper.Instance;
|
|
||||||
await Task.WhenAll(
|
|
||||||
Task.Run(async () => accounts = await instance.GetListAsync<Account>()),
|
|
||||||
Task.Run(async () => categories = await instance.GetListAsync<Category>()),
|
|
||||||
Task.Run(async () => bills = await instance.GetListAsync<Bill>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnResume()
|
protected override void OnResume()
|
||||||
{
|
{
|
||||||
SetTheme(AppInfo.RequestedTheme);
|
SetTheme(AppInfo.RequestedTheme);
|
||||||
@ -93,6 +87,21 @@ namespace Billing
|
|||||||
Resources = instance;
|
Resources = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetSaveLocation(bool flag)
|
||||||
|
{
|
||||||
|
saveLocation = flag;
|
||||||
|
Preferences.Set(SaveLocationKey, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task InitializeData()
|
||||||
|
{
|
||||||
|
var instance = await StoreHelper.Instance;
|
||||||
|
await Task.WhenAll(
|
||||||
|
Task.Run(async () => accounts = await instance.GetListAsync<Account>()),
|
||||||
|
Task.Run(async () => categories = await instance.GetListAsync<Category>()),
|
||||||
|
Task.Run(async () => bills = await instance.GetListAsync<Bill>()));
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<bool> OpenUrl(string url)
|
public static async Task<bool> OpenUrl(string url)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(url))
|
if (string.IsNullOrEmpty(url))
|
||||||
@ -101,12 +110,7 @@ namespace Billing
|
|||||||
}
|
}
|
||||||
if (File.Exists(url))
|
if (File.Exists(url))
|
||||||
{
|
{
|
||||||
var status = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
|
var status = await Helper.CheckAndRequestPermissionAsync<Permissions.StorageRead>();
|
||||||
if (status != PermissionStatus.Disabled &&
|
|
||||||
status != PermissionStatus.Granted)
|
|
||||||
{
|
|
||||||
status = await Permissions.RequestAsync<Permissions.StorageRead>();
|
|
||||||
}
|
|
||||||
if (status != PermissionStatus.Granted)
|
if (status != PermissionStatus.Granted)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -136,6 +136,17 @@ namespace Billing
|
|||||||
}
|
}
|
||||||
|
|
||||||
public delegate void PropertyValueChanged<TResult, TOwner>(TOwner obj, TResult old, TResult @new);
|
public delegate void PropertyValueChanged<TResult, TOwner>(TOwner obj, TResult old, TResult @new);
|
||||||
|
|
||||||
|
public static async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>() where T : Permissions.BasePermission, new()
|
||||||
|
{
|
||||||
|
var status = await Permissions.CheckStatusAsync<T>();
|
||||||
|
if (status != PermissionStatus.Disabled &&
|
||||||
|
status != PermissionStatus.Granted)
|
||||||
|
{
|
||||||
|
status = await Permissions.RequestAsync<T>();
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AsyncLazy<T>
|
public class AsyncLazy<T>
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
<Feature>Feature</Feature>
|
<Feature>Feature</Feature>
|
||||||
<CategoryManage>Category Management</CategoryManage>
|
<CategoryManage>Category Management</CategoryManage>
|
||||||
<Detail>Detail</Detail>
|
<Detail>Detail</Detail>
|
||||||
|
<SaveLocation>Save Location</SaveLocation>
|
||||||
<AddCategory>Add Category</AddCategory>
|
<AddCategory>Add Category</AddCategory>
|
||||||
<ConfirmDeleteCategory>Are you sure you want to delete the category: {0}?</ConfirmDeleteCategory>
|
<ConfirmDeleteCategory>Are you sure you want to delete the category: {0}?</ConfirmDeleteCategory>
|
||||||
<SelectCategory>Select Category</SelectCategory>
|
<SelectCategory>Select Category</SelectCategory>
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
<Feature>功能</Feature>
|
<Feature>功能</Feature>
|
||||||
<CategoryManage>分类管理</CategoryManage>
|
<CategoryManage>分类管理</CategoryManage>
|
||||||
<Detail>详细</Detail>
|
<Detail>详细</Detail>
|
||||||
|
<SaveLocation>保存位置</SaveLocation>
|
||||||
<AddCategory>新建分类</AddCategory>
|
<AddCategory>新建分类</AddCategory>
|
||||||
<ConfirmDeleteCategory>是否确认删除该分类:{0}?</ConfirmDeleteCategory>
|
<ConfirmDeleteCategory>是否确认删除该分类:{0}?</ConfirmDeleteCategory>
|
||||||
<SelectCategory>选择类别</SelectCategory>
|
<SelectCategory>选择类别</SelectCategory>
|
||||||
|
@ -14,5 +14,10 @@ namespace Billing.Models
|
|||||||
public string Store { get; set; }
|
public string Store { get; set; }
|
||||||
public DateTime CreateTime { get; set; }
|
public DateTime CreateTime { get; set; }
|
||||||
public string Note { get; set; }
|
public string Note { get; set; }
|
||||||
|
public double? Latitude { get; set; }
|
||||||
|
public double? Longitude { get; set; }
|
||||||
|
public double? Altitude { get; set; }
|
||||||
|
public double? Accuracy { get; set; }
|
||||||
|
public bool? IsGps { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Billing.Languages;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Billing.Models;
|
using Billing.Models;
|
||||||
using Billing.Store;
|
using Billing.Store;
|
||||||
using Billing.UI;
|
using Billing.UI;
|
||||||
@ -13,6 +14,7 @@ namespace Billing.Views
|
|||||||
{
|
{
|
||||||
public partial class AddBillPage : BillingPage
|
public partial class AddBillPage : BillingPage
|
||||||
{
|
{
|
||||||
|
private static readonly BindableProperty CheckBillProperty = Helper.Create<Command, AddBillPage>(nameof(CheckBill), defaultValue: new Command(() => { }, () => false));
|
||||||
private static readonly BindableProperty AmountProperty = Helper.Create<string, AddBillPage>(nameof(Amount));
|
private static readonly BindableProperty AmountProperty = Helper.Create<string, AddBillPage>(nameof(Amount));
|
||||||
private static readonly BindableProperty NameProperty = Helper.Create<string, AddBillPage>(nameof(Name));
|
private static readonly BindableProperty NameProperty = Helper.Create<string, AddBillPage>(nameof(Name));
|
||||||
private static readonly BindableProperty CategoryProperty = Helper.Create<Category, AddBillPage>(nameof(Category));
|
private static readonly BindableProperty CategoryProperty = Helper.Create<Category, AddBillPage>(nameof(Category));
|
||||||
@ -22,6 +24,7 @@ namespace Billing.Views
|
|||||||
private static readonly BindableProperty CreatedTimeProperty = Helper.Create<TimeSpan, AddBillPage>(nameof(CreatedTime));
|
private static readonly BindableProperty CreatedTimeProperty = Helper.Create<TimeSpan, AddBillPage>(nameof(CreatedTime));
|
||||||
private static readonly BindableProperty NoteProperty = Helper.Create<string, AddBillPage>(nameof(Note));
|
private static readonly BindableProperty NoteProperty = Helper.Create<string, AddBillPage>(nameof(Note));
|
||||||
|
|
||||||
|
public Command CheckBill => (Command)GetValue(CheckBillProperty);
|
||||||
public string Amount
|
public string Amount
|
||||||
{
|
{
|
||||||
get => (string)GetValue(AmountProperty);
|
get => (string)GetValue(AmountProperty);
|
||||||
@ -55,7 +58,6 @@ namespace Billing.Views
|
|||||||
set => SetValue(NoteProperty, value);
|
set => SetValue(NoteProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Command CheckBill { get; }
|
|
||||||
public Command SelectCategory { get; }
|
public Command SelectCategory { get; }
|
||||||
public Command SelectWallet { get; }
|
public Command SelectWallet { get; }
|
||||||
|
|
||||||
@ -65,11 +67,12 @@ namespace Billing.Views
|
|||||||
private readonly DateTime createDate;
|
private readonly DateTime createDate;
|
||||||
|
|
||||||
private bool categoryChanged;
|
private bool categoryChanged;
|
||||||
|
private CancellationTokenSource tokenSource;
|
||||||
|
private Location location;
|
||||||
|
|
||||||
public AddBillPage(DateTime date)
|
public AddBillPage(DateTime date)
|
||||||
{
|
{
|
||||||
createDate = date;
|
createDate = date;
|
||||||
CheckBill = new Command(OnCheckBill);
|
|
||||||
SelectCategory = new Command(OnSelectCategory);
|
SelectCategory = new Command(OnSelectCategory);
|
||||||
SelectWallet = new Command(OnSelectWallet);
|
SelectWallet = new Command(OnSelectWallet);
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -81,7 +84,6 @@ namespace Billing.Views
|
|||||||
public AddBillPage(Bill bill)
|
public AddBillPage(Bill bill)
|
||||||
{
|
{
|
||||||
this.bill = bill;
|
this.bill = bill;
|
||||||
CheckBill = new Command(OnCheckBill);
|
|
||||||
SelectCategory = new Command(OnSelectCategory);
|
SelectCategory = new Command(OnSelectCategory);
|
||||||
SelectWallet = new Command(OnSelectWallet);
|
SelectWallet = new Command(OnSelectWallet);
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -90,6 +92,15 @@ namespace Billing.Views
|
|||||||
Initial();
|
Initial();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnDisappearing()
|
||||||
|
{
|
||||||
|
if (tokenSource != null && !tokenSource.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
tokenSource.Cancel();
|
||||||
|
}
|
||||||
|
base.OnDisappearing();
|
||||||
|
}
|
||||||
|
|
||||||
private void Initial()
|
private void Initial()
|
||||||
{
|
{
|
||||||
if (bill != null)
|
if (bill != null)
|
||||||
@ -116,6 +127,41 @@ namespace Billing.Views
|
|||||||
protected override void OnLoaded()
|
protected override void OnLoaded()
|
||||||
{
|
{
|
||||||
editorAmount.SetFocus();
|
editorAmount.SetFocus();
|
||||||
|
|
||||||
|
if (App.SaveLocation)
|
||||||
|
{
|
||||||
|
_ = GetCurrentLocation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetValue(CheckBillProperty, new Command(OnCheckBill));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetCurrentLocation()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = new GeolocationRequest(GeolocationAccuracy.Best, TimeSpan.FromSeconds(10));
|
||||||
|
tokenSource = new CancellationTokenSource();
|
||||||
|
var status = await Helper.CheckAndRequestPermissionAsync<Permissions.LocationWhenInUse>();
|
||||||
|
if (status != PermissionStatus.Granted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
location = await Geolocation.GetLocationAsync(request, tokenSource.Token);
|
||||||
|
}
|
||||||
|
catch (FeatureNotSupportedException) { }
|
||||||
|
catch (FeatureNotEnabledException) { }
|
||||||
|
catch (PermissionException) { }
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Helper.Error("location.get", ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SetValue(CheckBillProperty, new Command(OnCheckBill));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnCheckBill()
|
private async void OnCheckBill()
|
||||||
@ -148,26 +194,27 @@ namespace Billing.Views
|
|||||||
{
|
{
|
||||||
name = category.Name;
|
name = category.Name;
|
||||||
}
|
}
|
||||||
if (bill != null)
|
Bill b = bill;
|
||||||
|
if (b == null)
|
||||||
{
|
{
|
||||||
bill.Amount = amount;
|
b = new Bill();
|
||||||
bill.Name = name;
|
|
||||||
bill.CategoryId = category.Id;
|
|
||||||
bill.WalletId = wallet.Id;
|
|
||||||
bill.CreateTime = CreatedDate.Date.Add(CreatedTime);
|
|
||||||
bill.Store = Store;
|
|
||||||
bill.Note = Note;
|
|
||||||
}
|
}
|
||||||
BillChecked?.Invoke(this, bill ?? new Bill
|
b.Amount = amount;
|
||||||
|
b.Name = name;
|
||||||
|
b.CategoryId = category.Id;
|
||||||
|
b.WalletId = wallet.Id;
|
||||||
|
b.CreateTime = CreatedDate.Date.Add(CreatedTime);
|
||||||
|
b.Store = Store;
|
||||||
|
b.Note = Note;
|
||||||
|
if (location != null)
|
||||||
{
|
{
|
||||||
Amount = amount,
|
b.Latitude = location.Latitude;
|
||||||
Name = name,
|
b.Longitude = location.Longitude;
|
||||||
CategoryId = category.Id,
|
b.Altitude = location.Altitude;
|
||||||
WalletId = wallet.Id,
|
b.Accuracy = location.Accuracy;
|
||||||
CreateTime = CreatedDate.Date.Add(CreatedTime),
|
b.IsGps = location.IsFromMockProvider;
|
||||||
Store = Store,
|
}
|
||||||
Note = Note
|
BillChecked?.Invoke(this, b);
|
||||||
});
|
|
||||||
|
|
||||||
category.LastAccountId = wallet.Id;
|
category.LastAccountId = wallet.Id;
|
||||||
category.LastUsed = DateTime.Now;
|
category.LastUsed = DateTime.Now;
|
||||||
|
@ -191,11 +191,15 @@ namespace Billing.Views
|
|||||||
FilterCommand = new Command(OnFilterCommand);
|
FilterCommand = new Command(OnFilterCommand);
|
||||||
EditBilling = new Command(OnEditBilling);
|
EditBilling = new Command(OnEditBilling);
|
||||||
|
|
||||||
|
#if __IOS__
|
||||||
var style = SKFontManager.Default.GetFontStyles("PingFang SC");
|
var style = SKFontManager.Default.GetFontStyles("PingFang SC");
|
||||||
if (style != null)
|
if (style != null)
|
||||||
{
|
{
|
||||||
font = style.CreateTypeface(SKFontStyle.Normal);
|
font = style.CreateTypeface(SKFontStyle.Normal);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
font = SKFontManager.Default.MatchCharacter(0x4e00);
|
||||||
|
|
||||||
DateTypes = new List<string>
|
DateTypes = new List<string>
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
<ui:OptionSelectCell Height="36" Title="{r:Text CategoryManage}"
|
<ui:OptionSelectCell Height="36" Title="{r:Text CategoryManage}"
|
||||||
Detail="{r:Text Detail}"
|
Detail="{r:Text Detail}"
|
||||||
Command="{Binding CategoryCommand}"/>
|
Command="{Binding CategoryCommand}"/>
|
||||||
|
<ui:OptionSwitchCell Height="36" Title="{r:Text SaveLocation}"
|
||||||
|
IsToggled="{Binding SaveLocation, Mode=TwoWay}"/>
|
||||||
</TableSection>
|
</TableSection>
|
||||||
<TableSection Title="{r:Text Preference}">
|
<TableSection Title="{r:Text Preference}">
|
||||||
<ui:OptionEntryCell Height="36" Title="{r:Text PrimaryColor}"
|
<ui:OptionEntryCell Height="36" Title="{r:Text PrimaryColor}"
|
||||||
|
@ -11,10 +11,16 @@ namespace Billing.Views
|
|||||||
public partial class SettingPage : BillingPage
|
public partial class SettingPage : BillingPage
|
||||||
{
|
{
|
||||||
private static readonly BindableProperty VersionProperty = Helper.Create<string, SettingPage>(nameof(Version));
|
private static readonly BindableProperty VersionProperty = Helper.Create<string, SettingPage>(nameof(Version));
|
||||||
|
private static readonly BindableProperty SaveLocationProperty = Helper.Create<bool, SettingPage>(nameof(SaveLocation));
|
||||||
private static readonly BindableProperty PrimaryColorProperty = Helper.Create<string, SettingPage>(nameof(PrimaryColor));
|
private static readonly BindableProperty PrimaryColorProperty = Helper.Create<string, SettingPage>(nameof(PrimaryColor));
|
||||||
private static readonly BindableProperty ManyRecordsProperty = Helper.Create<string, SettingPage>(nameof(ManyRecords));
|
private static readonly BindableProperty ManyRecordsProperty = Helper.Create<string, SettingPage>(nameof(ManyRecords));
|
||||||
|
|
||||||
public string Version => (string)GetValue(VersionProperty);
|
public string Version => (string)GetValue(VersionProperty);
|
||||||
|
public bool SaveLocation
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(SaveLocationProperty);
|
||||||
|
set => SetValue(SaveLocationProperty, value);
|
||||||
|
}
|
||||||
public string PrimaryColor
|
public string PrimaryColor
|
||||||
{
|
{
|
||||||
get => (string)GetValue(PrimaryColorProperty);
|
get => (string)GetValue(PrimaryColorProperty);
|
||||||
@ -35,16 +41,14 @@ namespace Billing.Views
|
|||||||
ShareLogsCommand = new Command(OnShareLogsCommand);
|
ShareLogsCommand = new Command(OnShareLogsCommand);
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
var main = AppInfo.VersionString;
|
SetValue(VersionProperty, $"{AppInfo.VersionString} ({AppInfo.BuildString})");
|
||||||
var build = AppInfo.BuildString;
|
|
||||||
SetValue(VersionProperty, $"{main} ({build})");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnAppearing()
|
protected override async void OnAppearing()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
|
|
||||||
//SetValue(VersionProperty, $"{AppInfo.VersionString} ({AppInfo.BuildString})");
|
SaveLocation = App.SaveLocation;
|
||||||
var colorString = Preferences.Get(Definition.PrimaryColorKey, Helper.DEFAULT_COLOR);
|
var colorString = Preferences.Get(Definition.PrimaryColorKey, Helper.DEFAULT_COLOR);
|
||||||
PrimaryColor = Helper.WrapColorString(colorString);
|
PrimaryColor = Helper.WrapColorString(colorString);
|
||||||
|
|
||||||
@ -56,8 +60,8 @@ namespace Billing.Views
|
|||||||
{
|
{
|
||||||
base.OnDisappearing();
|
base.OnDisappearing();
|
||||||
|
|
||||||
|
App.SetSaveLocation(SaveLocation);
|
||||||
Preferences.Set(Definition.PrimaryColorKey, PrimaryColor);
|
Preferences.Set(Definition.PrimaryColorKey, PrimaryColor);
|
||||||
//Light.Instance.RefreshColor(Color.FromHex(color));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnRefresh()
|
protected override async void OnRefresh()
|
||||||
|
@ -4,6 +4,9 @@ using Android.Content.PM;
|
|||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Net;
|
using Android.Net;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Android.Provider;
|
||||||
|
using Android.Database;
|
||||||
|
|
||||||
namespace Billing.Droid
|
namespace Billing.Droid
|
||||||
{
|
{
|
||||||
@ -23,11 +26,7 @@ namespace Billing.Droid
|
|||||||
string url;
|
string url;
|
||||||
if (Intent.ActionView.Equals(Intent.Action) && Intent.Data is Uri uri)
|
if (Intent.ActionView.Equals(Intent.Action) && Intent.Data is Uri uri)
|
||||||
{
|
{
|
||||||
url = uri.Path;
|
url = GetFilePath(BaseContext, uri);
|
||||||
if (url != null && url.StartsWith("/root"))
|
|
||||||
{
|
|
||||||
url = url[5..];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -44,5 +43,74 @@ namespace Billing.Droid
|
|||||||
|
|
||||||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetFilePath(Context context, Uri uri)
|
||||||
|
{
|
||||||
|
if (DocumentsContract.IsDocumentUri(context, uri))
|
||||||
|
{
|
||||||
|
Uri contentUri;
|
||||||
|
string[] split;
|
||||||
|
switch (uri.Authority)
|
||||||
|
{
|
||||||
|
case "com.android.externalstorage.documents":
|
||||||
|
split = DocumentsContract.GetDocumentId(uri).Split(':');
|
||||||
|
if (split[0] == "primary")
|
||||||
|
{
|
||||||
|
var external = ExternalCacheDir.Path;
|
||||||
|
external = external[..external.IndexOf("/Android/")];
|
||||||
|
return external + "/" + split[1];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "com.android.providers.downloads.documents":
|
||||||
|
contentUri = ContentUris.WithAppendedId(
|
||||||
|
Uri.Parse("content://downloads/public_downloads"),
|
||||||
|
long.Parse(DocumentsContract.GetDocumentId(uri)));
|
||||||
|
return GetDataColumn(context, contentUri, null, null);
|
||||||
|
|
||||||
|
case "com.android.providers.media.documents":
|
||||||
|
split = DocumentsContract.GetDocumentId(uri).Split(':');
|
||||||
|
contentUri = split[0] switch
|
||||||
|
{
|
||||||
|
"image" => MediaStore.Images.Media.ExternalContentUri,
|
||||||
|
"video" => MediaStore.Video.Media.ExternalContentUri,
|
||||||
|
"audio" => MediaStore.Audio.Media.ExternalContentUri,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
return GetDataColumn(context, contentUri, "_id=?", new[] { split[1] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (uri.Scheme == "content")
|
||||||
|
{
|
||||||
|
return GetDataColumn(context, uri, null, null);
|
||||||
|
}
|
||||||
|
else if (uri.Scheme == "file")
|
||||||
|
{
|
||||||
|
return uri.Path;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDataColumn(Context context, Uri uri, string selection, string[] selectionArgs)
|
||||||
|
{
|
||||||
|
ICursor cursor = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cursor = context.ContentResolver.Query(uri, new[] { "_data" }, selection, selectionArgs, null);
|
||||||
|
if (cursor != null && cursor.MoveToFirst())
|
||||||
|
{
|
||||||
|
var index = cursor.GetColumnIndexOrThrow("_data");
|
||||||
|
return cursor.GetString(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (cursor != null)
|
||||||
|
{
|
||||||
|
cursor.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.1.316" package="org.tsanie.billing" android:installLocation="auto" android:versionCode="15">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.2.317" package="org.tsanie.billing" android:installLocation="auto" android:versionCode="16">
|
||||||
<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="30" />
|
<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="30" />
|
||||||
<application android:label="@string/applabel" android:theme="@style/MainTheme"></application>
|
<application android:label="@string/applabel" android:theme="@style/MainTheme"></application>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
@ -30,3 +30,8 @@ using Android.App;
|
|||||||
[assembly: UsesPermission(Android.Manifest.Permission.ReadExternalStorage)]
|
[assembly: UsesPermission(Android.Manifest.Permission.ReadExternalStorage)]
|
||||||
[assembly: UsesPermission(Android.Manifest.Permission.ManageExternalStorage)]
|
[assembly: UsesPermission(Android.Manifest.Permission.ManageExternalStorage)]
|
||||||
[assembly: UsesPermission(Android.Manifest.Permission.Vibrate)]
|
[assembly: UsesPermission(Android.Manifest.Permission.Vibrate)]
|
||||||
|
[assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
|
||||||
|
[assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
|
||||||
|
[assembly: UsesFeature("android.hardware.location", Required = false)]
|
||||||
|
[assembly: UsesFeature("android.hardware.location.gps", Required = false)]
|
||||||
|
[assembly: UsesFeature("android.hardware.location.network", Required = false)]
|
||||||
|
@ -15,9 +15,9 @@ namespace Billing.Droid
|
|||||||
[IntentFilter(
|
[IntentFilter(
|
||||||
new[] { Intent.ActionView },
|
new[] { Intent.ActionView },
|
||||||
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
|
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
|
||||||
DataScheme = "file",
|
//DataScheme = "file",
|
||||||
DataMimeType = "*/*",
|
DataMimeType = "*/*",
|
||||||
DataPathPattern = ".*\\\\.db3")]
|
DataPathPattern = ".*\\.db3")]
|
||||||
public class SplashActivity : AppCompatActivity
|
public class SplashActivity : AppCompatActivity
|
||||||
{
|
{
|
||||||
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
|
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
|
||||||
|
@ -1 +1,2 @@
|
|||||||
"CFBundleDisplayName" = "Billing";
|
"CFBundleDisplayName" = "Billing";
|
||||||
|
"NSLocationWhenInUseUsageDescription" = "When "Save Location" is checked, the Billing app needs to access the location.";
|
@ -80,9 +80,9 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>15</string>
|
<string>16</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.1.316</string>
|
<string>1.2.317</string>
|
||||||
<key>LSApplicationQueriesSchemes</key>
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>mailto</string>
|
<string>mailto</string>
|
||||||
@ -91,5 +91,7 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>When "Save Location" is checked, the Billing app needs to access the location.</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -1 +1,2 @@
|
|||||||
"CFBundleDisplayName" = "记账本";
|
"CFBundleDisplayName" = "记账本";
|
||||||
|
"NSLocationWhenInUseUsageDescription" = "当选中“保存位置”时,记账本需要访问位置信息。";
|
Loading…
x
Reference in New Issue
Block a user