Skip to main content

simple_query_android 0.3.0 copy "simple_query_android: ^0.3.0" to clipboard
simple_query_android: ^0.3.0 copied to clipboard

PlatformAndroid
unlisted

Android implementation for the simple_query federated plugin.

0.3.0 #

  • Behavior change: no host call lets a raw PlatformException reach callers any more (UNFY-300). The Kotlin host classifies each failure by exception type into the bridge code vocabulary, and the Dart side maps it to SimpleQueryError: a provider SecurityException → permissionDenied, IllegalArgumentException (e.g. Unknown URI) → invalidQuery, UnsupportedOperationException → notSupported, and so on per docs/ERROR_MAPPING.md. Anything unlisted → transientFailure. This covers queries, joins, mutations, batches, binary open/close, provider calls, file extraction, observers and the permission pre-flight. Errors carry domain, operation, a simple_query: message, details.code, details.nativeType and the host details, and keep the original stack trace. Callers that caught PlatformException must catch SimpleQueryError and switch on its code.

  • observe() now delivers a failed observer registration as a stream error, instead of an uncaught error (UNFY-300).

  • Writes, batches and provider calls now acquire the provider first. A missing provider fails as unavailable (not invalidQuery), and a provider that dies mid-write fails as unavailable instead of silently returning a null insert URI or a -1 count (UNFY-300).

  • extractToFile no longer turns every native failure into unavailable ("returned no output path") and no longer leaks its temp file on failure. It raises the mapped failure instead; unavailable remains for a provider that hands back no stream (UNFY-300).

  • dispose() now runs every cleanup step even when a host call fails, then throws the first failure, instead of stopping at the first one (UNFY-300).

  • A failed native stream close, if the platform reports one, is no longer ignored: closeBinary() raises it, mapped to transientFailure, and dispose() raises the first such failure after finishing its cleanup (UNFY-300).

  • A background openBinary() content failure now closes the pipe's write end, so a reader sees end-of-stream instead of blocking until closeBinary(). The native side reports the failure, but Dart does not yet surface it to callers, so end-of-stream alone does not mean the copy succeeded (UNFY-300; surfacing it is UNFY-333).

  • No pipe end is closed twice from two threads any more, so a copy finishing during closeBinary() can no longer close the same descriptor twice. Releasing a stream stops its copy, whether it is queued, running, or stalled in a provider read (UNFY-300).

  • Plugin detach now cancels in-flight host calls and sends no reply or stream error to the detached engine. An observer or stream registered while the plugin detaches is released instead of leaking (UNFY-300).

  • The permission pre-flight SimpleQueryError(permissionDenied) now carries the request's domain (UNFY-300).

  • Behavior change: a null resolver cursor (provider unreachable, or none returned) on the Dart query() path and the android.provider queryWithJoins extension now throws SimpleQueryError(code: unavailable) with domain, operation and the failing provider's details.contentUri, instead of returning an empty result. Callers that relied on [] for an optional provider must catch unavailable. queryWithJoins raises it for the primary query and for any related query, whose join is named in the native details. Other host errors map as described in the UNFY-300 entry above (UNFY-284).

  • Add ContentQuery.queryOrNull(...), which returns null when the resolver hands back a null cursor (provider unreachable, or none returned) and an empty list only for zero matching rows; ContentQuery.query(...) now delegates to it and still returns an empty list for both (UNFY-284).

  • fix(UNFY-172): migrate Android and example to built-in Kotlin

  • fix(UNFY-300): unblock a stalled provider read on release; honest stream-error docs

  • fix(UNFY-300): report closeBinary failures with their request context

  • fix(UNFY-300): let a release stop a running copy; tighten detach races

  • fix(UNFY-300): give each pipe end one closer; release streams and observers on detach

  • fix(UNFY-300): close stream pipes on every exit; surface close failures

  • fix(UNFY-300): classify extraction failures; reply on body cancellation

  • fix(UNFY-300): address /code-review findings on host-error mapping

  • fix(UNFY-300): map every Android host error to SimpleQueryError

  • fix(UNFY-284): surface a null cursor on the Dart query path as SimpleQueryError(unavailable)

  • feat(UNFY-284): add ContentQuery.queryOrNull to distinguish no cursor from zero rows

0.2.3 #

  • fix(UNFY-123): validate the MMS query dependency release
  • fix(UNFY-270): preserve ambiguous observer mutation types
  • fix(UNFY-270): validate observer identity and dependency contract
  • fix(UNFY-270): make observer flag tests executable
  • fix(UNFY-270): correct URI pathSegments length check for direct message-row URIs
  • fix(UNFY-270): restrict URI parsing to direct message-row URIs, clean test
  • fix(UNFY-270): clean test deps, correct selfChange contract docs
  • fix(UNFY-270): forward selfChange/flags through ContentObserver, regenerate pigeon
  • chore(release): reset versions to align with pub.dev (smallest iteration)
  • fix: address review feedback on PR #31 (staging→main)
  • chore: bring .gitignore to Flutter-template parity + untrack pubspec.lock files
  • chore(release): unblock pub publish — split path overrides into pubspec_overrides.yaml
  • fix/queryrequest-const
  • test: propagate const→final flip across all affected packages
  • chore(release): coordinated 0.6.0 across all simple_query packages
  • docs+tool: CHANGELOG Unreleased discipline
  • chore(release): coordinated 0.5.0 across all simple_query packages
  • chore(pigeon): pin to 22.7.4 + CI drift check + regen tool
  • chore(release): coordinated 0.4.0 across all simple_query packages
  • feat(permissions): inline check, drop simple_permissions dependency
  • Bumped Android Build Versions
  • feat(android): symmetric canonical/native field translation + calls extras
  • release: 0.3.1 — coordinated bump + audit-driven cleanup (#20)
  • Merge pull request #7 from jake-dev-99/staging
  • fix(android): defer SimpleQueryAndroidApi construction
  • ci: address review feedback + unblock CI
  • feat(kotlin): ContentQuery helper for sibling plugins
  • chore: alphabetize imports + refresh lockfiles
  • chore(deps): bump simple_permissions_native pin to ^1.2.0
  • Initial Push

Unreleased #

  • Require platform interface >=0.2.1 for the field catalog used by Android query mapping (UNFY-123).
  • Keep callbacks with multiple Android mutation flags unknown while preserving their raw flags (UNFY-270).
  • Preserve Android observer selfChange, raw flags, change type, and direct SMS/MMS row IDs; keep unsupported and descendant URIs identifier-free (UNFY-270).
  • Exercise all native observer callbacks and public Dart event mapping; align generated selfChange documentation.

0.2.1 #

Reset to align with pub.dev's published series #

This package on pub.dev is at 0.2.0. Local git tags 0.3.0 (and 0.3.1 on _android) and the develop pubspec at 0.6.0 were authored ahead of the next publish but never reached pub.dev. Orphan tags deleted from origin and the version reset to the smallest patch above the last-published version (0.2.0 → 0.2.1).

Cross-package constraints lowered from ^0.6.0 to ^0.2.0 to match the published series.

The 0.3 — 0.6 work described in the entries below is not lost — it lives in source and will surface in published form through subsequent patch / minor / major bumps as appropriate. Entries kept for archival reference.

0.6.0 #

Documentation and developer-experience release. Strictly additive — no public-API changes from 0.5.0.

Added #

  • docs/DESIGN.md — codifies the seven design principles (P1–P7 plus the permissions rule) that govern the public API. Read before contributing.
  • docs/EXTENSIONS.md — single index linking the five per-platform extension docs with a usage example and stability policy.
  • tool/regen_pigeon.sh already landed in 0.5.0; documented here for completeness.
  • Every package's CHANGELOG.md now leads with a ## Unreleased section. tool/publish.sh warns when the section is still present during a live publish.

Changed #

  • Root README.md now links every doc (DESIGN, API_SEMANTICS, ERROR_MAPPING, MIGRATION, PLATFORM_SUPPORT_MATRIX, EXTENSIONS, RELEASE) in a navigation table. "Highlights" expanded to cover the 0.4.0 / 0.5.0 additions.
  • docs/MIGRATION.md rewritten to cover iOS / macOS / desktop migrations alongside Android. Includes the column-name → canonical-field translation table for 0.4.0's symmetric vocabulary.
  • docs/API_SEMANTICS.md — "include reserved for future use" replaced with a clear non-goal statement and pointer to callExtension('android.provider', 'queryWithJoins').
  • docs/RELEASE.md — adds a "CHANGELOG discipline" section documenting the Unreleased → release promotion flow.
  • SimpleQueryPlatform (platform interface) now has class-level and per-method dartdoc. Documents that instance = is not thread-safe.
  • SimpleQuery (facade) class doc calls out the singleton contract explicitly and explains how tests swap the backend (via SimpleQueryPlatform.instance, not the facade).
  • Every facade passthrough (query, mutate, batch, observe, callExtension, dispose) now has a dartdoc block with cross-links.
  • QueryDomainContracts and CapabilityContracts have class-level dartdoc.

Example app #

  • Rewritten to showcase the full 0.5.0 API: queryBuilder, queryPaginated, mutate round-trip, observe with live filesystem events, withBinaryContent, callExtension (platform-aware), and queryRaw (Android). Buttons are capability-gated; a refresh button re-probes.

Migration #

None required — docs/example/dartdoc changes only.

0.5.0 #

Consumer-ergonomics release. Additive — no breaking changes from 0.4.0.

Added #

  • SimpleQuery.queryPaginated(request) — returns a Stream<QueryResult> that walks nextCursor / nextOffset to exhaustion. Cursor is preferred when both are present; stops on the first empty page or when both pagination tokens are null. Cancellable via the stream subscription.
  • SimpleQuery.queryPaginatedTyped<T>(request, fromRecord) — same but maps each page through fromRecord. Mapping failures wrapped in SimpleQueryError(invalidQuery, details: {recordIndex, cause}) like queryTyped.
  • BinaryContent class wraps BinaryContentHandle with typed getters and a self-closing close() that's idempotent.
  • SimpleQuery.openBinaryContent(request) — opens binary content as a BinaryContent.
  • SimpleQuery.withBinaryContent(request, body) — scoped helper that runs body with an open BinaryContent and guarantees close on return or throw.
  • SimpleQuery.queryBuilder(domain) — fluent entry point for building queries off the facade instead of importing QueryBuilder directly.
  • QueryBuilder.pageOffset({limit, required offset}) and pageCursor({limit, required cursor}) — type-safe pagination convenience methods.
  • QueryBuilder.executePaginated() — convenience for queryPaginated(build()).

Changed #

  • QueryBuilder.build() now validates filter/sort/projection field names against QueryFieldCatalog before returning. Unknown canonical fields throw SimpleQueryError(invalidQuery, details: {field, allowed}) instead of failing later in the platform layer with a less actionable error. No-op for QueryDomain.platformSpecific.

Tooling #

  • Pigeon dependency pinned to exact version 22.7.4 in every platform package — different developers will produce identical generated output.
  • New tool/regen_pigeon.sh regenerates every platform's pigeon glue and runs dart format on the output for stable line-wrap.
  • New pigeon-drift CI job re-runs the regen tool and fails the build if the committed .g.dart / .g.kt are stale. Catches "edited pigeon.dart but forgot to commit the regen" before merge.

Migration #

None required. All additions are new methods; existing code keeps working.

Deferred #

  • Typed callExtension registry (plan 2.5) — needs concrete consumer demand to design correctly; raw callExtension remains the supported path.

0.4.0 #

Breaking changes #

  • Filter / sort / projection field vocabulary is now canonical on every named domain. Callers must pass the canonical names (callType, timestamp, durationSec, id, ...) defined in QueryFieldCatalog.canonicalFields(domain). Raw native column names (type, date, _id, ...) on a named domain throw SimpleQueryError(invalidQuery, details: {field, allowed}). Use QueryDomain.platformSpecific (or SimpleQuery.queryRaw) when you need raw column names.
  • Android: simple_permissions_native dependency dropped. The SimpleQueryAndroidApi constructor no longer takes a checkPermission callback. simple_query checks permissions inline via a new pigeon hasPermission call and throws SimpleQueryError(permissionDenied, details: {permissions: [...], contentUri, write}) when a permission is missing. Callers request the permission via their own mechanism (permission_handler, simple_permissions, raw ActivityCompat.requestPermissions) and retry.

Added #

  • QueryFieldCatalog (in simple_query_platform_interface) — single source of truth for the canonical field vocabulary per domain. Exposes canonicalFields(domain), ensureKnown({domain, canonical}), and ensureAllKnown({domain, fields}). No-op for QueryDomain.platformSpecific.
  • RuntimeContractValidation.validateQueryRequest / validateMutationRequest (extended) / validateObserveRequest (extended) now reject unknown canonical fields with a clear error before reaching the platform.
  • SimpleQuery.queryRaw({contentUri, ...}) — first-class entry point for arbitrary content providers (content://com.biz.app/...). Bypasses canonical validation; returns raw Map<String, Object?> records. Currently Android-only.
  • Every typed *Record (Contact, CalendarEvent, Media, File, Message, Call) now exposes raw: Map<String, Object?> (untouched source map) and extras: Map<String, Object?> (raw minus canonical keys). Surfaces OEM and niche columns without losing the typed view.
  • CallRecord gains the optional canonical fields isNew, isRead, geocodedLocation, subscriptionId, populated by Android from native columns new, is_read, geocoded_location, subscription_id. Absent (not defaulted) on devices that don't expose the column. Closes the gap surfaced by simple-telephony's listCallLog handoff.

Changed #

  • Android backend now translates canonical filter / sort / projection field names to native ContentResolver columns symmetrically (output records were already canonical). New _AndroidFieldAliases helper centralises the mapping; platformSpecific skips translation.
  • Apple permissionDenied errors now carry details: {framework, infoPlistKey, authorizationStatus} so callers learn exactly which Info.plist usage description to declare.
  • Filesystem fallback (Linux / Windows / non-Android desktop) maps FileSystemException with errno 1 / 13 / 5 (EPERM, EACCES, ERROR_ACCESS_DENIED) to SimpleQueryErrorCode.permissionDenied instead of the previous unavailable.
  • validateBatchRequest no longer cascades to per-operation validation. Batches are sequentialBestEffort — a malformed op records its error in per-result metadata.error instead of aborting the batch.

Migration #

  • If you currently filter or sort on a named domain using raw Android column names, switch to canonical names. Example: field: 'type' → field: 'callType', field: 'date' → field: 'timestamp', field: '_id' → field: 'id'. Full catalog: QueryFieldCatalog.canonicalFields(domain).
  • If you constructed SimpleQueryAndroidApi directly with checkPermission:, drop the argument. The internal pigeon-based permission check replaces it. Permission requests stay your responsibility.
  • If your app handled SimpleQueryErrorCode.unavailable for filesystem permission errors, add a permissionDenied branch.

0.3.1 #

Coordinated release #

  • Part of the lock-step 0.3.1 release across all simple_query_* packages. See the matching entry in simple_query and simple_query_platform_interface for the cross-package work (strict record type coercion, extended runtime validation, copyWith null-clearing, constructor guards on QueryPage / QueryFilterCondition, shared FakeSimpleQueryPlatform).

Fixed #

  • SimpleQueryAndroid.registerWith() no longer throws "Binding has not yet been initialized" when called from Flutter's generated Dart plugin registrant. SimpleQueryAndroidApi's constructor calls QueryFlutterApi.setUp(this), which touches the default binary messenger — but the registrant runs before WidgetsFlutterBinding.ensureInitialized(), so eager construction failed, the registrant's try/catch swallowed the error, and SimpleQueryPlatform.instance silently stayed as the "unsupported" stub. Every query / observe call on Android then threw notSupported against consumer apps. _api is now late final, deferring construction to first method call — by which point runApp has run and the binding is ready.

0.2.1 #

  • Bump simple_permissions_native dependency constraint from ^0.0.1 to ^1.2.0 to match the current published version. No API changes.

0.2.0 #

  • Initial public release.
  • Typed query API with 7 domains: contacts, media, files, calendar, messages, calls, platformSpecific.
  • Cursor-based and offset-based pagination.
  • Capability-driven design via getCapabilities().
  • Typed record classes: ContactRecord, CalendarEventRecord, MediaRecord, FileRecord, MessageRecord, CallRecord.
  • Structured error model with 5 error codes.
0
likes
150
points
174
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Android implementation for the simple_query federated plugin.

Repository (GitHub)
View/report issues

Topics

#flutter #plugin #contacts #query #files

License

BSD-3-Clause (license)

Dependencies

flutter, simple_query_platform_interface

More

Packages that depend on simple_query_android

Packages that implement simple_query_android