Как я могу отобразить изображение, хранящееся на мобильном устройстве, в моей заявке? - PullRequest
0 голосов
/ 22 марта 2019

У меня есть приложение, где в какой-то момент мне нужно зайти в список контактов пользователя и получить оттуда данные. Для этого я использовал Xamarin.Forms.Contacts(1.0.5) плагинов, и он работал хорошо. Я смог получить Name Number Email PhotoUri PhotoUriThumbnail от каждого контакта. А потом я показываю некоторые сведения о моем приложении. Однако я не могу отобразить изображение из каталога PhotoUri. PhotoUri - строка с этим форматом: content://android/.... Я попытался преобразовать PhotoUri в ImageSource, а затем использовать его в файле xaml, но ничего не получалось ... Кто-нибудь может помочь?

1 Ответ

1 голос
/ 22 марта 2019

Для получения данных из content:// URI вы можете использовать ContentResolver. В частности, вы можете загрузить содержимое из файла с помощью ContentResolver.OpenInputStream ( см. Здесь ). Для отображения изображения вы можете использовать StreamImageSource ( см. Здесь ). Если у вас уже есть Uri, вы можете создать экземпляр StreamImageSource, как показано в следующем фрагменте

var contentResolver = Application.ApplicationContext.ContentResolver;
var streamImageSource = new StreamImageSource() 
{
    Stream = (cancellationToken) => Task.FromResult(contentResolver.OpenInputStream(uri));
}

Обратите внимание : если PhotoUri - это примечание, полученное из Android.Net.Uri, вам придется преобразовать его в последнее.

Редактировать

Представленный код работает только с MainActivity. В качестве обходного пути я добавил статическое свойство Instance к MainActivity, назначенное в OnCreate

public static MainActivity Instance { get; private set; }

protected override void OnCreate(Bundle savedInstanceState)
{
    this.Window.RequestFeature(WindowFeatures.ActionBar);
    this.SetTheme(Resource.Style.MainTheme);

    base.OnCreate(savedInstanceState);

    MainActivity.Instance = this;

    // whatever
}

затем вы можете использовать

var contentResolver = MainActivity.Instance.Application.ApplicationContext.ContentResolver;

, который не может быть оптимальным, но работает. В качестве альтернативы (что я бы предпочел), вы можете добавить MainActivity в ваши экземпляры.

Редактировать 2

Поскольку возник вопрос, как использовать этот код из Xamarin.Forms, я дам краткое описание. Если вы не используете внедрение зависимостей, самый простой способ будет использовать DependencyService (см. здесь ). Создайте интерфейс в вашем общем коде

public interface IContentLoader
{
    ImageSource LoadFromContentUri(Uri uri);
}

Реализация этого интерфейса должна быть добавлена ​​к проекту платформы

[assembly: Dependency (typeof (Droid.ContentLoader))]

namespace Droid
{
    public class ContentLoader : IContentLoader
    {
        public ImageSource LoadFromContentUri(Uri uri)
        {
            var contentResolver = MainActivity.Instance.Application.ApplicationContext.ContentResolver;
            var streamImageSource = new StreamImageSource() 
            {
                Stream = (cancellationToken) => Task.FromResult(contentResolver.OpenInputStream(Android.Net.Uri.Parse(uri.ToString())));
            }
            return streamImageSource;
        }
    }
}

Теперь IContentLoader можно использовать из вашего проекта Xamarin.Forms, используя DependencyService:

var contentLoader = DependencyService.Get<IContentLoader>();
// ...
var imageSource = contentLoader.LoadFromContentUri(uri);

Обратите внимание : если вы программируете для iOS и Android, вам нужно позаботиться о том, чтобы вы могли загружать изображения с обеих платформ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...