mirror of
https://github.com/zoriya/Opus.git
synced 2025-12-06 06:26:15 +00:00
youtube login
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
Any raw assets you want to be deployed with your application can be placed in
|
||||
this directory (and child directories) and given a Build Action of "AndroidAsset".
|
||||
|
||||
These files will be deployed with you package and will be accessible using Android's
|
||||
AssetManager, like this:
|
||||
|
||||
public class ReadAsset : Activity
|
||||
{
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
{
|
||||
base.OnCreate (bundle);
|
||||
|
||||
InputStream input = Assets.Open ("my_asset.txt");
|
||||
}
|
||||
}
|
||||
|
||||
Additionally, some Android functions will automatically load asset files:
|
||||
|
||||
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
|
||||
1
MusicApp/Assets/client_secret.json
Normal file
1
MusicApp/Assets/client_secret.json
Normal file
@@ -0,0 +1 @@
|
||||
{"installed":{"client_id":"758089506779-7gofatbsl2fgh18cua38ovp805n38veb.apps.googleusercontent.com","project_id":"musicapp-185015","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
|
||||
@@ -1,18 +1,24 @@
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Support.V7.App;
|
||||
using Android.Runtime;
|
||||
using Android.Support.Design.Widget;
|
||||
using Android.Support.V4.View;
|
||||
using Android.Support.V7.App;
|
||||
using Android.Support.V7.Preferences;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Google.Apis.Auth.OAuth2;
|
||||
using Google.Apis.Services;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using MusicApp.Resources.Fragments;
|
||||
using MusicApp.Resources.Portable_Class;
|
||||
using Android.Views;
|
||||
using Android.Support.V4.View;
|
||||
using Android.Runtime;
|
||||
using Android.Widget;
|
||||
using Android.Content;
|
||||
using MusicApp.Resources.values;
|
||||
using Square.Picasso;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xamarin.Auth;
|
||||
using SearchView = Android.Support.V7.Widget.SearchView;
|
||||
|
||||
namespace MusicApp
|
||||
@@ -29,6 +35,133 @@ namespace MusicApp
|
||||
private bool prepared = false;
|
||||
|
||||
|
||||
#region Youtube
|
||||
|
||||
public const string clientID = "758089506779-tstocfigqvjsog2mq5j295b1305igle0.apps.googleusercontent.com";
|
||||
public static YouTubeService youtubeService;
|
||||
public static OAuth2Authenticator auth;
|
||||
public static string refreshToken;
|
||||
|
||||
public void Login()
|
||||
{
|
||||
AccountStore accountStore = AccountStore.Create();
|
||||
Account account = accountStore.FindAccountsForService("Google").FirstOrDefault();
|
||||
if (account != null)
|
||||
{
|
||||
if (!TokenHasExpire(account.Properties["refresh_token"]))
|
||||
{
|
||||
refreshToken = account.Properties["refresh_token"];
|
||||
|
||||
if (YoutubeEngine.youtubeService != null)
|
||||
return;
|
||||
|
||||
GoogleCredential credential = GoogleCredential.FromAccessToken(account.Properties["access_token"]);
|
||||
YoutubeEngine.youtubeService = new YouTubeService(new BaseClientService.Initializer()
|
||||
{
|
||||
HttpClientInitializer = credential
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auth = new OAuth2Authenticator(
|
||||
clientID,
|
||||
string.Empty,
|
||||
YouTubeService.Scope.Youtube,
|
||||
new Uri("https://accounts.google.com/o/oauth2/v2/auth"),
|
||||
new Uri("com.musicapp.android:/oauth2redirect"),
|
||||
new Uri("https://www.googleapis.com/oauth2/v4/token"),
|
||||
isUsingNativeUI: true);
|
||||
|
||||
auth.Completed += (s, e) =>
|
||||
{
|
||||
if (e.IsAuthenticated)
|
||||
{
|
||||
string tokenType = e.Account.Properties["token_type"];
|
||||
string accessToken = e.Account.Properties["access_token"];
|
||||
string refreshToken = e.Account.Properties["refresh_token"];
|
||||
string expiresIN = e.Account.Properties["expires_in"];
|
||||
MainActivity.refreshToken = refreshToken;
|
||||
|
||||
DateTime expireDate = DateTime.UtcNow.AddSeconds(double.Parse(expiresIN));
|
||||
ISharedPreferences pref = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
ISharedPreferencesEditor editor = pref.Edit();
|
||||
editor.PutString("expireDate", expireDate.ToString());
|
||||
editor.Apply();
|
||||
|
||||
GoogleCredential credential = GoogleCredential.FromAccessToken(accessToken);
|
||||
|
||||
YoutubeEngine.youtubeService = new YouTubeService(new BaseClientService.Initializer()
|
||||
{
|
||||
HttpClientInitializer = credential,
|
||||
ApplicationName = "MusicApp"
|
||||
});
|
||||
|
||||
AccountStore.Create().Save(e.Account, "Google");
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.MakeText(this, "Error in authentification.", ToastLength.Short).Show();
|
||||
}
|
||||
};
|
||||
|
||||
StartActivity(auth.GetUI(this));
|
||||
}
|
||||
}
|
||||
|
||||
public bool TokenHasExpire(string refreshToken = null)
|
||||
{
|
||||
if (refreshToken == null)
|
||||
refreshToken = MainActivity.refreshToken;
|
||||
|
||||
ISharedPreferences pref = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
string expireDate = pref.GetString("expireDate", null);
|
||||
if (expireDate != null)
|
||||
{
|
||||
DateTime expiresDate = DateTime.Parse(expireDate);
|
||||
|
||||
if (expiresDate > DateTime.UtcNow)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
RequestNewToken(refreshToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public async void RequestNewToken(string refreshToken)
|
||||
{
|
||||
Dictionary<string, string> queryValues = new Dictionary<string, string>
|
||||
{
|
||||
{"refresh_token", refreshToken },
|
||||
{"client_id", clientID },
|
||||
{"grant_type", "refresh_token" }
|
||||
};
|
||||
await auth.RequestAccessTokenAsync(queryValues).ContinueWith(result =>
|
||||
{
|
||||
string accessToken = result.Result["access_token"];
|
||||
string expiresIN = result.Result["expires_in"];
|
||||
|
||||
DateTime expireDate = DateTime.UtcNow.AddSeconds(double.Parse(expiresIN));
|
||||
ISharedPreferences pref = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
ISharedPreferencesEditor editor = pref.Edit();
|
||||
editor.PutString("expireDate", expireDate.ToString());
|
||||
editor.Apply();
|
||||
|
||||
GoogleCredential credential = GoogleCredential.FromAccessToken(accessToken);
|
||||
YoutubeEngine.youtubeService = new YouTubeService(new BaseClientService.Initializer()
|
||||
{
|
||||
HttpClientInitializer = credential,
|
||||
ApplicationName = "MusicApp"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public static int paddingBot
|
||||
{
|
||||
get
|
||||
@@ -99,7 +232,7 @@ namespace MusicApp
|
||||
SupportActionBar.SetDisplayHomeAsUpEnabled(false);
|
||||
SupportActionBar.Title = "MusicApp";
|
||||
FolderTracks.instance = null;
|
||||
SetTabs(1);
|
||||
SetBrowseTabs(1);
|
||||
}
|
||||
}
|
||||
else if(item.ItemId == Resource.Id.search)
|
||||
@@ -209,7 +342,7 @@ namespace MusicApp
|
||||
break;
|
||||
|
||||
case Resource.Id.browseLayout:
|
||||
SetTabs();
|
||||
SetBrowseTabs();
|
||||
break;
|
||||
|
||||
case Resource.Id.downloadLayout:
|
||||
@@ -219,7 +352,7 @@ namespace MusicApp
|
||||
break;
|
||||
|
||||
case Resource.Id.playlistLayout:
|
||||
HideTabs();
|
||||
SetYtTabs();
|
||||
HideSearch();
|
||||
fragment = Playlist.NewInstance();
|
||||
break;
|
||||
@@ -231,11 +364,10 @@ namespace MusicApp
|
||||
SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, fragment).Commit();
|
||||
}
|
||||
|
||||
void SetTabs(int selectedTab = 0)
|
||||
void SetBrowseTabs(int selectedTab = 0)
|
||||
{
|
||||
FrameLayout frame = FindViewById<FrameLayout>(Resource.Id.contentView);
|
||||
frame.Visibility = ViewStates.Gone;
|
||||
|
||||
TabLayout tabs = FindViewById<TabLayout>(Resource.Id.tabs);
|
||||
tabs.Visibility = ViewStates.Visible;
|
||||
tabs.RemoveAllTabs();
|
||||
@@ -243,6 +375,7 @@ namespace MusicApp
|
||||
tabs.AddTab(tabs.NewTab().SetText("Folders"));
|
||||
ViewPager pager = FindViewById<ViewPager>(Resource.Id.pager);
|
||||
pager.SetPadding(0, 200, 0, 0);
|
||||
pager.ClearOnPageChangeListeners();
|
||||
pager.AddOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabs));
|
||||
ViewPagerAdapter adapter = new ViewPagerAdapter(SupportFragmentManager);
|
||||
|
||||
@@ -256,6 +389,32 @@ namespace MusicApp
|
||||
tabs.SetScrollPosition(selectedTab, 0f, true);
|
||||
}
|
||||
|
||||
void SetYtTabs(int selectedTab = 0)
|
||||
{
|
||||
FrameLayout frame = FindViewById<FrameLayout>(Resource.Id.contentView);
|
||||
frame.Visibility = ViewStates.Gone;
|
||||
|
||||
TabLayout tabs = FindViewById<TabLayout>(Resource.Id.tabs);
|
||||
tabs.Visibility = ViewStates.Visible;
|
||||
tabs.RemoveAllTabs();
|
||||
tabs.AddTab(tabs.NewTab().SetText("Playlists"));
|
||||
tabs.AddTab(tabs.NewTab().SetText("Youtube playlists"));
|
||||
ViewPager pager = FindViewById<ViewPager>(Resource.Id.pager);
|
||||
pager.SetPadding(0, 200, 0, 0);
|
||||
pager.ClearOnPageChangeListeners();
|
||||
pager.AddOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabs));
|
||||
ViewPagerAdapter adapter = new ViewPagerAdapter(SupportFragmentManager);
|
||||
|
||||
adapter.AddFragment(Playlist.NewInstance(), "Playlists");
|
||||
adapter.AddFragment(YtPlaylist.NewInstance(), "Youtube playlists");
|
||||
|
||||
pager.Adapter = adapter;
|
||||
tabs.SetupWithViewPager(pager);
|
||||
|
||||
pager.CurrentItem = selectedTab;
|
||||
tabs.SetScrollPosition(selectedTab, 0f, true);
|
||||
}
|
||||
|
||||
public void HideTabs()
|
||||
{
|
||||
TabLayout tabs = FindViewById<TabLayout>(Resource.Id.tabs);
|
||||
|
||||
@@ -91,9 +91,39 @@
|
||||
<HintPath>..\packages\Google.Apis.YouTube.v3.1.30.0.1035\lib\netstandard1.3\Google.Apis.YouTube.v3.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Logging, Version=1.1.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.IdentityModel.Logging.1.1.3\lib\netstandard1.4\Microsoft.IdentityModel.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Tokens, Version=5.1.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.1.3\lib\netstandard1.4\Microsoft.IdentityModel.Tokens.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PCLCrypto, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d4421c8a4786956c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PCLCrypto.2.0.147\lib\MonoAndroid23\PCLCrypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PInvoke.BCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PInvoke.Kernel32, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PInvoke.NCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PInvoke.Windows.Core, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Plugin.CurrentActivity, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Plugin.CurrentActivity.1.0.1\lib\MonoAndroid10\Plugin.CurrentActivity.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -119,11 +149,18 @@
|
||||
<HintPath>..\packages\Square.Picasso.2.5.2.1\lib\MonoAndroid\Square.Picasso.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=5.1.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IdentityModel.Tokens.Jwt.5.1.3\lib\netstandard1.4\System.IdentityModel.Tokens.Jwt.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Json" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="Validation, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Validation.2.2.8\lib\dotnet\Validation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.Animated.Vector.Drawable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -139,6 +176,9 @@
|
||||
<Reference Include="Xamarin.Android.Support.Core.Utils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.Android.Support.Core.Utils.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Core.Utils.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.CustomTabs, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.Android.Support.CustomTabs.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.CustomTabs.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Android.Support.Design, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.Android.Support.Design.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Design.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -166,6 +206,9 @@
|
||||
<Reference Include="Xamarin.Android.Support.Vector.Drawable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.Android.Support.Vector.Drawable.25.4.0.2\lib\MonoAndroid70\Xamarin.Android.Support.Vector.Drawable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.Auth, Version=1.5.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.Auth.1.5.0.3\lib\MonoAndroid10\Xamarin.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.GooglePlayServices.Auth, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.GooglePlayServices.Auth.42.1021.1\lib\MonoAndroid70\Xamarin.GooglePlayServices.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -178,9 +221,6 @@
|
||||
<Reference Include="Xamarin.GooglePlayServices.Basement, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.GooglePlayServices.Basement.42.1021.1\lib\MonoAndroid70\Xamarin.GooglePlayServices.Basement.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.GooglePlayServices.Identity, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.GooglePlayServices.Identity.42.1021.1\lib\MonoAndroid70\Xamarin.GooglePlayServices.Identity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.GooglePlayServices.Tasks, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.GooglePlayServices.Tasks.42.1021.1\lib\MonoAndroid70\Xamarin.GooglePlayServices.Tasks.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -202,6 +242,7 @@
|
||||
<Compile Include="Resources\Portable Class\FolderBrowse.cs" />
|
||||
<Compile Include="Resources\Portable Class\FolderTracks.cs" />
|
||||
<Compile Include="Resources\Portable Class\MusicPlayer.cs" />
|
||||
<Compile Include="Resources\Portable Class\OauthCallback.cs" />
|
||||
<Compile Include="Resources\Portable Class\Player.cs" />
|
||||
<Compile Include="Resources\Portable Class\Playlist.cs" />
|
||||
<Compile Include="Resources\Portable Class\PlaylistTracks.cs" />
|
||||
@@ -213,6 +254,7 @@
|
||||
<Compile Include="Resources\Portable Class\YoutubeEngine.cs" />
|
||||
<Compile Include="Resources\Portable Class\YtAdapter.cs" />
|
||||
<Compile Include="Resources\Portable Class\YtFile.cs" />
|
||||
<Compile Include="Resources\Portable Class\YtPlaylists.cs" />
|
||||
<Compile Include="Resources\Resource.Designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Resources\values\Folder.cs" />
|
||||
@@ -225,9 +267,7 @@
|
||||
<None Include="app.config" />
|
||||
<None Include="GettingStarted.Xamarin" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
<None Include="Properties\AndroidManifest.xml" />
|
||||
<None Include="Assets\AboutAssets.txt" />
|
||||
<AndroidResource Include="Resources\layout\MusicLayout.axml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
@@ -240,6 +280,9 @@
|
||||
<AndroidResource Include="Resources\layout\DownloadLayout.axml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
<AndroidAsset Include="Assets\client_secret.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AndroidAsset>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\Main.axml">
|
||||
@@ -425,9 +468,9 @@
|
||||
<Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Basement.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Basement.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Basement.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Basement.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Tasks.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Tasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Tasks.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Tasks.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Base.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Identity.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Identity.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Identity.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Identity.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.Base.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Xamarin.Android.Support.CustomTabs.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.CustomTabs.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Android.Support.CustomTabs.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.CustomTabs.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\NETStandard.Library.2.0.1\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\packages\NETStandard.Library.2.0.1\build\netstandard2.0\NETStandard.Library.targets')" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.Compat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Compat.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Compat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Compat.targets')" />
|
||||
@@ -447,9 +490,9 @@
|
||||
<Import Project="..\packages\Xamarin.GooglePlayServices.Basement.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Basement.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Basement.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Basement.targets')" />
|
||||
<Import Project="..\packages\Xamarin.GooglePlayServices.Tasks.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Tasks.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Tasks.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Tasks.targets')" />
|
||||
<Import Project="..\packages\Xamarin.GooglePlayServices.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Base.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Base.targets')" />
|
||||
<Import Project="..\packages\Xamarin.GooglePlayServices.Identity.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Identity.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Identity.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Identity.targets')" />
|
||||
<Import Project="..\packages\Xamarin.GooglePlayServices.Auth.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.Base.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.Base.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.Base.targets')" />
|
||||
<Import Project="..\packages\Xamarin.GooglePlayServices.Auth.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.42.1021.1\build\MonoAndroid70\Xamarin.GooglePlayServices.Auth.targets')" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.CustomTabs.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.CustomTabs.targets" Condition="Exists('..\packages\Xamarin.Android.Support.CustomTabs.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.CustomTabs.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">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="MusicApp.MusicApp" android:versionCode="1" android:versionName="1.0" android:installLocation="preferExternal">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.musicapp.android" android:versionCode="1" android:versionName="1.0" android:installLocation="preferExternal">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="25" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
Images, layout descriptions, binary blobs and string dictionaries can be included
|
||||
in your application as resource files. Various Android APIs are designed to
|
||||
operate on the resource IDs instead of dealing with images, strings or binary blobs
|
||||
directly.
|
||||
|
||||
For example, a sample Android app that contains a user interface layout (main.axml),
|
||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
|
||||
would keep its resources in the "Resources" directory of the application:
|
||||
|
||||
Resources/
|
||||
drawable/
|
||||
icon.png
|
||||
|
||||
layout/
|
||||
main.axml
|
||||
|
||||
values/
|
||||
strings.xml
|
||||
|
||||
In order to get the build system to recognize Android resources, set the build action to
|
||||
"AndroidResource". The native Android APIs do not operate directly with filenames, but
|
||||
instead operate on resource IDs. When you compile an Android application that uses resources,
|
||||
the build system will package the resources for distribution and generate a class called "R"
|
||||
(this is an Android convention) that contains the tokens for each one of the resources
|
||||
included. For example, for the above Resources layout, this is what the R class would expose:
|
||||
|
||||
public class R {
|
||||
public class drawable {
|
||||
public const int icon = 0x123;
|
||||
}
|
||||
|
||||
public class layout {
|
||||
public const int main = 0x456;
|
||||
}
|
||||
|
||||
public class strings {
|
||||
public const int first_string = 0xabc;
|
||||
public const int second_string = 0xbcd;
|
||||
}
|
||||
}
|
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
|
||||
to reference the layout/main.axml file, or R.strings.first_string to reference the first
|
||||
string in the dictionary file values/strings.xml.
|
||||
41
MusicApp/Resources/Portable Class/OauthCallback.cs
Normal file
41
MusicApp/Resources/Portable Class/OauthCallback.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
|
||||
namespace MusicApp.Resources.Portable_Class
|
||||
{
|
||||
[Activity(Label = "OauthCallback")]
|
||||
[
|
||||
IntentFilter
|
||||
(
|
||||
actions: new[] { Intent.ActionView },
|
||||
Categories = new[]
|
||||
{
|
||||
Intent.CategoryDefault,
|
||||
Intent.CategoryBrowsable
|
||||
},
|
||||
DataSchemes = new[]
|
||||
{
|
||||
"com.musicapp.android"
|
||||
},
|
||||
DataPaths = new[]
|
||||
{
|
||||
"/oauth2redirect"
|
||||
}
|
||||
)
|
||||
]
|
||||
public class OauthCallback : Activity
|
||||
{
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
Android.Net.Uri IntentUri = Intent.Data;
|
||||
Uri uri = new Uri(IntentUri.ToString());
|
||||
|
||||
MainActivity.auth?.OnPageLoading(uri);
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,6 @@ using Android.Content.PM;
|
||||
using Android.Support.Design.Widget;
|
||||
using Android;
|
||||
using Android.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Java.Util;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using MusicApp.Resources.values;
|
||||
using static Android.Provider.MediaStore.Audio;
|
||||
|
||||
namespace MusicApp.Resources.Portable_Class
|
||||
@@ -41,14 +36,6 @@ namespace MusicApp.Resources.Portable_Class
|
||||
|
||||
if(ListView.Adapter == null)
|
||||
GetStoragePermission();
|
||||
|
||||
//if(GoogleAccount != null)
|
||||
{
|
||||
if (YoutubeEngine.youtubeService == null)
|
||||
YoutubeEngine.CreateYoutube();
|
||||
|
||||
GetYoutubePlaylists();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
@@ -65,7 +52,7 @@ namespace MusicApp.Resources.Portable_Class
|
||||
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
View view = base.OnCreateView(inflater, container, savedInstanceState);
|
||||
view.SetPadding(0, 100, 0, MainActivity.paddingBot);
|
||||
view.SetPadding(0, 0, 0, MainActivity.paddingBot);
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -144,56 +131,6 @@ namespace MusicApp.Resources.Portable_Class
|
||||
}
|
||||
}
|
||||
|
||||
async void GetYoutubePlaylists()
|
||||
{
|
||||
while (YoutubeEngine.youtubeService == null)
|
||||
await Task.Delay(100);
|
||||
|
||||
HashMap parameters = new HashMap();
|
||||
parameters.Put("part", "snippet,contentDetails");
|
||||
parameters.Put("mine", "true");
|
||||
parameters.Put("maxResults", "25");
|
||||
parameters.Put("onBehalfOfContentOwner", "");
|
||||
parameters.Put("onBehalfOfContentOwnerChannel", "");
|
||||
|
||||
YouTubeService youtube = YoutubeEngine.youtubeService;
|
||||
|
||||
PlaylistsResource.ListRequest ytPlaylists = youtube.Playlists.List(parameters.Get("part").ToString());
|
||||
|
||||
if (parameters.ContainsKey("mine") && parameters.Get("mine").ToString() != "")
|
||||
{
|
||||
bool mine = (parameters.Get("mine").ToString() == "true") ? true : false;
|
||||
ytPlaylists.Mine = mine;
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("maxResults"))
|
||||
{
|
||||
ytPlaylists.MaxResults = long.Parse(parameters.Get("maxResults").ToString());
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("onBehalfOfContentOwner") && parameters.Get("onBehalfOfContentOwner").ToString() != "")
|
||||
{
|
||||
ytPlaylists.OnBehalfOfContentOwner = parameters.Get("onBehalfOfContentOwner").ToString();
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("onBehalfOfContentOwnerChannel") && parameters.Get("onBehalfOfContentOwnerChannel").ToString() != "")
|
||||
{
|
||||
ytPlaylists.OnBehalfOfContentOwnerChannel = parameters.Get("onBehalfOfContentOwnerChannel").ToString();
|
||||
}
|
||||
|
||||
PlaylistListResponse response = await ytPlaylists.ExecuteAsync();
|
||||
List<Song> ytList = new List<Song>();
|
||||
|
||||
for (int i = 0; i < response.Items.Count ; i++)
|
||||
{
|
||||
Google.Apis.YouTube.v3.Data.Playlist playlist = response.Items[i];
|
||||
Song song = new Song(playlist.Snippet.Title, playlist.Snippet.ChannelTitle, playlist.Snippet.Thumbnails.Default__.Url, -1, -1, playlist.Id, true);
|
||||
ytList.Add(song);
|
||||
}
|
||||
|
||||
Adapter ytAdapter = new Adapter(Android.App.Application.Context, Resource.Layout.SongList, ytList);
|
||||
}
|
||||
|
||||
private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
|
||||
{
|
||||
AppCompatActivity act = (AppCompatActivity)Activity;
|
||||
@@ -291,8 +228,8 @@ namespace MusicApp.Resources.Portable_Class
|
||||
void RemovePlaylist(int position, long playlistID)
|
||||
{
|
||||
ContentResolver resolver = Activity.ContentResolver;
|
||||
Uri uri = MediaStore.Audio.Playlists.ExternalContentUri;
|
||||
resolver.Delete(MediaStore.Audio.Playlists.ExternalContentUri, MediaStore.Audio.Playlists.InterfaceConsts.Id + "=?", new string[] { playlistID.ToString() });
|
||||
Uri uri = Playlists.ExternalContentUri;
|
||||
resolver.Delete(Playlists.ExternalContentUri, Playlists.InterfaceConsts.Id + "=?", new string[] { playlistID.ToString() });
|
||||
playList.RemoveAt(position);
|
||||
playlistId.RemoveAt(position);
|
||||
ListAdapter = new ArrayAdapter(Android.App.Application.Context, Resource.Layout.PlaylistList, playList);
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace MusicApp.Resources.Portable_Class
|
||||
public Adapter adapter;
|
||||
public View emptyView;
|
||||
public List<Song> result;
|
||||
public long playlistId;
|
||||
public long playlistId = 0;
|
||||
public string ytID = "";
|
||||
public bool isEmpty = false;
|
||||
|
||||
private List<Song> tracks = new List<Song>();
|
||||
@@ -75,53 +76,63 @@ namespace MusicApp.Resources.Portable_Class
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Fragment NewInstance(string ytID)
|
||||
{
|
||||
instance = new PlaylistTracks { Arguments = new Bundle() };
|
||||
instance.ytID = ytID;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void PopulateList()
|
||||
{
|
||||
Uri musicUri = MediaStore.Audio.Playlists.Members.GetContentUri("external", playlistId);
|
||||
|
||||
CursorLoader cursorLoader = new CursorLoader(Android.App.Application.Context, musicUri, null, null, null, null);
|
||||
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
|
||||
|
||||
if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
if(playlistId != 0)
|
||||
{
|
||||
int titleID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Title);
|
||||
int artistID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Artist);
|
||||
int albumID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Album);
|
||||
int thisID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Id);
|
||||
int pathID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data);
|
||||
do
|
||||
Uri musicUri = MediaStore.Audio.Playlists.Members.GetContentUri("external", playlistId);
|
||||
|
||||
CursorLoader cursorLoader = new CursorLoader(Android.App.Application.Context, musicUri, null, null, null, null);
|
||||
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
|
||||
|
||||
if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
{
|
||||
string Artist = musicCursor.GetString(artistID);
|
||||
string Title = musicCursor.GetString(titleID);
|
||||
string Album = musicCursor.GetString(albumID);
|
||||
long AlbumArt = musicCursor.GetLong(musicCursor.GetColumnIndex(MediaStore.Audio.Albums.InterfaceConsts.AlbumId));
|
||||
long id = musicCursor.GetLong(thisID);
|
||||
string path = musicCursor.GetString(pathID);
|
||||
int titleID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Title);
|
||||
int artistID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Artist);
|
||||
int albumID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Album);
|
||||
int thisID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Id);
|
||||
int pathID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data);
|
||||
do
|
||||
{
|
||||
string Artist = musicCursor.GetString(artistID);
|
||||
string Title = musicCursor.GetString(titleID);
|
||||
string Album = musicCursor.GetString(albumID);
|
||||
long AlbumArt = musicCursor.GetLong(musicCursor.GetColumnIndex(MediaStore.Audio.Albums.InterfaceConsts.AlbumId));
|
||||
long id = musicCursor.GetLong(thisID);
|
||||
string path = musicCursor.GetString(pathID);
|
||||
|
||||
if (Title == null)
|
||||
Title = "Unknown Title";
|
||||
if (Artist == null)
|
||||
Artist = "Unknow Artist";
|
||||
if (Album == null)
|
||||
Album = "Unknow Album";
|
||||
if (Title == null)
|
||||
Title = "Unknown Title";
|
||||
if (Artist == null)
|
||||
Artist = "Unknow Artist";
|
||||
if (Album == null)
|
||||
Album = "Unknow Album";
|
||||
|
||||
tracks.Add(new Song(Title, Artist, Album, AlbumArt, id, path));
|
||||
tracks.Add(new Song(Title, Artist, Album, AlbumArt, id, path));
|
||||
}
|
||||
while (musicCursor.MoveToNext());
|
||||
musicCursor.Close();
|
||||
}
|
||||
while (musicCursor.MoveToNext());
|
||||
musicCursor.Close();
|
||||
}
|
||||
|
||||
adapter = new Adapter(Android.App.Application.Context, Resource.Layout.SongList, tracks);
|
||||
ListAdapter = adapter;
|
||||
ListView.TextFilterEnabled = true;
|
||||
ListView.ItemClick += ListView_ItemClick;
|
||||
ListView.ItemLongClick += ListView_ItemLongClick;
|
||||
adapter = new Adapter(Android.App.Application.Context, Resource.Layout.SongList, tracks);
|
||||
ListAdapter = adapter;
|
||||
ListView.TextFilterEnabled = true;
|
||||
ListView.ItemClick += ListView_ItemClick;
|
||||
ListView.ItemLongClick += ListView_ItemLongClick;
|
||||
|
||||
if (adapter == null || adapter.Count == 0)
|
||||
{
|
||||
isEmpty = true;
|
||||
Activity.AddContentView(emptyView, View.LayoutParameters);
|
||||
if (adapter == null || adapter.Count == 0)
|
||||
{
|
||||
isEmpty = true;
|
||||
Activity.AddContentView(emptyView, View.LayoutParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,10 @@ using Android.Support.Design.Widget;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Android.Gms.Common.Apis;
|
||||
using System.Collections.Generic;
|
||||
using Google.Apis.Services;
|
||||
using Android.Preferences;
|
||||
using YoutubeExplode;
|
||||
using System.Linq;
|
||||
using MusicApp.Resources.values;
|
||||
using System.Threading.Tasks;
|
||||
using Android.Support.V7.App;
|
||||
|
||||
namespace MusicApp.Resources.Portable_Class
|
||||
@@ -27,7 +25,6 @@ namespace MusicApp.Resources.Portable_Class
|
||||
private bool isEmpty = true;
|
||||
private string[] actions = new string[] { "Play", "Play Next", "Play Last", "Download" };
|
||||
|
||||
public const string ApiKey = "AIzaSyBOQyZVnBAKjur0ztBuYPSopS725Qudgc4";
|
||||
private string videoID;
|
||||
|
||||
public override void OnActivityCreated(Bundle savedInstanceState)
|
||||
@@ -49,22 +46,8 @@ namespace MusicApp.Resources.Portable_Class
|
||||
Activity.AddContentView(emptyView, View.LayoutParameters);
|
||||
}
|
||||
|
||||
CreateYoutube();
|
||||
}
|
||||
|
||||
public static async void CreateYoutube()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (youtubeService == null)
|
||||
{
|
||||
youtubeService = new YouTubeService(new BaseClientService.Initializer()
|
||||
{
|
||||
ApiKey = ApiKey,
|
||||
ApplicationName = "MusicApp"
|
||||
});
|
||||
}
|
||||
});
|
||||
if(youtubeService == null)
|
||||
MainActivity.instance.Login();
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
@@ -95,6 +78,11 @@ namespace MusicApp.Resources.Portable_Class
|
||||
if (search == null || search == "")
|
||||
return;
|
||||
|
||||
if (MainActivity.instance.TokenHasExpire())
|
||||
{
|
||||
MainActivity.instance.Login();
|
||||
}
|
||||
|
||||
SearchResource.ListRequest searchResult = youtubeService.Search.List("snippet");
|
||||
searchResult.Fields = "items(id/videoId,snippet/title,snippet/thumbnails/default/url,snippet/channelTitle)";
|
||||
searchResult.Q = search;
|
||||
|
||||
238
MusicApp/Resources/Portable Class/YtPlaylists.cs
Normal file
238
MusicApp/Resources/Portable Class/YtPlaylists.cs
Normal file
@@ -0,0 +1,238 @@
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Support.V7.App;
|
||||
using Android.Support.V4.App;
|
||||
using System.Collections.Generic;
|
||||
using Android.Provider;
|
||||
using Android.Database;
|
||||
using Android.Content.PM;
|
||||
using Android.Support.Design.Widget;
|
||||
using Android;
|
||||
using Android.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Java.Util;
|
||||
using Google.Apis.YouTube.v3;
|
||||
using Google.Apis.YouTube.v3.Data;
|
||||
using MusicApp.Resources.values;
|
||||
using Java.IO;
|
||||
using Google.Apis.Auth.OAuth2;
|
||||
using System.IO;
|
||||
using Google.Apis.Auth.OAuth2.Flows;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
using Google.Apis.Util.Store;
|
||||
|
||||
namespace MusicApp.Resources.Portable_Class
|
||||
{
|
||||
public class YtPlaylist : ListFragment
|
||||
{
|
||||
public static YtPlaylist instance;
|
||||
public Adapter adapter;
|
||||
public View emptyView;
|
||||
public static Credentials credentials;
|
||||
|
||||
private List<Song> playlists = new List<Song>();
|
||||
private string[] actions = new string[] { "Random play", "Rename", "Delete" };
|
||||
private bool isEmpty = false;
|
||||
|
||||
|
||||
public override void OnActivityCreated(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnActivityCreated(savedInstanceState);
|
||||
emptyView = LayoutInflater.Inflate(Resource.Layout.NoPlaylist, null);
|
||||
ListView.EmptyView = emptyView;
|
||||
|
||||
if (YoutubeEngine.youtubeService == null)
|
||||
MainActivity.instance.Login();
|
||||
|
||||
GetYoutubePlaylists();
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
if (isEmpty)
|
||||
{
|
||||
ViewGroup rootView = Activity.FindViewById<ViewGroup>(Android.Resource.Id.Content);
|
||||
rootView.RemoveView(emptyView);
|
||||
}
|
||||
base.OnDestroy();
|
||||
instance = null;
|
||||
}
|
||||
|
||||
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
View view = base.OnCreateView(inflater, container, savedInstanceState);
|
||||
view.SetPadding(0, 100, 0, MainActivity.paddingBot);
|
||||
return view;
|
||||
}
|
||||
|
||||
public static Fragment NewInstance()
|
||||
{
|
||||
instance = new YtPlaylist { Arguments = new Bundle() };
|
||||
return instance;
|
||||
}
|
||||
|
||||
async void GetYoutubePlaylists()
|
||||
{
|
||||
while (YoutubeEngine.youtubeService == null)
|
||||
await Task.Delay(100);
|
||||
|
||||
System.Console.WriteLine("getting playlists");
|
||||
|
||||
HashMap parameters = new HashMap();
|
||||
parameters.Put("part", "snippet,contentDetails");
|
||||
parameters.Put("mine", "true");
|
||||
parameters.Put("maxResults", "25");
|
||||
parameters.Put("onBehalfOfContentOwner", "");
|
||||
parameters.Put("onBehalfOfContentOwnerChannel", "");
|
||||
|
||||
YouTubeService youtube = YoutubeEngine.youtubeService;
|
||||
|
||||
PlaylistsResource.ListRequest ytPlaylists = youtube.Playlists.List(parameters.Get("part").ToString());
|
||||
|
||||
if (parameters.ContainsKey("mine") && parameters.Get("mine").ToString() != "")
|
||||
{
|
||||
bool mine = (parameters.Get("mine").ToString() == "true") ? true : false;
|
||||
ytPlaylists.Mine = mine;
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("maxResults"))
|
||||
{
|
||||
ytPlaylists.MaxResults = long.Parse(parameters.Get("maxResults").ToString());
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("onBehalfOfContentOwner") && parameters.Get("onBehalfOfContentOwner").ToString() != "")
|
||||
{
|
||||
ytPlaylists.OnBehalfOfContentOwner = parameters.Get("onBehalfOfContentOwner").ToString();
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("onBehalfOfContentOwnerChannel") && parameters.Get("onBehalfOfContentOwnerChannel").ToString() != "")
|
||||
{
|
||||
ytPlaylists.OnBehalfOfContentOwnerChannel = parameters.Get("onBehalfOfContentOwnerChannel").ToString();
|
||||
}
|
||||
|
||||
PlaylistListResponse response = await ytPlaylists.ExecuteAsync();
|
||||
playlists = new List<Song>();
|
||||
|
||||
for (int i = 0; i < response.Items.Count; i++)
|
||||
{
|
||||
Google.Apis.YouTube.v3.Data.Playlist playlist = response.Items[i];
|
||||
Song song = new Song(playlist.Snippet.Title, playlist.Snippet.ChannelTitle, playlist.Snippet.Thumbnails.Default__.Url, -1, -1, playlist.Id, true);
|
||||
playlists.Add(song);
|
||||
}
|
||||
|
||||
Adapter ytAdapter = new Adapter(Android.App.Application.Context, Resource.Layout.SongList, playlists);
|
||||
}
|
||||
|
||||
private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
|
||||
{
|
||||
AppCompatActivity act = (AppCompatActivity)Activity;
|
||||
act.SupportActionBar.SetHomeButtonEnabled(true);
|
||||
act.SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||
act.SupportActionBar.Title = playlists[e.Position].GetName();
|
||||
FragmentTransaction transaction = FragmentManager.BeginTransaction();
|
||||
transaction.Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(playlists[e.Position].GetPath()));
|
||||
transaction.AddToBackStack(null);
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
private void ListView_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
|
||||
{
|
||||
//AlertDialog.Builder builder = new AlertDialog.Builder(Activity, Resource.Style.AppCompatAlertDialogStyle);
|
||||
//builder.SetTitle("Pick an action");
|
||||
//builder.SetItems(actions, (senderAlert, args) =>
|
||||
//{
|
||||
// switch (args.Which)
|
||||
// {
|
||||
// case 0:
|
||||
// RandomPlay(playlists[e.Position].GetPath());
|
||||
// break;
|
||||
// case 1:
|
||||
// Rename(e.Position, playlistId[e.Position]);
|
||||
// break;
|
||||
// case 2:
|
||||
// RemovePlaylist(e.Position, playlistId[e.Position]);
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//});
|
||||
//builder.Show();
|
||||
}
|
||||
|
||||
void RandomPlay(long playlistID)
|
||||
{
|
||||
List<string> tracksPath = new List<string>();
|
||||
Uri musicUri = MediaStore.Audio.Playlists.Members.GetContentUri("external", playlistID);
|
||||
|
||||
CursorLoader cursorLoader = new CursorLoader(Android.App.Application.Context, musicUri, null, null, null, null);
|
||||
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
|
||||
|
||||
if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
{
|
||||
int pathID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data);
|
||||
do
|
||||
{
|
||||
string path = musicCursor.GetString(pathID);
|
||||
|
||||
tracksPath.Add(path);
|
||||
}
|
||||
while (musicCursor.MoveToNext());
|
||||
musicCursor.Close();
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Android.App.Application.Context, typeof(MusicPlayer));
|
||||
intent.PutStringArrayListExtra("files", tracksPath);
|
||||
intent.SetAction("RandomPlay");
|
||||
Activity.StartService(intent);
|
||||
}
|
||||
|
||||
void Rename(int position, long playlistID)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(Activity, Resource.Style.AppCompatAlertDialogStyle);
|
||||
builder.SetTitle("Playlist name");
|
||||
View view = LayoutInflater.Inflate(Resource.Layout.CreatePlaylistDialog, null);
|
||||
builder.SetView(view);
|
||||
builder.SetNegativeButton("Cancel", (senderAlert, args) => { });
|
||||
builder.SetPositiveButton("Rename", (senderAlert, args) =>
|
||||
{
|
||||
RenamePlaylist(position, view.FindViewById<EditText>(Resource.Id.playlistName).Text, playlistID);
|
||||
});
|
||||
builder.Show();
|
||||
}
|
||||
|
||||
void RenamePlaylist(int position, string name, long playlistID)
|
||||
{
|
||||
//ContentResolver resolver = Activity.ContentResolver;
|
||||
//Uri uri = MediaStore.Audio.Playlists.ExternalContentUri;
|
||||
//ContentValues value = new ContentValues();
|
||||
//value.Put(MediaStore.Audio.Playlists.InterfaceConsts.Name, name);
|
||||
//resolver.Update(MediaStore.Audio.Playlists.ExternalContentUri, value, MediaStore.Audio.Playlists.InterfaceConsts.Id + "=?", new string[] { playlistID.ToString() });
|
||||
//playList[position] = name;
|
||||
//ListAdapter = new ArrayAdapter(Android.App.Application.Context, Resource.Layout.PlaylistList, playList);
|
||||
//if (ListAdapter.Count == 0)
|
||||
//{
|
||||
// isEmpty = true;
|
||||
// Activity.AddContentView(emptyView, View.LayoutParameters);
|
||||
//}
|
||||
}
|
||||
|
||||
void RemovePlaylist(int position, long playlistID)
|
||||
{
|
||||
//ContentResolver resolver = Activity.ContentResolver;
|
||||
//Uri uri = MediaStore.Audio.Playlists.ExternalContentUri;
|
||||
//resolver.Delete(MediaStore.Audio.Playlists.ExternalContentUri, MediaStore.Audio.Playlists.InterfaceConsts.Id + "=?", new string[] { playlistID.ToString() });
|
||||
//playList.RemoveAt(position);
|
||||
//playlistId.RemoveAt(position);
|
||||
//ListAdapter = new ArrayAdapter(Android.App.Application.Context, Resource.Layout.PlaylistList, playList);
|
||||
//if (ListAdapter.Count == 0)
|
||||
//{
|
||||
// isEmpty = true;
|
||||
// Activity.AddContentView(emptyView, View.LayoutParameters);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
818
MusicApp/Resources/Resource.Designer.cs
generated
818
MusicApp/Resources/Resource.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -5,10 +5,20 @@
|
||||
<package id="Google.Apis.Core" version="1.30.0" targetFramework="monoandroid70" />
|
||||
<package id="Google.Apis.YouTube.v3" version="1.30.0.1035" targetFramework="monoandroid70" />
|
||||
<package id="Microsoft.CSharp" version="4.4.0" targetFramework="monoandroid70" />
|
||||
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="1.1.0" targetFramework="monoandroid71" />
|
||||
<package id="Microsoft.Extensions.Logging" version="1.1.1" targetFramework="monoandroid71" />
|
||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.1" targetFramework="monoandroid71" />
|
||||
<package id="Microsoft.IdentityModel.Logging" version="1.1.3" targetFramework="monoandroid71" />
|
||||
<package id="Microsoft.IdentityModel.Tokens" version="5.1.3" targetFramework="monoandroid71" />
|
||||
<package id="Microsoft.NETCore.Platforms" version="2.0.0" targetFramework="monoandroid70" />
|
||||
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="NETStandard.Library" version="2.0.1" targetFramework="monoandroid70" />
|
||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="monoandroid70" />
|
||||
<package id="PCLCrypto" version="2.0.147" targetFramework="monoandroid71" />
|
||||
<package id="PInvoke.BCrypt" version="0.3.2" targetFramework="monoandroid71" />
|
||||
<package id="PInvoke.Kernel32" version="0.3.2" targetFramework="monoandroid71" />
|
||||
<package id="PInvoke.NCrypt" version="0.3.2" targetFramework="monoandroid71" />
|
||||
<package id="PInvoke.Windows.Core" version="0.3.2" targetFramework="monoandroid71" />
|
||||
<package id="Plugin.CurrentActivity" version="1.0.1" targetFramework="monoandroid70" />
|
||||
<package id="Plugin.MediaManager" version="0.4.5" targetFramework="monoandroid70" />
|
||||
<package id="Plugin.Permissions" version="2.1.0" targetFramework="monoandroid70" />
|
||||
@@ -18,6 +28,7 @@
|
||||
<package id="System.AppContext" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Collections" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.ComponentModel" version="4.3.0" targetFramework="monoandroid71" />
|
||||
<package id="System.ComponentModel.TypeConverter" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Console" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="monoandroid70" />
|
||||
@@ -26,6 +37,7 @@
|
||||
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Globalization" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Globalization.Calendars" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.IdentityModel.Tokens.Jwt" version="5.1.3" targetFramework="monoandroid71" />
|
||||
<package id="System.IO" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.IO.Compression" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="monoandroid70" />
|
||||
@@ -51,6 +63,7 @@
|
||||
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Runtime.Serialization.Formatters" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Runtime.Serialization.Primitives" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Security.Claims" version="4.3.0" targetFramework="monoandroid71" />
|
||||
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="monoandroid70" />
|
||||
@@ -64,6 +77,7 @@
|
||||
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="monoandroid70" />
|
||||
<package id="Validation" version="2.2.8" targetFramework="monoandroid71" />
|
||||
<package id="Xam.Plugins.Android.ExoPlayer" version="2.5.3" targetFramework="monoandroid70" />
|
||||
<package id="Xam.Plugins.Android.ExoPlayer.Core" version="2.5.3" targetFramework="monoandroid70" />
|
||||
<package id="Xam.Plugins.Android.ExoPlayer.Dash" version="2.5.3" targetFramework="monoandroid70" />
|
||||
@@ -75,6 +89,7 @@
|
||||
<package id="Xamarin.Android.Support.Compat" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Android.Support.Core.UI" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Android.Support.Core.Utils" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Android.Support.CustomTabs" version="25.4.0.2" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Android.Support.Design" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Android.Support.Fragment" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Android.Support.Media.Compat" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
@@ -84,12 +99,12 @@
|
||||
<package id="Xamarin.Android.Support.v7.Preference" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Android.Support.v7.RecyclerView" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Android.Support.Vector.Drawable" version="25.4.0.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.Auth" version="1.5.0.3" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.Build.Download" version="0.4.2" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.GooglePlayServices.Auth" version="42.1021.1" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.GooglePlayServices.Auth.Base" version="42.1021.1" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.GooglePlayServices.Base" version="42.1021.1" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.GooglePlayServices.Basement" version="42.1021.1" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.GooglePlayServices.Identity" version="42.1021.1" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.GooglePlayServices.Tasks" version="42.1021.1" targetFramework="monoandroid70" />
|
||||
<package id="Xamarin.GooglePlayServices.Auth" version="42.1021.1" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.GooglePlayServices.Auth.Base" version="42.1021.1" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.GooglePlayServices.Base" version="42.1021.1" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.GooglePlayServices.Basement" version="42.1021.1" targetFramework="monoandroid71" />
|
||||
<package id="Xamarin.GooglePlayServices.Tasks" version="42.1021.1" targetFramework="monoandroid71" />
|
||||
<package id="YoutubeExplode" version="3.2.5" targetFramework="monoandroid70" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user