Xamarin Android Facebook share button disabled - facebook

Hope You're all ok.
I have a simple xamarin android application, and trying to integrate facebook share button in it.
I've done all by docs, and other tutorials. App is registered in Facebook.
But the button is showing gray in app, it's disabled.
I don't know what's the problem.
Testing it in Nexus 5, with Android M 6.0.1.
Thanks.
Little update on what I've done so far.
Manifest File
Manifest File
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/app_id" />
<activity android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:label="#string/ApplicationName" />
<provider android:authorities="com.facebook.app.FacebookContentProvider266540057101076" android:name="com.facebook.FacebookContentProvider" android:exported="true" />
Activity file code snippet
<com.facebook.share.widget.ShareButton
android:id="#+id/fShareButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal" />
And finally controller.
private ShareButton fShareButton;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
getKeyHashes();
FacebookSdk.SdkInitialize(ApplicationContext);
SetContentView(Resource.Layout.details);
fShareButton = FindViewById<ShareButton>(Resource.Id.fShareButton);
fShareButton.Click += FShareButton_Click;
..........
}
private void FShareButton_Click(object sender, EventArgs e)
{
#region Facebook Share Button
View v1 = Window.DecorView.RootView;
v1.DrawingCacheEnabled = true;
Android.Graphics.Bitmap bitmap = Android.Graphics.Bitmap.CreateBitmap(v1.GetDrawingCache(true));
var photoBuilder = new SharePhoto.Builder();
photoBuilder.SetBitmap(bitmap);
var photo = photoBuilder.Build().JavaCast<SharePhoto>();
var photos = new List<SharePhoto>();
photos.Add(photo);
SharePhotoContent photoContent = new SharePhotoContent.Builder().SetPhotos(photos).Build();
fShareButton.ShareContent = photoContent;
#endregion
}

You must set callbackManager and fill ShareContent property in ShareButton, in my example I use ShareLinkContent for the content, but there are other options like "ShareMediaContent", "SharePhotContent", etc., you can get more explanaition about this in https://developers.facebook.com/docs/sharing/android/?locale=en_US :
fShareButton = FindViewById<ShareButton>(Resource.Id.fShareButton);
callbackManager = CallbackManagerFactory.Create();
fShareButton.RegisterCallback(callbackManager, this);
var content = new ShareLinkContent.Builder();
content.SetContentUrl(Android.Net.Uri.Parse("https://www.mivinco.com/linkapp_an9.html"));
var hashtag = new ShareHashtag.Builder();
hashtag.SetHashtag("#porqueTuExperienciaCuenta");
content.SetShareHashtag((ShareHashtag)hashtag.Build());
fShareButton.ShareContent = content.Build();
Also, you should implement IFacebookCallback interface in your activity:
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
callbackManager.OnActivityResult(requestCode, (int)resultCode, data);
}
It works fine in my Android app. Let me know if it works fine in your app too.

Related

How to play text to speech using xamarin.essential

I want to play text to speech but I can't hear anything using Xamarin.essential. I 'm sure I don't have muted smartphone. The code:
using Xamarin.Essential
private void PlayTextMethod()
{
if(do sth)
{
SpeekFrommethodAsync();
}
}
private async SpeekFrommethodAsync()
{
await TextToSpeech.SpeakAsync(Tasklabel.Text, new SpeechOptions
{
Volume = 1f
});
}
If your project's Target Android version is set to Android 11 (R API 30),
Open the AndroidManifest.xml file under the Properties folder and add the following inside of the manifest node:
<queries>
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />
</intent>
</queries>
And try this in your method:
public async Task SpeakNow()
{
var locales = await TextToSpeech.GetLocalesAsync();
// Grab the first locale
var locale = locales.FirstOrDefault();
var settings = new SpeechOptions()
{
Volume = .75f,
Pitch = 1.0f,
Locale = locale
};
await TextToSpeech.SpeakAsync("Hello World", settings);
}
Refer: https://learn.microsoft.com/en-us/xamarin/essentials/text-to-speech?context=xamarin%2Fandroid&tabs=android
I made a demo and I tested it on the Android 12 emulator. I found the Text-to-speech function can not speak the words which belong to another country. So I added a picker to choose the country.
Here is the code in MainPage.xaml
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Text to speech sample!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
</Frame>
<Picker x:Name="Languages"></Picker>
<Entry x:Name="TextToSpeak"></Entry>
<Button Text="Speak Please" Clicked="Button_Clicked"></Button>
</StackLayout>
And here is the code in MainPage.xaml.cs.
using Xamarin.Essentials;
public partial class MainPage : ContentPage
{
IEnumerable<Locale> locales;
public MainPage()
{
InitializeComponent();
}
protected async override void OnAppearing()
{
base.OnAppearing();
locales = await TextToSpeech.GetLocalesAsync();
// add the locales to the picker
foreach(var locale in locales)
{
Languages.Items.Add(locale.Name);
}
}
// realize the button
private void Button_Clicked(object sender, EventArgs e)
{
if(Languages.SelectedIndex > 0)
{
// use the TextToSpeech to read the words in the Entry.
TextToSpeech.SpeakAsync(TextToSpeak.Text, new SpeechOptions
{
Locale = locales.Single(locales=> locales.Name == Languages.SelectedItem.ToString())
});
}
}
}
This is the view of the project.

How to share information between pages

Before starting, as is stated in the title, I'm learning .NET MAUI and I'm very new in this.
My problem is that I can't find a way to share information from a page to a previous page.
What I'm trying to do is the following:
In the MainPage, have a button that once pressed, sends the user to another page, let's call it LoginPage, there, ask the user for his name, and after the input, redirect him to the previous page showing an "Hello {Name}, and welcome!"
MainPage code:
string Name = "";
string greetings = "";
async private void LogintBtn_Clicked(object sender, EventArgs e)
{
{
await Navigation.PushAsync(new LoginPage());
}
greetings = $"Welcome {Name}!";
Greetinglbl.Text = greetings;
}
Log in code:
public string name { get; set; }
private void btnRegister_Clicked(object sender, EventArgs e)
{
if (ValidateName()==false) { return; };
Navigation.PopAsync();
}
private bool ValidateName()
{
if (string.IsNullOrWhiteSpace(txtRegistro.Text))
{
return false;
}
else
return true;
}
Beside this, I don't know how to share information between these pages.
I have seen that a lot of devs use MVVM but I can't get a Beginners guide propperly, even watching the .NET MAUI Beginners Guides from James Montemagno doesn't help me.
I've also tried using something like
await Shell.Current.GoToAsync($"LoginPage?Name={Name}");
that, for what I read is used to send data but don't know where to put it, plus triying to navigate with the same line throws an error (null).
Plus, most of the videos only shows how to send Data to the next Page, not the previous, and usually to a collection, and some of them import NuGet Packages that I don't see to be necessary in this project.
In your scenario, you could share the data through Constructor, here's the code snippet below for your reference.
MainPage:
Xaml:
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Label Text="MainPage"></Label>
<Button
Text="To Login Page"
Clicked="OnClicked"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ScrollView>
Code-behind:
      public MainPage()
      {
            InitializeComponent();
      }
public MainPage(string a)
{
InitializeComponent();
      
            App.Current.MainPage.DisplayAlert("Welcome Back",a,"OK");
}
private async void OnClicked(object sender, EventArgs e)
      {
            await Navigation.PushAsync(new LoginPage());
      }
LoginPage:
Xaml:
<VerticalStackLayout>
<Label Text="LoginPage"></Label>
<Entry x:Name="myentry"/>
<Button
Text="ToMain"
Clicked="BackTo"
HorizontalOptions="Center" />
</VerticalStackLayout>
Code-behind:
public LoginPage()
      {
            InitializeComponent();
      }
private async void BackTo(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new MainPage(myentry.Text));
}
Last but not least, in your App.xaml.cs, use it like below:
MainPage = new NaviagtionPage(new MainPage())

getting actionbar null in my xamarin.andoird application

I am new to xamarin.android native. i am learning and developing this app from this tutorial
Tutorial Video link
but i am getting nullreference exception beacuse my actionbar is null.tutorial auther shared source code also.i ahve done same still its not working in my app.
this is my code:
MainMenuPage.axml
<?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/fragmentContainer"
android:layout_height="match_parent"
android:layout_width="match_parent" />
</LinearLayout>
MainActivity.cs
[Activity(Label = "HotDogMenuActivityWithTabs",Icon = "#drawable/smallicon",Theme = "#style/AppTheme")]
public class HotDogMenuActivityWithTabs : Activity
{
private ListView hotDogListView;
private List<HotDog> allHotDogs;
private HotDogDataService hotDogDataService;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
ActionBar.NavigationMode = ActionBarNavigationMode.Tabs;
AddTab("Favorites", Resource.Drawable.FavoritesIcon, new FavoriteHotDogFragment());
AddTab("Meat Lovers", Resource.Drawable.MeatLoversIcon, new MeatLoversFragment());
AddTab("Veggie Lovers", Resource.Drawable.veggieloversicon, new VeggieLoversFragment());
}
private void AddTab(string tabText, int iconResourceId, Fragment view)
{
var tab = this.ActionBar.NewTab();
tab.SetText(tabText);
tab.SetIcon(iconResourceId);//TODO
tab.TabSelected += delegate (object sender, Android.App.ActionBar.TabEventArgs e)
{
var fragment = this.FragmentManager.FindFragmentById(Resource.Id.fragmentContainer);
if (fragment != null)
e.FragmentTransaction.Remove(fragment);
e.FragmentTransaction.Add(Resource.Id.fragmentContainer, view);
};
tab.TabUnselected += delegate (object sender, Android.App.ActionBar.TabEventArgs e)
{
e.FragmentTransaction.Remove(view);
};
this.ActionBar.AddTab(tab);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok && requestCode == 100)
{
var selectedHotDog = hotDogDataService.GetHotDogById(data.GetIntExtra("selectedHotDogId", 0));
var dialog = new Android.App.AlertDialog.Builder(this);
dialog.SetTitle("Confirmation");
dialog.SetMessage(string.Format("You've added {0} time(s) the {1}", data.GetIntExtra("amount", 0), selectedHotDog.Name));
dialog.Show();
}
}
}
Style.xaml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar" >
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
what is wrong i am doing here.please help
tahnkx in advance.

Start Activity Intent from Android Application

I have an activity that holds a handler that I need to be running for the whole app. What I need to do is call the handler activity whenever main activity starts up, then upon executing a function at handler activity, handler activity should start the intent into second activity.
This is my code:
public class MyApp extends Application {
public void onCreate() {
h = new Handler() {
#Override
public void handleMessage(Message msg) {
Bundle b = msg.getData();
Log.d("tag",b.getString("msg"));
//THIS IS WHERE I WANT TO OPEN SECONDACTIVITY
}
};
}
}
MyApp is a global Application class I use to run a socket connection across the whole app. It needs to be alive as long as the app is running.
Its simple
Intent intent = new Intent(YourActivityClass.this, SECONDACTIVITY.class);
startActivity(intent);
public class MyApp extends Application {
public void onCreate() {
h = new Handler() {
#Override
public void handleMessage(Message msg) {
Bundle b = msg.getData();
Log.d("tag",b.getString("msg"));
Intent myIntent = new Intent(this, YourSecondActivity.class);
startActivity(myIntent);
}
};
}
}
Also add this to your manifest file
<activity android:name=".YourSecondActivity" />
Well, It turns out that I need to add: i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent i = new Intent(MyApp.this, SecondActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
Because From MainActivity, I called MyApp (An class to maintain global application state). Then in MyApp, I process something and then I call SecondActivity.
First You add the activity information in AndroidManifest.xml LIKE
<activity
android:name="com.assignment.matchnumber.PlayActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.assignment.matchnumber.PLAY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Then put this in your MyApp activity where you want.
Intent openPlayActivity = new Intent("com.assignment.matchnumber.PLAY");
startActivity(openPlayActivity);
thanks
--Sajib

Video customview in full screen exits when toggling the device screen in android

I am developing an android application which is purely web based. It needs to display HTML5 based webpages using webview which is rich in multimedia contents. when I try to play video content embedded in the webpage its all gone fine and i am also able to play video in full screen.
But my main problem starts here: When I toggled the device screen while playing fullscreen video, it suddenly exits from playback to its current web page. I am stucked here and here I am including all codes that I used as I can in hopes someone can help me.
Activity that is used: MainActivity.java
`
public class MainActivity extends Activity {
private WebView webView;
private FrameLayout customViewContainer;
private WebChromeClient.CustomViewCallback customViewCallback;
private View mCustomView;
private MyWebViewClient mWebViewClient;
private MyWebChromeClient mWebChromeClient;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customViewContainer = (FrameLayout) findViewById(R.id.customViewContainer);
webView = (WebView) findViewById(R.id.webView);
mWebViewClient = new MyWebViewClient();
webView.setWebViewClient(mWebViewClient);
mWebChromeClient = new MyWebChromeClient();
webView.setWebChromeClient(mWebChromeClient);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setSaveFormData(true);
webView.loadUrl("http://yuotube.com");
}
public boolean inCustomView() {
return (mCustomView != null);
}
public void hideCustomView() {
mWebChromeClient.onHideCustomView();
}
#Override
protected void onPause() {
super.onPause(); //To change body of overridden methods use File | Settings | File Templates.
webView.onPause();
}
#Override
protected void onResume() {
super.onResume(); //To change body of overridden methods use File | Settings | File Templates.
webView.onResume();
}
#Override
protected void onStop() {
super.onStop(); //To change body of overridden methods use File | Settings | File Templates.
if (inCustomView()) {
hideCustomView();
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (inCustomView()) {
hideCustomView();
return true;
}
if ((mCustomView == null) && webView.canGoBack()) {
webView.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
// WebChromeClient Class
public class MyWebChromeClient extends WebChromeClient {
private Bitmap mDefaultVideoPoster;
private View mVideoProgressView;
#Override
public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
onShowCustomView(view, callback); //To change body of overridden methods use File | Settings | File Templates.
}
#Override
public void onShowCustomView(View view,CustomViewCallback callback) {
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomView = view;
webView.setVisibility(View.GONE);
customViewContainer.setVisibility(View.VISIBLE);
customViewContainer.addView(view);
customViewCallback = callback;
}
#Override
public View getVideoLoadingProgressView() {
if (mVideoProgressView == null) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
mVideoProgressView = inflater.inflate(R.layout.video_progress, null);
}
return mVideoProgressView;
}
#Override
public void onHideCustomView() {
super.onHideCustomView(); //To change body of overridden methods use File | Settings | File Templates.
if (mCustomView == null)
return;
webView.setVisibility(View.VISIBLE);
customViewContainer.setVisibility(View.GONE);
// Hide the custom view.
mCustomView.setVisibility(View.GONE);
// Remove the custom view from its container.
customViewContainer.removeView(mCustomView);
customViewCallback.onCustomViewHidden();
mCustomView = null;
}
}
// WebViewClient Class
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url); //To change body of overridden methods use File | Settings | File Templates.
}
ProgressDialog dialog = ProgressDialog.show(MainActivity.this, "",
"Loading multimedia! Please wait...", true);
#Override
public void onPageFinished(WebView view, String url) {
dialog.dismiss();
}
}
}
web_activity.xml
<!-- View that will be hidden when video goes fullscreen -->
<RelativeLayout
android:id="#+id/nonVideoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.iptvmodified.VideoEnabledWebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="#+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- View that will be shown while the fullscreen video loads (maybe include a spinner and a "Loading..." message) -->
<View
android:id="#+id/videoLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="invisible" />
</RelativeLayout>
`activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
I am searching for a solution for thisand googled this to death with no progress made. Any help would be greatly appreciated.
Normally when the device is rotated your activity gets destroyed and recreated. This is probably causing the WebView to get 'kicked out of' fullscreen playback.
You need to override Activity.onConfigurationChanged and declare you want to handle orientation changes in your manifest. See the docs for details.