Bir bulut medya sağlayıcısı, Android uygulamasına ek bulut medya içeriği sağlar.
Fotoğraf seçiciyi kullanın. Kullanıcılar, kendileri tarafından sağlanan fotoğrafları veya videoları
bir uygulama ACTION_PICK_IMAGES
veya kullandığında bulut medya sağlayıcısı
Kullanıcıdan medya dosyaları istemek için ACTION_GET_CONTENT
. Bir bulut medyası
sağlayıcı, şurada göz atılabilen albümler hakkında da bilgi verebilir:
Android fotoğraf seçici.
Başlamadan önce
Bulutunuzu derlemeye başlamadan önce aşağıdaki unsurları göz önünde bulundurun medya sağlayıcıdır.
Uygunluk
Android, OEM tarafından aday gösterilen uygulamaların bulut haline getirilmesini sağlamak için bir pilot program yürütüyor izin verir. Yalnızca OEM'ler tarafından aday gösterilen uygulamalar programa katılabilir. şu anda Android için bulut medya sağlayıcısı olmak üzere bu programa katılmayı tercih edebilirsiniz. Her biri OEM en fazla 3 uygulamayı aday gösterebilir. Bu uygulamalar onaylandıktan sonra kullandıkları GMS Android destekli cihazlardaki bulut medya sağlayıcıları yüklendi.
Android, tüm uygun bulut sağlayıcılarının sunucu tarafı listesini tutar. Her bir OEM yapılandırılabilir bir yer paylaşımı kullanarak varsayılan bir bulut sağlayıcı seçebilir. Aday gösterildi Uygulamalar tüm teknik şartları karşılamalı ve tüm kalite testlerini geçmelidir. Öğrenmek için OEM bulut medya sağlayıcısı pilot programının süreci ve soru formunu doldurun.
Bulut medya sağlayıcısı oluşturmanız gerekip gerekmediğine karar verin
Bulut medya sağlayıcıları, kullanıcıların temel işlevi gören uygulama veya hizmetler olarak tasarlanmıştır: fotoğraf ve videoları bulutta yedekleyip almak için birincil kaynak. Uygulamanızın yararlı içeriklerden oluşan bir kitaplığı varsa, ancak bu kitaplık genellikle bir içerik kitaplığı olarak kullanılmıyorsa fotoğraf depolama çözümü olarak bir doküman sağlayıcı oluşturmayı düşünmelisiniz. .
Profil başına bir etkin bulut sağlayıcı
Her Android için aynı anda en fazla bir etkin bulut medya sağlayıcısı olabilir profil. Kullanıcılar, seçtikleri bulut medya sağlayıcıyı kaldırabilir veya değiştirebilir istediğiniz zaman fotoğraf seçici ayarlarından yapabilirsiniz.
Android fotoğraf seçici varsayılan olarak bir bulut sağlayıcı seçmeyi dener otomatik olarak oluşturur.
- Cihazda yalnızca bir uygun bulut sağlayıcı varsa bu uygulama otomatik olarak geçerli sağlayıcı seçilir.
Cihazda birden fazla uygun bulut sağlayıcı varsa ve öğelerin OEM tarafından seçilen varsayılan uygulama ile eşleştiğinden OEM tarafından seçilen uygulama seçilir.
Cihazda birden fazla uygun bulut sağlayıcı varsa ve bunların hiçbiri uygulama OEM tarafından seçilen varsayılan değerle eşleştiğinden hiçbir uygulama seçilmez.
Bulut medya sağlayıcınızı oluşturma
Aşağıdaki şemada, olaydan önceki ve sonraki olayların sırası gösterilmektedir
Android uygulaması, Android fotoğraf seçici,
yerel cihazın MediaProvider
ve CloudMediaProvider
.
- Sistem, kullanıcının tercih ettiği bulut sağlayıcıyı ilk kullanıma hazırlar ve düzenli aralıklarla medya meta verilerini Android fotoğraf seçici arka ucuyla senkronize eder.
- Bir Android uygulaması, fotoğraf seçiciyi başlattığında, birleştirilmiş bir yerel dosyayı göstermeden önce kullanıcı için bulut öğesi ızgarasında, fotoğraf seçici gecikmeye duyarlı bir Sonuçların olabildiğince güncel olmasını sağlamak için bulut sağlayıcı ile artımlı senkronizasyon yardımcı olabilirsiniz. Yanıt aldıktan sonra veya teslim tarihine ulaşıldığında fotoğraf seçici ızgarasında artık erişilebilir tüm fotoğraflar görüntülenerek depolananlar yerel olarak cihazınızda yerel olarak paylaşabilirsiniz.
- Kullanıcı sayfayı kaydırırken fotoğraf seçici, sayfanın üst kısmından medya küçük resimlerini kullanıcı arayüzünde görüntülenecek bir bulut medya sağlayıcı
- Kullanıcı oturumu tamamladığında ve sonuçlar bir bulut medyası içerdiğinde öğesini seçerseniz fotoğraf seçici içerik için dosya tanımlayıcıları ister, URI'dır ve çağıran uygulamaya dosyaya erişim izni verir.
- Uygulama artık URI'yı açabiliyor ve medyaya salt okuma erişimine sahip. içerik. Hassas meta veriler varsayılan olarak çıkartılır. Fotoğraf seçici iki platform arasındaki veri alışverişini koordine etmek için FUSE dosya sisteminden Android uygulaması ve bulut medya sağlayıcı.
Sık Karşılaşılan Sorunlar
Müşteri yolculuğunuza karar verirken aklınızda bulundurmanız gereken uygulama:
Yinelenen dosyalardan kaçının
Android fotoğraf seçicinin bulut medya durumunu denetlemesi mümkün olmadığından
CloudMediaProvider
değerinin imleçteki MEDIA_STORE_URI
değerini sağlaması gerekir
hem bulutta hem de yerel cihazda bulunan herhangi bir dosyanın satırı veya
kullanıcı fotoğraf seçicide yinelenen dosyalar görecektir.
Resim boyutlarını önizleme ekranı için optimize edin
onOpenPreview
alanından döndürülen dosyanın,
ve istenen Size
şartlarına uymalıdır. Resim çok büyük
Kullanıcı arayüzünde yükleme süreleri oluşur ve çok küçük bir resim pikselleştirilebilir veya
cihazın ekran boyutuna göre bulanık.
Doğru yönü tutma
onOpenPreview
içinde döndürülen küçük resimler EXIF verilerini içermiyorsa
Küçük resimlerin döndürülmesini önlemek için doğru yönde döndürülmelidir.
yanlış şekilde etiketleyebilirsiniz.
Yetkisiz erişimi engelleyin
Verileri şuraya geri döndürmeden önce MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION
olup olmadığını kontrol edin:
ContentProvider'dan arayana. Bu şekilde yetkisiz uygulamaların
.
CloudMediaProvider sınıfı
android.content.ContentProvider
türünden türetilen, CloudMediaProvider
sınıfı, aşağıdaki örnekte gösterilenlere benzer yöntemler içerir:
Kotlin
abstract class CloudMediaProvider : ContentProvider() {
@NonNull
abstract override fun onGetMediaCollectionInfo(@NonNull bundle: Bundle): Bundle
@NonNull
override fun onQueryAlbums(@NonNull bundle: Bundle): Cursor = TODO("Implement onQueryAlbums")
@NonNull
abstract override fun onQueryDeletedMedia(@NonNull bundle: Bundle): Cursor
@NonNull
abstract override fun onQueryMedia(@NonNull bundle: Bundle): Cursor
@NonNull
abstract override fun onOpenMedia(
@NonNull string: String,
@Nullable bundle: Bundle?,
@Nullable cancellationSignal: CancellationSignal?
): ParcelFileDescriptor
@NonNull
abstract override fun onOpenPreview(
@NonNull string: String,
@NonNull point: Point,
@Nullable bundle: Bundle?,
@Nullable cancellationSignal: CancellationSignal?
): AssetFileDescriptor
@Nullable
override fun onCreateCloudMediaSurfaceController(
@NonNull bundle: Bundle,
@NonNull callback: CloudMediaSurfaceStateChangedCallback
): CloudMediaSurfaceController? = null
}
Java
public abstract class CloudMediaProvider extends android.content.ContentProvider {
@NonNull
public abstract android.os.Bundle onGetMediaCollectionInfo(@NonNull android.os.Bundle);
@NonNull
public android.database.Cursor onQueryAlbums(@NonNull android.os.Bundle);
@NonNull
public abstract android.database.Cursor onQueryDeletedMedia(@NonNull android.os.Bundle);
@NonNull
public abstract android.database.Cursor onQueryMedia(@NonNull android.os.Bundle);
@NonNull
public abstract android.os.ParcelFileDescriptor onOpenMedia(@NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;
@NonNull
public abstract android.content.res.AssetFileDescriptor onOpenPreview(@NonNull String, @NonNull android.graphics.Point, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;
@Nullable
public android.provider.CloudMediaProvider.CloudMediaSurfaceController onCreateCloudMediaSurfaceController(@NonNull android.os.Bundle, @NonNull android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback);
}
CloudMediaProviderContract sınıfı
Birincil CloudMediaProvider
uygulama sınıfına ek olarak,
Android fotoğraf seçicide bir CloudMediaProviderContract
sınıfı bulunur.
Bu sınıfta, fotoğraf seçici ile bulut arasındaki birlikte çalışabilirlik açıklanmaktadır.
dahil olmak üzere, bir medya sağlayıcısı için MediaCollectionInfo
gibi özellikleri
senkronizasyon işlemleri, beklenen Cursor
sütun ve Bundle
ekstra özelliği.
Kotlin
object CloudMediaProviderContract {
const val EXTRA_ALBUM_ID = "android.provider.extra.ALBUM_ID"
const val EXTRA_LOOPING_PLAYBACK_ENABLED = "android.provider.extra.LOOPING_PLAYBACK_ENABLED"
const val EXTRA_MEDIA_COLLECTION_ID = "android.provider.extra.MEDIA_COLLECTION_ID"
const val EXTRA_PAGE_SIZE = "android.provider.extra.PAGE_SIZE"
const val EXTRA_PAGE_TOKEN = "android.provider.extra.PAGE_TOKEN"
const val EXTRA_PREVIEW_THUMBNAIL = "android.provider.extra.PREVIEW_THUMBNAIL"
const val EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED = "android.provider.extra.SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED"
const val EXTRA_SYNC_GENERATION = "android.provider.extra.SYNC_GENERATION"
const val MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION = "com.android.providers.media.permission.MANAGE_CLOUD_MEDIA_PROVIDERS"
const val PROVIDER_INTERFACE = "android.content.action.CLOUD_MEDIA_PROVIDER"
object MediaColumns {
const val DATE_TAKEN_MILLIS = "date_taken_millis"
const val DURATION_MILLIS = "duration_millis"
const val HEIGHT = "height"
const val ID = "id"
const val IS_FAVORITE = "is_favorite"
const val MEDIA_STORE_URI = "media_store_uri"
const val MIME_TYPE = "mime_type"
const val ORIENTATION = "orientation"
const val SIZE_BYTES = "size_bytes"
const val STANDARD_MIME_TYPE_EXTENSION = "standard_mime_type_extension"
const val STANDARD_MIME_TYPE_EXTENSION_ANIMATED_WEBP = 3 // 0x3
const val STANDARD_MIME_TYPE_EXTENSION_GIF = 1 // 0x1
const val STANDARD_MIME_TYPE_EXTENSION_MOTION_PHOTO = 2 // 0x2
const val STANDARD_MIME_TYPE_EXTENSION_NONE = 0 // 0x0
const val SYNC_GENERATION = "sync_generation"
const val WIDTH = "width"
}
object AlbumColumns {
const val DATE_TAKEN_MILLIS = "date_taken_millis"
const val DISPLAY_NAME = "display_name"
const val ID = "id"
const val MEDIA_COUNT = "album_media_count"
const val MEDIA_COVER_ID = "album_media_cover_id"
}
object MediaCollectionInfo {
const val ACCOUNT_CONFIGURATION_INTENT = "account_configuration_intent"
const val ACCOUNT_NAME = "account_name"
const val LAST_MEDIA_SYNC_GENERATION = "last_media_sync_generation"
const val MEDIA_COLLECTION_ID = "media_collection_id"
}
}
Java
public final class CloudMediaProviderContract {
public static final String EXTRA_ALBUM_ID = "android.provider.extra.ALBUM_ID";
public static final String EXTRA_LOOPING_PLAYBACK_ENABLED = "android.provider.extra.LOOPING_PLAYBACK_ENABLED";
public static final String EXTRA_MEDIA_COLLECTION_ID = "android.provider.extra.MEDIA_COLLECTION_ID";
public static final String EXTRA_PAGE_SIZE = "android.provider.extra.PAGE_SIZE";
public static final String EXTRA_PAGE_TOKEN = "android.provider.extra.PAGE_TOKEN";
public static final String EXTRA_PREVIEW_THUMBNAIL = "android.provider.extra.PREVIEW_THUMBNAIL";
public static final String EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED = "android.provider.extra.SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED";
public static final String EXTRA_SYNC_GENERATION = "android.provider.extra.SYNC_GENERATION";
public static final String MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION = "com.android.providers.media.permission.MANAGE_CLOUD_MEDIA_PROVIDERS";
public static final String PROVIDER_INTERFACE = "android.content.action.CLOUD_MEDIA_PROVIDER";
}
// Columns available for every media item
public static final class CloudMediaProviderContract.MediaColumns {
public static final String DATE_TAKEN_MILLIS = "date_taken_millis";
public static final String DURATION_MILLIS = "duration_millis";
public static final String HEIGHT = "height";
public static final String ID = "id";
public static final String IS_FAVORITE = "is_favorite";
public static final String MEDIA_STORE_URI = "media_store_uri";
public static final String MIME_TYPE = "mime_type";
public static final String ORIENTATION = "orientation";
public static final String SIZE_BYTES = "size_bytes";
public static final String STANDARD_MIME_TYPE_EXTENSION = "standard_mime_type_extension";
public static final int STANDARD_MIME_TYPE_EXTENSION_ANIMATED_WEBP = 3; // 0x3
public static final int STANDARD_MIME_TYPE_EXTENSION_GIF = 1; // 0x1
public static final int STANDARD_MIME_TYPE_EXTENSION_MOTION_PHOTO = 2; // 0x2
public static final int STANDARD_MIME_TYPE_EXTENSION_NONE = 0; // 0x0
public static final String SYNC_GENERATION = "sync_generation";
public static final String WIDTH = "width";
}
// Columns available for every album item
public static final class CloudMediaProviderContract.AlbumColumns {
public static final String DATE_TAKEN_MILLIS = "date_taken_millis";
public static final String DISPLAY_NAME = "display_name";
public static final String ID = "id";
public static final String MEDIA_COUNT = "album_media_count";
public static final String MEDIA_COVER_ID = "album_media_cover_id";
}
// Media Collection metadata that is cached by the OS to compare sync states.
public static final class CloudMediaProviderContract.MediaCollectionInfo {
public static final String ACCOUNT_CONFIGURATION_INTENT = "account_configuration_intent";
public static final String ACCOUNT_NAME = "account_name";
public static final String LAST_MEDIA_SYNC_GENERATION = "last_media_sync_generation";
public static final String MEDIA_COLLECTION_ID = "media_collection_id";
}
onGetMediaCollectionInfo
onGetMediaCollectionInfo()
yöntemi, işletim sistemi tarafından şu işlemler için kullanılır:
Önbelleğe alınan bulut medya öğelerinin geçerliliğini değerlendirebilir ve
senkronize etmek için kullanılabilir. Sık sık projeden çıkma riski
tarafından yapılan çağrı sayısı (onGetMediaCollectionInfo()
) dikkate alınır
Performans açısından kritik; uzun süreli işlemler
veya yan görevlerden kaçınmak
olumsuz yönde etkileyebilecek riskleri ele alacağız. İşletim sistemi,
bu yöntemin önceki yanıtları ve bunları sonraki yanıtlarla karşılaştırır
uygun eyleme karar vermek için kullanır.
Kotlin
abstract fun onGetMediaCollectionInfo(extras: Bundle): Bundle
Java
@NonNull
public abstract Bundle onGetMediaCollectionInfo(@NonNull Bundle extras);
Döndürülen MediaCollectionInfo
paketi aşağıdaki sabit değerleri içerir:
onQueryMedia
onQueryMedia()
yöntemi, tablodaki ana fotoğraf tablosunu doldurmak için
çeşitli görünümlerde fotoğraf seçiciyi kullanabilirsiniz. Bu aramalar gecikmeye duyarlı olabilir ve
arka planda proaktif senkronizasyonun parçası olarak veya fotoğraf seçici sırasında çağrılabilir
tam veya artımlı senkronizasyon durumunun gerekli olduğu oturumlar. Fotoğraf seçici
kullanıcı arayüzü, sonuçların görüntülenmesi için süresiz olarak bir yanıt beklemez ve
bu istekler, kullanıcı arayüzü amaçlarıyla zaman aşımına uğrayabilir. Döndürülen imleç
fotoğraf seçicinin veritabanına işlenmeye devam eder
anlamına gelir.
Bu yöntem, medyadaki tüm medya öğelerini temsil eden bir Cursor
döndürür
isteğe bağlı olarak sağlanan ekstralar tarafından filtrelenen ve tersine sıralanan koleksiyon
MediaColumns#DATE_TAKEN_MILLIS
kronolojik sırası (en son öğeler
) gerekir.
Döndürülen CloudMediaProviderContract
paketi şunları içerir:
sabit değerler:
EXTRA_ALBUM_ID
EXTRA_LOOPING_PLAYBACK_ENABLED
EXTRA_MEDIA_COLLECTION_ID
EXTRA_PAGE_SIZE
EXTRA_PAGE_TOKEN
EXTRA_PREVIEW_THUMBNAIL
EXTRA_SURFACE_CONTROLLER_AUDIO_MUTE_ENABLED
EXTRA_SYNC_GENERATION
MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION
PROVIDER_INTERFACE
Bulut medya sağlayıcısı,
Döndürülenler arasında CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID
Bundle
. Bu ayar yapılmaması bir hatadır ve döndürülen Cursor
değerini geçersiz kılar. Eğer
sağlanan fazladan öğelerdeki filtreleri işleme koyduğunda,
ContentResolver#EXTRA_HONORED_ARGS
öğesinin bir parçası olarak
Cursor#setExtras
.
onSorguSilinmişMedya
onQueryDeletedMedia()
yöntemi,
Cloud hesaplarının fotoğraf seçici kullanıcı arayüzünden doğru şekilde kaldırılması. Kaynak:
bu çağrılar aşağıdaki öğelerin bir parçası olarak başlatılabilir:
- Arka planda proaktif senkronizasyon
- Fotoğraf seçici oturumları (tam veya artımlı senkronizasyon durumu gerekli olduğunda)
Fotoğraf seçicinin kullanıcı arayüzünde duyarlı bir kullanıcı deneyimine öncelik verilir
yanıt almak için sürekli beklemez. Etkileşimin sorunsuz olması için
zaman aşımları meydana gelebilir. Döndürülen Cursor
öğeleri işlenmeye devam eder
fotoğraf seçicinin veritabanına ekleyebilmenizi sağlar.
Bu yöntemCursor
Mevcut sağlayıcı sürümünde döndürüldüğü şekliyle medya koleksiyonunun tamamı
onGetMediaCollectionInfo()
. Bu öğeler isteğe bağlı olarak ekstralar ile filtrelenebilir.
Bulut medya sağlayıcısı,
Döndürülenler arasında CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID
Cursor#setExtras
Ayarlanmazsa bu bir hatadır ve Cursor
politikasını geçersiz kılar. Eğer
sağlayıcı, sağlanan ekstralardaki filtreleri işleme aldıysa anahtarı
ContentResolver#EXTRA_HONORED_ARGS
.
onSorguAlbümleri
onQueryAlbums()
yöntemi, şu özelliklere sahip Cloud albümlerinin listesini getirmek için kullanılır:
bilgileri, bulut sağlayıcıda ve bunlarla ilişkili meta verilerinde bulunur. Görüntüleyin
Ayrıntılı bilgi için CloudMediaProviderContract.AlbumColumns
.
Bu yöntem, medyadaki tüm albüm öğelerini temsil eden bir Cursor
döndürür
isteğe bağlı olarak sağlanan ekstralar tarafından filtrelenen ve tersine sıralanan koleksiyon
AlbumColumns#DATE_TAKEN_MILLIS
adlı öğenin kronolojik sırası , en son öğeler
tıklayın. Bulut medya sağlayıcısı,
Döndürülenler arasında CloudMediaProviderContract#EXTRA_MEDIA_COLLECTION_ID
Cursor
. Bu ayar yapılmaması bir hatadır ve döndürülen Cursor
değerini geçersiz kılar. Eğer
sağlayıcı, sağlanan ekstralardaki filtreleri işleme aldıysa anahtarı
ContentResolver#EXTRA_HONORED_ARGS
, döndürülen Cursor
kapsamındadır.
onOpenMedia
onOpenMedia()
yöntemi,
sağlanan mediaId
. Bu yöntem
iptal etmek için sağlanan CancellationSignal
cihazını düzenli aralıklarla kontrol etmeniz gerekir.
vazgeçenlerin oranı olabilir.
onOpenPreview
onOpenPreview()
yöntemi, sağlanan
Sağlanan mediaId öğesi için size
. Küçük resim
orijinal CloudMediaProviderContract.MediaColumns#MIME_TYPE
ve şu şekilde olması bekleniyor:
onOpenMedia
tarafından iade edilen öğeden çok daha düşük çözünürlüğe sahip olmalıdır. Bu yöntem
uygulama cihaza içerik indirilirken engellendiğinde düzenli olarak
Vazgeçilen istekleri iptal etmek için sağlanan CancellationSignal
öğesini kontrol edin.
onCreateCloudMediaSurfaceController
onCreateCloudMediaSurfaceController()
yöntemi,
Medya öğelerinin önizlemesini oluşturmak için CloudMediaSurfaceController
kullanılır veya
Önizleme oluşturma desteklenmiyorsa null
.
Medya öğelerinin önizlemesini oluşturmayı CloudMediaSurfaceController
yönetir
belirli Surface
örneklerinde test eder. Bu sınıfın yöntemleri şunlardır:
eşzamansız ve ağır işlemler yaparak engelleme yapmamalıdır. Tek
CloudMediaSurfaceController
örneği, birden fazla oluşturmaktan sorumlu
birden fazla yüzeyle ilişkili medya öğeleri.
CloudMediaSurfaceController
aşağıdaki listeyi destekler
yaşam döngüsü geri çağırmaları:
onConfigChange
onDestroy
onMediaPause
onMediaPlay
onMediaSeekTo
onPlayerCreate
onPlayerRelease
onSurfaceChanged
onSurfaceCreated
onSurfaceDestroyed