feature: shortcut

This commit is contained in:
Tsanie Lily 2022-03-17 20:29:27 +08:00
parent 60f7824cb5
commit ef5e91aad1
18 changed files with 118 additions and 36 deletions

View File

@ -13,6 +13,7 @@ namespace Billing
{ {
public class App : Application public class App : Application
{ {
internal const string NewBillAction = "/newbill";
private const string SaveLocationKey = nameof(SaveLocationKey); private const string SaveLocationKey = nameof(SaveLocationKey);
public static AppTheme CurrentTheme { get; private set; } public static AppTheme CurrentTheme { get; private set; }
@ -21,17 +22,27 @@ namespace Billing
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; public static bool SaveLocation => saveLocation;
public static string MainRoute => mainRoute;
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 static bool saveLocation;
private static string mainRoute;
private string initialUrl; private string initialUrl;
public App(string url = null) public App(string url = null)
{ {
if (url == NewBillAction)
{
mainRoute = "//Bills/Details";
}
else
{
mainRoute = "//Bills";
initialUrl = url; initialUrl = url;
}
CurrentCulture = new PlatformCulture(); CurrentCulture = new PlatformCulture();
InitResources(); InitResources();

View File

@ -1,3 +1,4 @@
using Billing.Views;
using Xamarin.Forms; using Xamarin.Forms;
namespace Billing namespace Billing
@ -6,6 +7,8 @@ namespace Billing
{ {
public MainShell() public MainShell()
{ {
Routing.RegisterRoute("Bills/Details", typeof(AddBillPage));
InitializeComponent(); InitializeComponent();
} }
} }

View File

@ -14,7 +14,7 @@ namespace Billing
{ {
await App.InitializeData(); await App.InitializeData();
await Shell.Current.GoToAsync("//Bills"); await Shell.Current.GoToAsync(App.MainRoute);
} }
} }
} }

View File

@ -38,6 +38,7 @@ namespace Billing.Store
catch (Exception ex) catch (Exception ex)
{ {
Helper.Error("database.close", ex); Helper.Error("database.close", ex);
return false;
} }
try try
{ {
@ -54,12 +55,13 @@ namespace Billing.Store
SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.ReadWrite |
SQLiteOpenFlags.Create | SQLiteOpenFlags.Create |
SQLiteOpenFlags.SharedCache); SQLiteOpenFlags.SharedCache);
return true;
} }
catch (Exception ex) catch (Exception ex)
{ {
Helper.Error("database.connect", ex); Helper.Error("database.connect", ex);
return false;
} }
return true;
} }
public static readonly AsyncLazy<StoreHelper> Instance = new(async () => public static readonly AsyncLazy<StoreHelper> Instance = new(async () =>

View File

@ -70,6 +70,7 @@ namespace Billing.Views
private CancellationTokenSource tokenSource; private CancellationTokenSource tokenSource;
private Location location; private Location location;
public AddBillPage() : this(DateTime.Today) { }
public AddBillPage(DateTime date) public AddBillPage(DateTime date)
{ {
createDate = date; createDate = date;

View File

@ -13,25 +13,24 @@
Shell.TabBarIsVisible="True"> Shell.TabBarIsVisible="True">
<Shell.TitleView> <Shell.TitleView>
<StackLayout Orientation="Horizontal" Spacing="10"> <Grid ColumnSpacing="10" ColumnDefinitions="30, *, 30">
<ui:TintImageButton Source="left.png" WidthRequest="20" HeightRequest="20" <ui:TintImageButton Source="left.png" WidthRequest="20" HeightRequest="20"
VerticalOptions="Center" HorizontalOptions="Start" VerticalOptions="Center" HorizontalOptions="Center"
Command="{Binding LeftCommand}"/> Command="{Binding LeftCommand}"/>
<Label Text="{Binding Title}" <Label Grid.Column="1" Text="{Binding Title}"
TextColor="{DynamicResource PrimaryColor}" TextColor="{DynamicResource PrimaryColor}"
FontSize="{OnPlatform Android=20, iOS=18}" FontSize="{OnPlatform Android=20, iOS=18}"
FontFamily="{x:Static ui:Definition.SemiBoldFontFamily}" FontFamily="{x:Static ui:Definition.SemiBoldFontFamily}"
VerticalOptions="Center" VerticalOptions="Center"
HorizontalOptions="FillAndExpand" HorizontalOptions="Center">
HorizontalTextAlignment="Center">
<Label.GestureRecognizers> <Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding FilterCommand}"/> <TapGestureRecognizer Command="{Binding FilterCommand}"/>
</Label.GestureRecognizers> </Label.GestureRecognizers>
</Label> </Label>
<ui:TintImageButton Source="right.png" WidthRequest="20" HeightRequest="20" <ui:TintImageButton Grid.Column="2" Source="right.png" WidthRequest="20" HeightRequest="20"
VerticalOptions="Center" HorizontalOptions="End" VerticalOptions="Center" HorizontalOptions="Center"
Command="{Binding RightCommand}"/> Command="{Binding RightCommand}"/>
</StackLayout> </Grid>
</Shell.TitleView> </Shell.TitleView>
<!--<ContentPage.ToolbarItems> <!--<ContentPage.ToolbarItems>

View File

@ -607,7 +607,9 @@
<ItemGroup> <ItemGroup>
<AndroidResource Include="Resources\drawable\left.png" /> <AndroidResource Include="Resources\drawable\left.png" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<AndroidResource Include="Resources\xml\shortcuts.xml" />
</ItemGroup>
<Import Project="..\..\Billing.Shared\Billing.Shared.projitems" Label="Shared" /> <Import Project="..\..\Billing.Shared\Billing.Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project> </Project>

View File

@ -4,7 +4,6 @@ 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.Provider;
using Android.Database; using Android.Database;
@ -25,9 +24,16 @@ 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)
{
if (uri.Authority == "org.tsanie.billing.shortcuts")
{
url = uri.Path;
}
else
{ {
url = GetFilePath(BaseContext, uri); url = GetFilePath(BaseContext, uri);
} }
}
else else
{ {
url = null; url = null;
@ -82,6 +88,15 @@ namespace Billing.Droid
} }
else if (uri.Scheme == "content") else if (uri.Scheme == "content")
{ {
if (uri.Authority == "com.speedsoftware.rootexplorer.fileprovider")
{
var path = uri.Path;
if (path.StartsWith("/root/"))
{
return path[5..];
}
return path;
}
return GetDataColumn(context, uri, null, null); return GetDataColumn(context, uri, null, null);
} }
else if (uri.Scheme == "file") else if (uri.Scheme == "file")

View File

@ -1,7 +1,7 @@
<?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.2.317" package="org.tsanie.billing" android:installLocation="auto" android:versionCode="16"> <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" android:requestLegacyExternalStorage="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<queries> <queries>
<intent> <intent>

View File

@ -14,7 +14,7 @@ namespace Billing.Droid
{ {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.2.0.155")]
public partial class Resource public partial class Resource
{ {
@ -21803,43 +21803,46 @@ namespace Billing.Droid
public const int nav_app_bar_open_drawer_description = 2131624042; public const int nav_app_bar_open_drawer_description = 2131624042;
// aapt resource value: 0x7F0E006B // aapt resource value: 0x7F0E006B
public const int not_set = 2131624043; public const int newbill = 2131624043;
// aapt resource value: 0x7F0E006C // aapt resource value: 0x7F0E006C
public const int overflow_tab_title = 2131624044; public const int not_set = 2131624044;
// aapt resource value: 0x7F0E006D // aapt resource value: 0x7F0E006D
public const int password_toggle_content_description = 2131624045; public const int overflow_tab_title = 2131624045;
// aapt resource value: 0x7F0E006E // aapt resource value: 0x7F0E006E
public const int path_password_eye = 2131624046; public const int password_toggle_content_description = 2131624046;
// aapt resource value: 0x7F0E006F // aapt resource value: 0x7F0E006F
public const int path_password_eye_mask_strike_through = 2131624047; public const int path_password_eye = 2131624047;
// aapt resource value: 0x7F0E0070 // aapt resource value: 0x7F0E0070
public const int path_password_eye_mask_visible = 2131624048; public const int path_password_eye_mask_strike_through = 2131624048;
// aapt resource value: 0x7F0E0071 // aapt resource value: 0x7F0E0071
public const int path_password_strike_through = 2131624049; public const int path_password_eye_mask_visible = 2131624049;
// aapt resource value: 0x7F0E0072 // aapt resource value: 0x7F0E0072
public const int preference_copied = 2131624050; public const int path_password_strike_through = 2131624050;
// aapt resource value: 0x7F0E0073 // aapt resource value: 0x7F0E0073
public const int search_menu_title = 2131624051; public const int preference_copied = 2131624051;
// aapt resource value: 0x7F0E0074 // aapt resource value: 0x7F0E0074
public const int status_bar_notification_info_overflow = 2131624052; public const int search_menu_title = 2131624052;
// aapt resource value: 0x7F0E0075 // aapt resource value: 0x7F0E0075
public const int summary_collapsed_preference_list = 2131624053; public const int status_bar_notification_info_overflow = 2131624053;
// aapt resource value: 0x7F0E0076 // aapt resource value: 0x7F0E0076
public const int v7_preference_off = 2131624054; public const int summary_collapsed_preference_list = 2131624054;
// aapt resource value: 0x7F0E0077 // aapt resource value: 0x7F0E0077
public const int v7_preference_on = 2131624055; public const int v7_preference_off = 2131624055;
// aapt resource value: 0x7F0E0078
public const int v7_preference_on = 2131624056;
static String() static String()
{ {
@ -32297,22 +32300,25 @@ namespace Billing.Droid
public const int image_share_filepaths = 2131820544; public const int image_share_filepaths = 2131820544;
// aapt resource value: 0x7F110001 // aapt resource value: 0x7F110001
public const int standalone_badge = 2131820545; public const int shortcuts = 2131820545;
// aapt resource value: 0x7F110002 // aapt resource value: 0x7F110002
public const int standalone_badge_gravity_bottom_end = 2131820546; public const int standalone_badge = 2131820546;
// aapt resource value: 0x7F110003 // aapt resource value: 0x7F110003
public const int standalone_badge_gravity_bottom_start = 2131820547; public const int standalone_badge_gravity_bottom_end = 2131820547;
// aapt resource value: 0x7F110004 // aapt resource value: 0x7F110004
public const int standalone_badge_gravity_top_start = 2131820548; public const int standalone_badge_gravity_bottom_start = 2131820548;
// aapt resource value: 0x7F110005 // aapt resource value: 0x7F110005
public const int standalone_badge_offset = 2131820549; public const int standalone_badge_gravity_top_start = 2131820549;
// aapt resource value: 0x7F110006 // aapt resource value: 0x7F110006
public const int xamarin_essentials_fileprovider_file_paths = 2131820550; public const int standalone_badge_offset = 2131820550;
// aapt resource value: 0x7F110007
public const int xamarin_essentials_fileprovider_file_paths = 2131820551;
static Xml() static Xml()
{ {

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<resources> <resources>
<string name="applabel">记账本</string> <string name="applabel">记账本</string>
<string name="newbill">记录一条</string>
</resources> </resources>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<resources> <resources>
<string name="applabel">Billing</string> <string name="applabel">Billing</string>
<string name="newbill">Write a bill</string>
</resources> </resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut android:shortcutId="newbill" android:enabled="true" android:icon="@drawable/daily" android:shortcutShortLabel="@string/newbill" android:shortcutLongLabel="@string/newbill" android:shortcutDisabledMessage="@string/newbill">
<intent android:action="android.intent.action.VIEW" android:targetPackage="org.tsanie.billing" android:targetClass="org.tsanie.billing.SplashScreen" android:data="content://org.tsanie.billing.shortcuts/newbill" />
</shortcut>
</shortcuts>

View File

@ -18,6 +18,9 @@ namespace Billing.Droid
//DataScheme = "file", //DataScheme = "file",
DataMimeType = "*/*", DataMimeType = "*/*",
DataPathPattern = ".*\\.db3")] DataPathPattern = ".*\\.db3")]
[MetaData(
"android.app.shortcuts",
Resource = "@xml/shortcuts")]
public class SplashActivity : AppCompatActivity public class SplashActivity : AppCompatActivity
{ {
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState) public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)

View File

@ -1,4 +1,5 @@
using Foundation; using Foundation;
using ObjCRuntime;
using UIKit; using UIKit;
namespace Billing.iOS namespace Billing.iOS
@ -19,7 +20,16 @@ namespace Billing.iOS
public override bool FinishedLaunching(UIApplication app, NSDictionary options) public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{ {
Xamarin.Forms.Forms.Init(); Xamarin.Forms.Forms.Init();
LoadApplication(new App()); string action;
if (options != null && options.TryGetValue(UIApplication.LaunchOptionsShortcutItemKey, out var obj) && obj is UIApplicationShortcutItem shortcut)
{
action = "/" + shortcut.Type;
}
else
{
action = null;
}
LoadApplication(new App(action));
return base.FinishedLaunching(app, options); return base.FinishedLaunching(app, options);
} }
@ -32,5 +42,14 @@ namespace Billing.iOS
} }
return false; return false;
} }
public override void PerformActionForShortcutItem(UIApplication application, UIApplicationShortcutItem shortcutItem, UIOperationHandler completionHandler)
{
if (shortcutItem == null || string.IsNullOrEmpty(shortcutItem.Type))
{
return;
}
Xamarin.Essentials.MainThread.BeginInvokeOnMainThread(async () => await Xamarin.Forms.Shell.Current.GoToAsync("//Bills/Details"));
}
} }
} }

View File

@ -1,2 +1,3 @@
"CFBundleDisplayName" = "Billing"; "CFBundleDisplayName" = "Billing";
"BillingShortcutNew" = "Write a bill";
"NSLocationWhenInUseUsageDescription" = "When &quot;Save Location&quot; is checked, the Billing app needs to access the location."; "NSLocationWhenInUseUsageDescription" = "When &quot;Save Location&quot; is checked, the Billing app needs to access the location.";

View File

@ -93,5 +93,16 @@
<true/> <true/>
<key>NSLocationWhenInUseUsageDescription</key> <key>NSLocationWhenInUseUsageDescription</key>
<string>When &quot;Save Location&quot; is checked, the Billing app needs to access the location.</string> <string>When &quot;Save Location&quot; is checked, the Billing app needs to access the location.</string>
<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeCompose</string>
<key>UIApplicationShortcutItemTitle</key>
<string>BillingShortcutNew</string>
<key>UIApplicationShortcutItemType</key>
<string>newbill</string>
</dict>
</array>
</dict> </dict>
</plist> </plist>

View File

@ -1,2 +1,3 @@
"CFBundleDisplayName" = "记账本"; "CFBundleDisplayName" = "记账本";
"BillingShortcutNew" = "记录一条";
"NSLocationWhenInUseUsageDescription" = "当选中“保存位置”时,记账本需要访问位置信息。"; "NSLocationWhenInUseUsageDescription" = "当选中“保存位置”时,记账本需要访问位置信息。";