Free HTML to APK
المطورون

JavaScript API

التطبيقات المبنية بـ Free HTML to APK تحقن جسرًا أصليًا باسم window.FreeApp. استدعِه من JavaScript العادي أو من React أو Vue أو من محرك ألعاب. تظل صفحتك تعمل في متصفح عادي إذا حميتَ الاستدعاءات.

البدء

قد يصل الجسر بعد لحظة من تشغيل نصوصك البرمجية، لذا أجرِ الإعداد الأصلي في الحدث freeappready، وكذلك فورًا إذا كان window.FreeApp موجودًا بالفعل. وفّر دائمًا بديلًا للمتصفح.

function setup() {
  FreeApp.statusBar('#E2552A');
  FreeApp.toast('Hello from Android');
}
if (window.FreeApp) setup();
else window.addEventListener('freeappready', setup, { once: true });

document.querySelector('#buzz').onclick = () =>
  window.FreeApp ? FreeApp.vibrate(40) : console.log('Not in the app');

الاستدعاءات التي تحتاج إذنًا (الكاميرا، الميكروفون، الموقع، الإشعارات) تسأل المستخدم في المرة الأولى. فعّل الإذن المطابق في خطوة الأذونات في المنشئ؛ والقوالب تفعّل ما يستخدمه كودها.

التغذية الراجعة والواجهة

FreeApp.brightness(level: number): void

من 0.0 إلى 1.0 لهذه النافذة، والقيمة السالبة تعيد سطوع النظام.

FreeApp.fullscreen(on: boolean): void

أخفِ أشرطة النظام (وضع الانغماس).

FreeApp.keepAwake(on: boolean): void

أبقِ الشاشة قيد التشغيل.

FreeApp.notify(title: string, body?: string): void

إشعار محلي فوري (يطلب الإذن على Android 13 وما بعده).

FreeApp.orientation(value: 'portrait' | 'landscape' | 'sensor_portrait' | 'sensor_landscape' | 'sensor' | 'unspecified'): void
FreeApp.print(): void

اطبع الصفحة / احفظها بصيغة PDF.

FreeApp.scheduleNotification(title: string, body: string, delayMs: number, opts?: {id?: number, url?: string, repeatMs?: number, exact?: boolean}): number

تُرجع المعرّف.

FreeApp.speak(text: string, lang?: string): void

تحويل النص إلى كلام أصلي، اللغة مثل 'en-US'.

FreeApp.statusBar(hexColor: string): void

مثال: '#2563EB'.

FreeApp.stopSpeaking(): void
FreeApp.toast(message: string): void

رسالة toast أصلية قصيرة.

FreeApp.vibrate(ms?: number | number[]): void

اهتزازة واحدة (الافتراضي 50 مللي ثانية) أو نمط [إيقاف، تشغيل، إيقاف، تشغيل…].

الكاميرا والمسح

FreeApp.camera.capture(opts?: {maxSize?: number, quality?: number, mirror?: boolean}): Promise<{dataUrl, facing}>

صورة ثابتة من المعاينة الجارية.

FreeApp.camera.start(opts?: {facing?: 'back' | 'front', element?: string | Element /* place the preview over this element */, behind?: boolean /* draw under a transparent page so HTML controls float on top */}): Promise<{facing}>
FreeApp.camera.switch(): Promise<{facing}>; FreeApp.camera.torch(on: boolean): boolean; FreeApp.camera.stop(): void; FreeApp.camera.isOpen(): boolean
FreeApp.compressImage(dataUrl: string, opts?: {maxSize?: number, quality?: number}): Promise<{dataUrl, width, height, bytes}>

أصلي، وسريع على الهواتف منخفضة المواصفات.

FreeApp.saveToGallery(dataUrl: string, fileName?: string): Promise<{uri}>

تحفظ صورة في الصور.

FreeApp.scanCode(opts?: {formats?: string[] /* e.g. ['QR_CODE','EAN_13','CODE_128'] */, facing?: 'back' | 'front'}): Promise<{text, format}>

ماسح QR / باركود أصلي بملء الشاشة مع مصباح؛ يُرفض بـ 'cancelled'.

FreeApp.torch(on: boolean): boolean

المصباح، يُرجع false إذا لم يكن هناك فلاش.

الموقع والمستشعرات

FreeApp.address(lat: number, lng: number): Promise<{address, city, country, countryCode, postalCode, street}>
FreeApp.compass(cb: (d: {heading: number /* degrees */, pitch: number, roll: number}) => void): (() => void) | null

تُرجع دالة إيقاف.

FreeApp.location(opts?: {maxAge?: number}): Promise<{lat, lng, accuracy, altitude, speed, provider, time, fromLastKnown}>
FreeApp.maps(query: string): void

افتح مكانًا أو "lat,lng" في تطبيق الخرائط.

FreeApp.sensors.start(type: 'accelerometer' | 'gyroscope' | 'magnetometer' | 'light' | 'proximity' | 'pressure' | 'gravity' | 'linear_acceleration' | 'rotation' | 'humidity' | 'temperature' | 'steps' | 'step_detector', cb: (d: {type, values: number[], x, y, z, accuracy, t}) => void, intervalMs?: number): (() => void) | null

تُرجع دالة إيقاف، أو null إذا لم تكن متاحة.

FreeApp.sensors.stop(type: string): void
FreeApp.watchLocation(cb: (p) => void, opts?: {interval?: number, distance?: number}): () => void

تُرجع دالة إيقاف.

الجهاز والتطبيق

FreeApp.app(): {packageName, versionName, versionCode, name, firstInstall}
FreeApp.battery(): {level: number /* 0-100 */, charging: boolean}
FreeApp.biometric(title: string, subtitle?: string): Promise<boolean>

فتح القفل ببصمة الإصبع / الوجه.

FreeApp.device(): {manufacturer, model, brand, androidVersion, sdkInt, language, screenWidth, screenHeight, density, isTablet, darkMode}
FreeApp.launchUrl(): string | null

الرابط العميق الذي فتح التطبيق.

FreeApp.network(): 'wifi' | 'cellular' | 'ethernet' | 'vpn' | 'other' | 'none' | 'unknown'
FreeApp.on('deeplink', (d: {url}) => void): () => void

الروابط التي فُتحت أثناء تشغيل التطبيق.

FreeApp.online(): boolean

الملفات والمشاركة والتخزين

FreeApp.copy(text: string): void

النسخ إلى الحافظة.

FreeApp.open(url: string): void

افتح في المتصفح / التطبيق الخارجي.

FreeApp.paste(): string

اقرأ نص الحافظة.

FreeApp.pickFile(opts?: {accept?: string[], multiple?: boolean}): Promise<{name, mime, size, dataUrl}>
FreeApp.saveFile(name: string, mime: string, data: string /* base64 or data: URL */ | Blob): Promise<boolean>

تحفظ في التنزيلات؛ FreeApp.on('saved', d => …) يعطي {name, ok, location}.

FreeApp.share(text: string, title?: string): void

نافذة المشاركة في Android.

FreeApp.shareFile(fileName: string, mimeType: string, base64OrDataUrl: string): boolean

شارك ملفًا حقيقيًا.

FreeApp.store.get(key: string): any | null
FreeApp.store.set(key: string, value: any): void

تخزين أصلي دائم بنظام مفتاح/قيمة (JSON).

NFC

FreeApp.nfc.read(): Promise<{tagId, techs: string[], writable, maxSize, records: Array<{type: "text" | "uri" | "mime" | "unknown", value, mime?, lang?}>}>

تنتظر وسمًا؛ FreeApp.nfc.stop() يلغي ذلك.

FreeApp.nfc.status(): 'ready' | 'disabled' | 'unsupported' | 'not_enabled_in_app'
FreeApp.nfc.write(records: string | Array<{type: 'text' | 'uri' | 'mime', value: string, mime?: string}>): Promise<{written}>

الأذونات

FreeApp.hasPermission(name: string): boolean
FreeApp.openSettings(): void

افتح صفحة إعدادات النظام لهذا التطبيق.

FreeApp.permissionStatus(name: 'camera' | 'microphone' | 'location' | 'notifications' | 'activity'): 'granted' | 'prompt' | 'blocked' | 'unavailable'
FreeApp.requestPermission(name: 'camera' | 'microphone' | 'location' | 'notifications'): Promise<boolean>
FreeApp.requestPermissions(names: string[]): Promise<{[name]: boolean}>

الإعلانات

متاح عند تفعيل AdMob في المنشئ. في وضع الاختبار تُعرض إعلانات Google التجريبية.

FreeApp.ads.loadBanner(unit?: string, position?: 'top' | 'bottom'): void

حمّل لافتة وأظهرها. بدون معاملات تستخدم الوحدة والموضع المحددين في المنشئ.

FreeApp.ads.showBanner(position?) / hideBanner() / isBannerLoaded()

أظهر اللافتة أو أخفِها أو تحقق منها.

FreeApp.ads.loadInterstitial(unit?) / showInterstitial() / isInterstitialLoaded()

إعلانات بملء الشاشة بين الشاشات. يتم فرض حد أدنى للفاصل بين إعلانات ملء الشاشة.

FreeApp.ads.loadRewarded(unit?) / isRewardedLoaded()

حمّل إعلانًا بمكافأة مسبقًا.

FreeApp.ads.showRewarded(): Promise<{ok, amount, type}>

تعرض إعلانًا بمكافأة؛ يكتمل عندما يحصل المستخدم على المكافأة، ويُرفض إذا أغلقه مبكرًا.

FreeApp.ads.privacyOptionsRequired(): boolean / showPrivacyOptions()

تتيح للمستخدمين تغيير خيارات الموافقة (مطلوب في بعض المناطق).

FreeApp.ads.adapterStatus(): {[network]: {installed, configured, ready, description, latencyMs}}

مع الوساطة: أي شبكات الشركاء موجودة داخل التطبيق وأيها أعدّها حساب AdMob الخاص بك.

FreeApp.ads.openAdInspector(): void

يفتح Ad Inspector من Google على أجهزة الاختبار.

FreeApp.ads.on(cb: (event) => void): () => void

أحداث الإعلانات مثل initialized وbannerLoaded وinterstitialDismissed وrewardedFailed. تُرجع دالة إلغاء الاشتراك.

مع شراء "إزالة الإعلانات"، تتوقف إعلانات اللافتة والإعلانات بملء الشاشة ويُطلق الحدث adFree. تستمر الإعلانات بمكافأة في العمل، لأن المستخدمين يختارون مشاهدتها.

الشراء داخل التطبيق

متاح عند تفعيل المشتريات في أداة الإنشاء. بِع منتجات لمرة واحدة، ومنتجات استهلاكية مثل العملات، واشتراكات عبر حساب Google Play الخاص بك. أنشئ المنتجات في Play Console أولًا بالمعرّفات نفسها. تعمل المشتريات في نسخة مثبّتة من Google Play، لذا اختبر باستخدام مسار اختبار ومختبِر ترخيص.

const billing = window.FreeApp && FreeApp.billing;
if (billing && billing.isOwned('pro_unlock')) unlockPro();

// Unlock in the purchase event: it also arrives for purchases finished while the app was closed.
billing && billing.on(e => { if (e.event === 'purchase' && e.id === 'pro_unlock') unlockPro(); });

buyButton.onclick = async () => {
  try { await billing.buy('pro_unlock'); }
  catch (err) { if (err.code === 'pending') show('Payment pending'); else if (err.code !== 'cancelled') show('Purchase failed'); }
};
FreeApp.billing.products(ids: string[]): Promise<Product[]>

التفاصيل المباشرة لمنتجاتك من Google Play: العنوان، والسعر المحلي، والعملة، وللاشتراكات فترة الفوترة والعروض. تُستبعد المعرّفات التي لا يعرفها Play.

FreeApp.billing.buy(id: string, opts?: {offer?: string}): Promise<Purchase>

يفتح نافذة الدفع في Google Play. للاشتراك، يختار offer خطة أساسية أو معرّف عرض. يُرفض مع خطأ رمزه cancelled أو pending أو not_found أو unavailable أو busy أو network أو developer_error.

FreeApp.billing.owned(): string[] / isOwned(id): boolean

ما يمتلكه المستخدم، محفوظًا على الهاتف، فيأتي الرد فورًا وحتى دون اتصال. استخدمه عند بدء التشغيل لفتح الميزات المدفوعة.

FreeApp.billing.restore(): Promise<{purchases, owned}>

يسأل Google Play مجددًا عن كل ما يمتلكه المستخدم، لزر استعادة المشتريات.

FreeApp.billing.consume(idOrToken: string): Promise

يستهلك منتجًا لمرة واحدة ليمكن شراؤه مرة أخرى. المنتجات المدرجة كاستهلاكية في أداة الإنشاء تُستهلك تلقائيًا.

FreeApp.billing.isAdFree(): boolean

true عندما يمتلك المستخدم أحد منتجات "إزالة الإعلانات" المحددة في أداة الإنشاء. عندها يوقف التطبيق إعلانات اللافتة والإعلانات بملء الشاشة تلقائيًا.

FreeApp.billing.manageSubscriptions(id?: string): void

يفتح شاشة الاشتراكات في Google Play، حيث يلغي المستخدمون خطتهم أو يغيّرونها.

FreeApp.billing.on(cb: (event) => void): () => void

أحداث الشراء: purchase (افتح الميزة هنا)، وpending، وowned (تغيّرت قائمة الممتلكات: شراء أو استرداد أو اشتراك منتهٍ)، وfailed، وunavailable. يُرجع دالة لإلغاء الاشتراك في الأحداث.

طبقة التوافق

الصفحات المكتوبة لأدوات HTML-to-APK الأخرى التي تستدعي window.AndroidAPI تظل تعمل: أسماء الدوال ومعرّفات الاستدعاء وأسماء الأحداث نفسها مدعومة، واستدعاءات الإعلانات آمنة وبلا أثر في التطبيقات التي لا تحتوي على إعلانات.