how to give access my xamarin.forms webview for use browse file? - xamarin.forms

I use a WebView on my Xamarin app, and I use it without any problem. but I can't use browse file on my phone for select file. I click button but I don't see any action. that is work on my web site, but I can't use it on my phone app.
On my web

You can check this code and use the new Uri[].
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage) return;
Android.Net.Uri result = intent.Data;
mUploadMessage.OnReceiveValue(new Uri[] { result });
mUploadMessage = null;
}
}

Related

Xamarin.Forms MvvM Prism Software and Hardware Back Button

I have problem with implementation Code which resolve problem with confirm software nad hardware button back. I need confirm and save state page field. When confirm is true and save state have no error I want close page and when confirm is false or save state have error I want stop closing page. I use xamarin.forms with mvvm prism.
If you mean want to custom the method of Software and Hardware Back Button of Android device, you could override OnOptionsItemSelected and OnKeyDown method in MainActivity.cs to achieve that.
Software Back Button code in MainActivity.cs:
protected override void OnCreate(Bundle savedInstanceState)
{
...
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
SupportActionBar.SetHomeButtonEnabled(true);
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
if(item.ItemId == Android.Resource.Id.Home)
{
Console.WriteLine("software back button press");
return false;
}
else
{
return base.OnOptionsItemSelected(item);
}
}
Hardware Back Button code in MainActivity.cs:
public override bool OnKeyDown([GeneratedEnum] Keycode keyCode, KeyEvent e)
{
if(e.Action == KeyEventActions.Down && keyCode == Keycode.Back)
{
Console.WriteLine("hardware back button press");
}
return false;
}

How can I go about uploading and receiving a users profile picture?

So far in my social media app, the user's data such as first name, last name, email, gender, and more can be saved in a firebase database and retrieved when needed. As of today, I got a working profile picture when first creating a profile you can tap on the empty profile picture icon and it loads up your gallery replacing it with whatever image the user chooses.
Although this is quite neat I need to be able to upload this image somehow under the Users node in my firebase database. I am quite lost when it comes to converting the bitmap data and after reading through some documentation it still confuses me. Below is my code for using a locally saved photo replacing it as the profile picture to show what I have so far.
#Override
public void onClick(View view)
{
if (view == profilePicture)
{
//Toast.makeText(this, "We made it to the onClick for image!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
Uri targetUri = data.getData();
Bitmap bitmap;
try
{
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
profilePicture.setImageBitmap(bitmap);
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The onClick method runs after the user taps the profile icon. Now I will show you the database I am currently working with, this is the Firebase real-time database, not the Firebase storage. While firebase storage might be more appropriate I can't seem to figure out how to tell whos photo would be who as it does not upload them with a user id associated with them.
Database Picture Here
Instead of uploading a bitMap, a far better solution for a simple problem like yours would be Firebase Storage, similar to the Database but you can upload files such as images with much ease.
Here are the methods I currently use in my app:
private void chooseImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
private void uploadImage() {
if(filePath != null)
{
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
StorageReference ref = storageReference.child("images/"+userID);
ref.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
toastMessage("Uploaded");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
toastMessage("Failed"+e.getMessage());
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
.getTotalByteCount());
progressDialog.setMessage("Uploaded "+(int)progress+"%");
}
});
}
}

Save & Restore Page in Xamarin Forms

I'm looking to save the current navigation stack on the OnSleep Event in my Xamarin Forms page and restore it on the OnResume Event. Is it possible to do this?
Cheers!
I think you should not memorize all navigation stack. Your device decide to kill your app or to restart from the last page you have seen when it comes up from background. I think you can memorize if you are "Logged in" or not: if you are "Logged in" you can restart from the first page "after the login", otherwise start "from the login".
For this case you can take a look to this link and use Properties
public class App : Xamarin.Forms.Application
{
public App ()
{
}
protected override void OnStart()
{
// Handle when your app starts
Debug.WriteLine ("OnStart");
checkLogin();
}
protected override void OnSleep()
{
// Handle when your app sleeps
Debug.WriteLine ("OnSleep");
}
protected override void OnResume()
{
// Handle when your app resumes
Debug.WriteLine ("OnResume");
checkLogin();
}
}
void checkLogin(){
if (Application.Current.Properties.ContainsKey("IsLogged"))
{
var IsLogged = Application.Current.Properties ["IsLogged"] as bool;
// do something with IsLogged
if(IsLogged)
MainPage = new MyFirstPage();
else
MainPage = new MyLoginPage();
}
else
MainPage = new MyLoginPage();
}
then, when you have logged in
Application.Current.Properties ["IsLogged"] = true;

Navigating from Platform Specific (UWP) PageRenderer and back to PCL Page

I have a MainPage in PCL which then navigates to a Platform Specific
Login Page on LoginButton Click Event
The LoginPage is inherited from
platform specific PageRenderer as it needs platform specific
Authentication to Social Providers (Facebook, Google, Twitter,
Microsoft, etc.)
I am using Xamarin.Auth to do the authentication.
Inside the OnElementChanged event of the LoginPage, it instantiates
the OAuth2Authenticator object.
Upon successful instantiation (based
on provider and app details), it needs to call the UI of the specific
provider.
To do that, I call the auth.GetUI where auth is
Xamarin.Auth.OAuth2Authenticator object.
I have two questions:
In UWP, how do I navigate to the provider login UI? More specifically, what is the equivalent in UWP of the following code snippets in iOS and Android? In iOS, the following code is used:
PresentViewController(auth.GetUI(), true, null);
where auth is Xamarin.Auth.OAuth2Authenticator object.
In Android the following is used:
activity.StartActivity(auth.GetUI(activity));
I am looking for the equivalent code in UWP. Please bear in mind that these calls are made from the LoginPage which is derived from Platform specific PageRenderer
How do I navigate back to my MainPage (which is in PCL) upon successful authentication?
The code is based off of a sample from the following source:
http://www.c-sharpcorner.com/article/oauth-login-authenticating-with-identity-provider-in-xamarin-forms/
Here is my code for the LoginPage:
using System;
using Valufy;
using Xamarin.Forms.Platform.UWP;
using System.ComponentModel;
using Valufy.UWP;
using Valufy.AuthConfiguration;
using Xamarin.Forms;
[assembly: ExportRenderer(typeof(ProviderLoginPage), typeof(LoginRenderer))]
namespace Valufy.UWP
{
class LoginRenderer: PageRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.Page> e)
{
base.OnElementChanged(e);
//Get and Assign ProviderName from ProviderLoginPage
ProviderLoginPage loginPage = (ProviderLoginPage)Element;
string providername = loginPage.ProviderName;
//Create OauthProviderSetting class with Oauth Implementation .Refer Step 6
OAuthProviderSetting oauth = new OAuthProviderSetting();
Xamarin.Auth.OAuth2Authenticator auth = oauth.LoginWithProvider(providername);
// After facebook,google and all identity provider login completed
auth.Completed += Auth_Completed;
Type page_type = auth.GetUI();
//////THIS IS WHERE I AM STUCK...HOW DO I GO TO THE PROVIDER AUTH UI ////////////
//this.Frame.Navigate(page_type, auth);
//parentPage.Navigation.PushModalAsync(auth.GetUI());
}
}
private void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
if (e.IsAuthenticated)
{
OAuthConfig.User = new UserDetails();
// Get and Save User Details
OAuthConfig.User.Token = e.Account.Properties["oauth_token"];
OAuthConfig.User.TokenSecret = e.Account.Properties["oauth_token_secret"];
OAuthConfig.User.TwitterId = e.Account.Properties["user_id"];
OAuthConfig.User.ScreenName = e.Account.Properties["screen_name"];
/////NOW, HOW GO I GO BACK TO THE CALLING PAGE IN PCL ///////////////////
}
else
{
// The user cancelled
/////NOW, HOW GO I GO BACK TO THE CALLING PAGE IN PCL ///////////////////
}
}
}
}
Here is the code to navigate to the provider login for UWP:
WindowsPage windowsPage = new WindowsPage();
_frame = windowsPage.Frame;
if (_frame == null)
{
_frame = new Windows.UI.Xaml.Controls.Frame
{
Language = global::Windows.Globalization.ApplicationLanguages.Languages[0]
};
windowsPage.Content = _frame;
SetNativeControl(windowsPage);
}
Type pageType = auth.GetUI();
_frame.Navigate(pageType, auth);
To navigate back to my page upon successful authentication, here is the code:
private async void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
if (e.IsAuthenticated)
{
var request = new OAuth2Request("GET", new Uri("https://login.microsoftonline.com/common/oauth2/V2.0/token?oauth2_access_token=" + e.Account.Properties["access_token"]), null, e.Account);
try
{
string response = await MSGetUserInfo(e.Account);
}
catch (System.OperationCanceledException)
{
}
catch (Exception ex)
{
}
this.Element.Navigation.PushModalAsync(new MainPage());
}
else
{
// The user cancelled
}
}
1- In UWP, how do I navigate to the provider login UI
You need to create a UWP Page object, the same object you are will use to display in the renderer is the one you will use to do the navigation.
Type page_type = auth.GetUI();
page = new MyUWPLoginPage();
page.Frame.Navigate(page_type, auth);
2- How do I navigate back to my MainPage (which is in PCL) upon successful authentication?
There are many ways to do this, the easiest one is creating a public method in your ProviderLoginPage class and from the renderer classes call this method and pass-in the parameters.
public class ProviderLoginPage: ContentPage
{
......
public void AuthenticationCompleted(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
// Do your logic
}
}
In your Renderer using the Element:
private void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
var xamElement = Element as ProviderLogin;
xamElement?.AuthenticationCompleted(sender, e);
}
Move all the logic to the PCL class so you don't have to repeat it on each renderer.
This should help.

if(resultCode==Activity.RESULT_OK) is returning false

I am working on a very basic app which captures a photo using the phone's camera and sets it up on the ImageView. But the code is not entering the if(resultCode==Activity.RESULT_OK) statement. I understood this by using Log inside the if statement. Any idea how I can resolve this? Here is the onActivityResult()
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==Activity.RESULT_OK){
Log.v("cam"," resultCode");
Bundle extras=data.getExtras();
bmp=(Bitmap) extras.getParcelable("data");
iv.setImageBitmap(bmp);
button1.setText("Take Another");
}
}
first of all
Check that u have all the necessary permission in the manifest file for capturing the image and where you're storing that image that folder access.
Check it out for more reference. for reference
Try This ... It works for Me..
if ( resultCode == Activity.RESULT_OK ) {
Uri path = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),path);
imgView.setImageBitmap(bitmap);
imgView.setVisibility(View.VISIBLE);
Name.setVisibility(View.VISIBLE);
} catch (IOException e) {
e.printStackTrace();
}
}

Resources