diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 641cace..5f13117 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -46,8 +46,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -70,8 +94,10 @@ - - + + diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index ed0dc44..b6e28ca 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -53,6 +53,7 @@ import Invitation, { import { returnOrUpdate } from 'ol/extent'; import Updater from '../updater'; import SystemDrawer from '../system-drawer'; +import { receiveIntent } from '../../lib/intent-receivers'; const [getState, setState] = createSignal({ lon: 0, @@ -101,6 +102,9 @@ const Map: Component = () => { if (searchInvitationInIntent(intent)) { return; } + if (receiveIntent(intent)) { + return; + } if (intent.action === 'android.intent.action.VIEW') { const url = new URL(intent.data); console.log({ caller: 'Intent receiver', intent, url }); @@ -166,13 +170,6 @@ const Map: Component = () => { if (matches) { findLocation(navigate, [matches[3], matches[2]]); } - } else if ( - intent.action === 'android.intent.action.SEND' && - !!intent.extras['android.intent.extra.STREAM'] - ) { - const uri = intent.extras['android.intent.extra.STREAM']; - // intent.type is 'image/*' for gallery share - importUrls([uri]); } }); } else { diff --git a/src/lib/intent-receivers/gpx-receiver.ts b/src/lib/intent-receivers/gpx-receiver.ts new file mode 100644 index 0000000..14e4c5d --- /dev/null +++ b/src/lib/intent-receivers/gpx-receiver.ts @@ -0,0 +1,34 @@ +import { importUrls } from '../../components/import'; + +const ACCEPTED_ACTIONS = [ + 'android.intent.action.VIEW', + 'android.intent.action.SEND', +]; + +const ACCEPTED_PROTOCOLS = ['content:']; + +const ACCEPTED_TYPES = [ + 'application/xml', + 'application/gpx+xml', + 'text/xml', + 'text/plain', + 'image/*', + 'image/jpeg', +]; + +export const gpxReceiver = (intent: any, url: URL | undefined) => { + if (!ACCEPTED_ACTIONS.includes(intent.action)) { + return false; + } + + if (!url) { + return false; + } + + if (!ACCEPTED_PROTOCOLS.includes(url.protocol)) { + return false; + } + + importUrls([url.toString()]); + return true; +}; diff --git a/src/lib/intent-receivers/index.ts b/src/lib/intent-receivers/index.ts new file mode 100644 index 0000000..e0f9e20 --- /dev/null +++ b/src/lib/intent-receivers/index.ts @@ -0,0 +1,24 @@ +import { gpxReceiver } from './gpx-receiver'; + +const receivers = { + gpxReceiver, +}; + +export const receiveIntent = (intent: any) => { + let url: URL | undefined; + try { + url = new URL( + intent.extras && intent.extras['android.intent.extra.STREAM'] + ? intent.extras['android.intent.extra.STREAM'] + : intent.data + ); + } catch (error) { + console.error({ caller: 'receiveIntent / URL', error }); + } + + const found = Object.values(receivers).some((receiver) => + receiver(intent, url) + ); + + return found; +};