Utilizando a Câmera – Xamarin.Forms

Olá, neste post irei demonstrar como a sua aplicação Xamarin.Forms pode acessar a câmera do dispositivo para tirar uma foto, fazer um vídeo ou acessar a galeria.

Para este exemplo irei assumir que você acabou de criar uma aplicação Xamarin.Forms, caso possua alguma dúvida sobre isso recomendo ler o post Criando um projeto Xamarin.Forms.

O primeiro passo após a sua aplicação ter sido criada é adicionar o Nuget Package Xam.Plugin.Media.

ADICIONANDO O NUGET PACKAGE

Clique com o botão direito em cima de sua Solution e selecione “Manage NuGet Packages for Solution…”.

nugetp

 

Digite “Xam.Plugin.Media” e selecione o plugin como demonstrado na imagem a seguir.

nuget

 

Selecione todos os projetos e clique no botão “Install”.

nuget

Repita esse procedimento para instalar o plugin: Plugin.Permissions

Android

Para a plataforma Android é necessário realizar a inicialização do plugin no arquivo MainActivity, para isso adicione a seguinte linha de código após o comando base.OnCreate(bundle):

await CrossMedia.Current.Initialize();

Também sobrescreva o método OnRequestPermissionsResult como demonstrado a seguir.


using Plugin.Media;
using Android.App;
using Android.Content.PM;
using Android.OS;
namespace DemoCamera.Droid
{
[Activity(Label = "DemoCamera", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override async void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
await CrossMedia.Current.Initialize();
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}

 

Em seguida, é preciso adicionar a permissão para o seu app acessar a câmera, isso é feito no  arquivo AndroidManifest.xml.

  • Adicione a permissão “android.permission.CAMERA”.
  • Dentro de application, adicione o provider e meta-data como demonstrado a seguir.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android&quot; android:versionCode="1" android:versionName="1.0" package="com.companyname.DemoCamera" android:installLocation="auto">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.CAMERA" />
<application android:label="DemoCamera.Android">
<provider android:name="android.support.v4.content.FileProvider"
android:authorities="com.companyname.DemoCamera.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
</application>
</manifest>

 

 

Dentro da pasta “Resources” crie uma pasta chamada xml e  adicione um arquivo chamado file_paths.xml, como demonstrado a seguir.


<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"&gt;
<external-files-path name="my_images" path="Pictures" />
<external-files-path name="my_movies" path="Movies" />
</paths>

view raw

file_paths.xml

hosted with ❤ by GitHub

iOS

Adicionar permissões para que o seu app acesse a câmera na plataforma iOS é necessário editar o arquivo Info.plist que encontra-se no seu projeto .iOS

info

No arquivo Info.plist iremos adicionar as seguintes chaves:

  • NSCameraUsageDescription
  • NSPhotoLibraryUsageDescription
  • NSMicrophoneUsageDescription
  • NSPhotoLibraryAddUsageDescription


</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>CFBundleName</key>
<string>DemoCamera</string>
<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to take photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs access to microphone.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs access to the photo gallery.</string>
</dict>
</plist>

view raw

Info.plist

hosted with ❤ by GitHub

Portable

O próximo passo é colocar alguns botões para acionar a câmera ou a galeria e um Image para demonstrar a foto tirada.

Xaml


<ContentPage xmlns="http://xamarin.com/schemas/2014/forms&quot;
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml&quot;
xmlns:local="clr-namespace:DemoCamera"
x:Class="DemoCamera.MainPage">
<StackLayout>
<Button Text="Tirar Foto" Clicked="TirarFoto" FontSize="20" />
<Button Text="Escolher Foto" Clicked="EscolherFoto" FontSize="20" />
<Button Text="Gravar Video" Clicked="GravarVideo" FontSize="20" />
<Button Text="Escolher Video" Clicked="EscolherVideo" FontSize="20" />
<Image x:Name="MinhaImagem" />
</StackLayout>
</ContentPage>

O evento click de cada botão ira chamar o seu respectivo método, como demonstrado a seguir.

Tirar Foto

tirarfoto

 

Escolher Foto

escolherfoto

 

Gravar Vídeo

gravarvideo.png

 

Escolher Vídeo

escolhervideo

CODE-BEHIND


using Plugin.Media;
using Plugin.Media.Abstractions;
using System;
using Xamarin.Forms;
namespace DemoCamera
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async void TirarFoto(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsTakePhotoSupported || !CrossMedia.Current.IsCameraAvailable)
{
await DisplayAlert("Ops" , "Nenhuma câmera detectada.", "OK");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(
new StoreCameraMediaOptions
{
SaveToAlbum = true,
Directory = "Demo"
});
if (file == null)
return;
MinhaImagem.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
private async void EscolherFoto(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("Ops", "Galeria de fotos não suportada.", "OK");
return;
}
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
MinhaImagem.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
private async void GravarVideo(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsTakeVideoSupported || !CrossMedia.Current.IsCameraAvailable)
{
await DisplayAlert("Ops", "Nenhuma câmera detectada.", "OK");
return;
}
var file = await CrossMedia.Current.TakeVideoAsync(
new StoreVideoOptions
{
SaveToAlbum = true,
Directory = "Demo",
Quality = VideoQuality.Medium
});
if (file == null)
return;
MinhaImagem.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
private async void EscolherVideo(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsPickVideoSupported)
{
await DisplayAlert("Ops", "Galeria de videos não suportada.", "OK");
return;
}
var file = await CrossMedia.Current.PickVideoAsync();
if (file == null)
return;
MinhaImagem.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
}
}

Resultado

ezgif.com-gif-maker

 

Esse e todos os exemplos deste blog encontram-se disponíveis no GitHub.

icongithub

59 comentários em “Utilizando a Câmera – Xamarin.Forms

  1. sabe me dizer como tirar uma FOTO DO VIDEO ? tipo screenshot, mas com a camera em modo video, ai uma função para ir batendo foto dos frame da camera ?

    Curtir

  2. Juliano, ao usar o evento Tirar Foto , visualizo a foto tirada e ao dar ok o meu aplicativo é jogado para o segundo plano. O que pode ser?

    Curtir

      1. No momento fiz apenas teste no meu celular mesmo. Tanto tirar uma foto nova como escolher na galeria, ao confirmar o APP fecha.

        Curtir

      2. Juliano ainda não tive sucesso. Caso não seja inconveniente segue abaixo o meu OutPut
        04-01 23:52:46.491 D/SecWifiDisplayUtil( 2994): Metadata value : SecSettings2
        04-01 23:52:46.491 D/ViewRootImpl( 2994): #1 mView = com.android.internal.policy.PhoneWindow$DecorView{c3923e2 I.E…… R…..ID 0,0-0,0}
        04-01 23:52:46.811 D/mali_winsys( 2994): new_window_surface returns 0x3000, [720×1280]-format:1
        04-01 23:52:46.831 D/ViewRootImpl( 2994): MSG_RESIZED_REPORT: ci=Rect(0, 48 – 0, 0) vi=Rect(0, 48 – 0, 0) or=1
        04-01 23:52:47.051 D/ViewRootImpl( 2994): #3 mView = null
        04-01 23:52:47.721 I/art ( 2994): Starting a blocking GC Explicit
        04-01 23:52:47.761 I/art ( 2994): Explicit concurrent mark sweep GC freed 1273(58KB) AllocSpace objects, 0(0B) LOS objects, 16% free, 41MB/49MB, paused 608us total 35.386ms
        04-01 23:52:47.761 D/Mono ( 2994): GC_TAR_BRIDGE bridges 299 objects 8103 colors 299 ignored 3478 sccs 299 xref 0 cache 0/0 setup 0.09ms tarjan 6.18ms scc-setup 0.13ms gather-xref 0.01ms xref-setup 0.00ms cleanup 0.66ms
        04-01 23:52:47.761 D/Mono ( 2994): GC_BRIDGE: Complete, was running for 39.49ms
        04-01 23:52:47.761 D/Mono ( 2994): GC_MINOR: (Nursery full) time 16.99ms, stw 17.39ms promoted 190K major size: 3728K in use: 2664K los size: 1024K in use: 788K

        Curtir

  3. Olá Juliano, fiz os mesmo passo em uma app net standard, mas esta dando erro “Java.Lang.RuntimeException: Unable to start activity ComponentInfo{com.companyname.App2/md5e528b4472ea765fab6a0696a5fd66c3a.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.support.v7.widget.ContentFrameLayout.setAttachListener(android.support.v7.widget.ContentFrameLayout$OnAttachListener)’ on a null object reference” e para o app.
    A câmera funciona somente se altera a herança do MainActivity para Xamarin.Forms.Platform.Android.FormsApplicationActivity, mas com essa alteração não consigo usar uma MasterPage.
    O pode ser?

    Curtido por 1 pessoa

  4. na hora de abrir a câmera travou na seguinte linha
    var file = await CrossMedia.Current.TakePhotoAsync(
    new StoreCameraMediaOptions
    {
    SaveToAlbum = true,
    Directory = “Demo”
    });
    agradeço ajuda desde já

    Curtir

      1. e o melhor é, quando é pra pegar da galeria funciona! de cabelo em pé aqui já pois preciso disso pro trabalho

        Curtir

  5. Juliano, boa tarde!

    No projeto para iOS, nao consegui localizar no arquivo Info.plist onde eu coloco as chaves

    NSCameraUsageDescription
    NSPhotoLibraryUsageDescription
    NSMicrophoneUsageDescription
    NSPhotoLibraryAddUsageDescription

    Poderia me ajudar?

    Curtir

    1. Olá Vilmar,

      Botão direito no Arquivo Info.plist, abrir com, XML Text Editor.
      Em seguida coloque dentro de “dict” depois do nome do seu app.

      Espero ter ajudado. 🙂

      Curtir

  6. Juliano, boa noite! To com o seguinte erro:

    Unhandled Exception:

    Java.Lang.RuntimeException: Unable to start activity ComponentInfo{Procon_Sorocaba.Procon_Sorocaba/md53d87c17fb05de643ade6b138d9319cf2.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.support.v7.widget.ContentFrameLayout.setAttachListener(android.support.v7.widget.ContentFrameLayout$OnAttachListener)’ on a null object reference

    Consegue me ajudar? Falta so isso pra terminar o projeto …

    Curtir

    1. Desconsidera, deu certo aqui. Peguei o problema de cima que tava ai e era exatamente o mesmo. Unico problema que ele nao ta pegando a permissão automática pra acessar camera e galeria. Tem algum jeito?

      Curtir

      1. Olá Vilmar,

        isso está acontecendo no iOS ?
        Você está rodando em debug ?
        Lembre-se que cada vez que você executa o projeto pelo VS ele desinstala o app e instala novamente, então será pedido a permissão novamente.
        Experimente fechar o app e abrir novamente sem rodar pelo VS, acredito que ele não irá pedir mais a permissão a partir do segundo acesso.

        Espero ter ajudado.

        Curtir

      2. Consegui finalmente instalar, mas assim que termino a instalção o método
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
        global::Xamarin.Forms.Forms.Init();
        LoadApplication(new App());

        return base.FinishedLaunching(app, options);
        }
        para de funcionar 😦
        a linha LoadApplication(new App()); no App() fica vermelho sem achar o namespace e não consegui resolver

        Curtir

  7. Boa dia Juliana, estou tendo um erro ao inicializar o plugin, Erro(System.NotImplementedException: This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.).
    Não posso utilizar esse plugin no projeto UWP ?

    Curtir

    1. Olá Amanda,

      De acordo com a Documentação desse plugin, ele suporta UWP sim.

      Verifique se o plugin está instalado em todos os projetos da sua Solution.

      Espero ter ajudado 🙂

      Curtir

  8. Boa tarde, consegui fazer funcionar tudo certinho. Gostaria de saber se eu consigo tirar fotos automaticamente por esse plugin, como se o botão do MAIN já batesse a foto após chamar a câmera.

    Curtir

    1. Boa tarde,

      Acredito que não seja possível utilizando esse plugin. Já que a ideia do Media.Plugin é ativar a câmera e depois pegar a foto tirada pelo usuário.

      Curtir

      1. Olá Alberto,

        Na própria postagem, verifique os passos destinados a cada plataforma. 🙂

        Curtir

      2. Estou com o mesmo erro e não consegui resolver. Já olhei o código várias vezes, nenhuma diferença, limpei a solução, compilei novamente e nada. Consegue me ajudar?

        Curtir

      3. Olá Otávio,

        Você alterou o arquivo do AndroidManifest ? Verifique se trocou o nome do pacote corretamente caso tenha copiado o código do post.

        Curtir

      4. Até refiz o projeto, depois de tudo verificado deu certo. Provavelmente tenha tido algum problema no AndroidManifest mesmo, mas o que fez meu app funcionar mesmo depois de tudo conferido foi dar um clean e um build novamente.

        Curtir

  9. Juliano, boa noite,
    Estou usando o Visual Studio Community 2017; instalei o Nuget Xam.Plugin.Midea e quando faço a compilação aparece a mensagem de Erro: “Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly ‘Plugin.Permissions.Abstractions, Version=2.2.1.0, Culture=neutral, PublicKeyToken=’. Perhaps it doesn’t exist in the Mono for Android profile?
    Nome do arquivo: ‘Plugin.Permissions.Abstractions.dll’
    em Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters)
    em Xamarin.Android.Tasks.ResolveAssemblies.AddAssemblyReferences(DirectoryAssemblyResolver resolver, ICollection`1 assemblies, AssemblyDefinition assembly, Boolean topLevel)
    em Xamarin.Android.Tasks.ResolveAssemblies.Execute(DirectoryAssemblyResolver resolver) Moshi.Android
    Você pode me ajudar?

    Curtir

    1. Olá Edgar,

      Você alterou o arquivo do AndroidManifest ? Verifique se trocou o nome do pacote corretamente caso tenha copiado o código do post.

      Curtir

  10. Estava dando erro ao clicar em “TIRAR FOTO”

    System.ArgumentException: Unable to get file location. This most likely means that the file provider information is not set in your Android Manifest file. Please check documentation on how to set this up in your project.

    Funcionou somente depois que eu modifiquei

    De: android:authorities=”com.companyname.DemoCamera.fileprovider”

    Para: android:authorities=”com.companyname.Camera1.fileprovider”

    Como sou novato, copiei o trecho do seu código. Depois de alguma procura fiz a alteração do valor da atributo e rolou.

    Curtir

  11. Oi Juliano,
    Parabéns pelo seu trabalho. Funcionou perfeitamente aqui pra mim.

    Surgiu a seguinte situação, eu gostaria de utilizar um controle de câmera similar ao do Instagram. Utilizando um layout com botões personalizados. Como se eu pudesse incluir a câmera como um controle ou visualizar a imagem dentro de um grid. Pesquisei muito na Internet e não consegui encontrar ainda.

    Você já se deparou com essa situação? Sabe como implementar ou tem algum tutorial semelhante a este?

    Obrigado.
    Att,
    Arthur

    Curtir

    1. Olá Arthur,

      Obrigado, que bom que funcionou.

      Então esse plugin não disponibiliza esses tipos de customizações.
      Até o momento não precisei fazer algo desse tipo, mas acredito que você teria que realizar essas customizações de acordo com cada plataforma.

      Espero ter ajudado. Abraço

      Curtir

  12. Bom dia, estou tendo problema para salvar video no álbum, ele abre a câmera, grava o video, porem quando vou no album o mesmo não esta lá, funciona perfeitamente para fotos.

    Consegue me auxiliar? já estou um tempinho nesse problema.

    Obrigado.

    Curtir

    1. Olá Everton,

      Você está utilizando “SaveToAlbum = true” ?
      Verifique também o nome do diretório que está salvando.

      Espero ter ajudado.

      Curtir

  13. Olá como vai?
    Estou tentando fazer tudo somente no Android, sou seja, sem usar o forms, mas quando chego no ImageSource.FromStream para pegar a foto o visual studio não sabe de onde vem esse objeto. Poderia me ajudar? Muito obrigado.

    Curtir

    1. Olá Adriano, vou bem e voce ?

      O problema em questão, acredito ser porque o ImageSource.FromStream pertence ao Xamarin.Forms.

      Curtir

  14. Olá Juliano, em primeiro lugar queria agradecer pelo tempo e trabalho dedicado para nos ajudar, consegui implementar estas funcionalidades com successo na minha app. Entretanto surgiu aqui uma dúvida: eu saquei uma imagem da web e guardei no android (emulado), mas na hora de escolher a imagem nao me aparece no ecrã, qual é a diretoria que as imagens têm de estar para aparecerem no ecra de ‘Selecionar Imagem’? Obrigado desde já e uma ótima continuação 🙂

    Curtir

    1. Olá.. Fico feliz em saber que o post te ajudou.
      Se você baixou a imagem da web, provavelmente ela está na pasta Downloads.
      Espero ter ajudado.

      Curtir

  15. Olá Juliano, parabéns pelo trabalho.
    No meu caso, as fotos estão sendo salvas na galeria do android mesmo com a opção SaveToAlbum = false. Existe alguma outra forma das fotos não serem salvas na galeria? Pode me ajudar?

    Curtir

    1. Olá Felipe, obrigado !!
      A opção SaveToAlbum é para caso você queira salvar a foto em um diretório específico, como no exemplo eu salvei na pasta “Demo”. É padrão do android salvar na galeria.

      Curtir

  16. Eu estava com o seguinte erro:

    System.ArgumentException: Unable to get file location. This most likely means that the file provider information is not set in your Android Manifest file. Please check documentation on how to set this up in your project.

    Após algumas pesquisas encontrei que meu PACKAGENAME estava errado, para consultar como era o nome correto, fui nas opções do ANDROID MANIFEST e consultei a forma correta do PACKAGENAME

    LINK de onde eu encontrei a solução, caso mais pessoas tenham a mesma duvida https://stackoverflow.com/questions/48415727/xamarin-forms-file-provider-not-set

    Curtir

  17. Olá Juliano, estou tentando implementar essa rotina em um projeto aqui da empresa. Eu precisaria apenas ter a função de tirar uma foto e salvar ela no banco de dados, porém me deparei com um erro e até então não consegui uma solução. Agradeço se puder me auxiliar. Quando clico no botão “Tirar Foto” o visual studio me traz o erro: “System.ArgumentException: Unable to get file location. This most likely means that the file provider information is not set in your Android Manifest file. Please check documentation on how to set this up in your project.”.
    Na depuração, o erro ocorre quando é preenchida a variavel “file”, e nesta mesma rotina, se eu parar o mouse sobre o “await CrossMedia” ele aparece ao lado assim: “Expression not supported.”.
    Tenha um bom dia!

    Curtir

  18. Fiz através de um modelo criado para xamarin do vs. Estava com uma dificuldade na autorização para tirar foto e gravar vídeo dentro do arquivo AndroidManifest.xml, devido ao erro o aplicativo somente buscava as fotos e vídeos da galeria e travava ao clicar em tirar foto e gravar vídeo.

    Resolvi substituindo a seguinte linha de código dentro do arquivo AndroidManifest.xml:

    DE:

    PARA:

    Muito obrigado, Juliano Custódio!!

    Curtir

  19. Fiz através de um modelo criado para xamarin do vs. Estava com uma dificuldade na autorização para tirar foto e gravar vídeo dentro do arquivo AndroidManifest.xml, devido ao erro o aplicativo somente buscava as fotos e vídeos da galeria e travava ao clicar em tirar foto e gravar vídeo.

    Resolvi substituindo a seguinte linha de código dentro do arquivo AndroidManifest.xml:

    DE:

    //

    //
    //

    PARA:

    //

    //
    //

    Muito obrigado, Juliano Custódio!!

    Resolvi substituindo a seguinte linha de código dentro do arquivo AndroidManifest.xml:

    DE:

    PARA:

    Muito obrigado, Juliano Custódio!!

    Curtir

Deixar mensagem para caique Cancelar resposta