---
title: Android
description: قم بدمج رحلة Human Token في تطبيق Android الخاص بك باستخدام Custom Tabs — خفيف وآمن وبدون الحاجة إلى WebView.
canonical: https://developer.unico.io/ar/human-token/integrations/app/android/link-integration
locale: ar
generated_by: markdown-export
---

# Android

قم بدمج رحلة Human Token في تطبيق Android الخاص بك باستخدام Custom Tabs.

تقوم Custom Tabs بتشغيل رحلة Human Token في تبويب متصفح داخل تطبيقك. عند انتهاء الرحلة، يعيد المتصفح التوجيه إلى مخطط URL المخصص الخاص بك ويعترضه تطبيقك.

### المتطلبات الأساسية

- Android 8 (API 26) أو أحدث
- `androidx.browser:browser:1.5.0`
- مخطط URL فريد لتطبيقك (مثل `myapp`)

### الخطوة 1: إضافة التبعية

في ملف `build.gradle` الخاص بك:

```groovy
implementation("androidx.browser:browser:1.5.0")
```

### الخطوة 2: تحديد مخطط URL الخاص بك

اختر مخططًا فريدًا (مثل `myapp`). يُستخدم هذا كـ `callbackUri` عند إنشاء العملية:

```
callbackUri: myapp://callback
```

### الخطوة 3: إنشاء النشاط

```kotlin
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent

class HumanTokenActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val url = intent.getStringExtra(EXTRA_PROCESS_URL) ?: return finish()

        CustomTabsIntent.Builder()
            .build()
            .launchUrl(this, Uri.parse(url))
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        intent.data?.let { uri ->
            if (uri.scheme == "myapp") {
                // Journey completed — send processId to your backend
                val processId = uri.getQueryParameter("id")
                handleResult(processId)
            }
        }
    }

    private fun handleResult(processId: String?) {
        // Fetch the result from your backend via Get Process
        finish()
    }

    companion object {
        const val EXTRA_PROCESS_URL = "process_url"
    }
}
```

### الخطوة 4: تكوين AndroidManifest.xml

```xml
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

<activity
    android:name=".HumanTokenActivity"
    android:launchMode="singleTop"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="myapp" android:host="callback" />
    </intent-filter>
</activity>
```

يضمن `singleTop` أن يستدعي Android دالة `onNewIntent()` على النشاط الحالي بدلاً من إنشاء نشاط جديد.

### الخطوة 5: بدء الرحلة

```kotlin
val intent = Intent(this, HumanTokenActivity::class.java)
    .putExtra(HumanTokenActivity.EXTRA_PROCESS_URL, processLink)
startActivity(intent)
```

### ملخص الملفات

| الملف | الغرض |
|---|---|
| `build.gradle` | تبعية `androidx.browser` |
| `HumanTokenActivity.kt` | تشغيل Custom Tabs + معالجة إعادة التوجيه |
| `AndroidManifest.xml` | مرشح Intent لمخطط URL الخاص بك |

---

### استخدام WebView بدلاً من Custom Tabs

> **تحذير:** Custom Tabs هو النهج الموصى به. فهو أكثر أمانًا ويتعامل مع عمليات إعادة التوجيه بشكل أصلي ويتطلب تكوينًا أقل. استخدم WebView فقط إذا لم يكن Custom Tabs خيارًا متاحًا في مشروعك.

إذا كان يجب عليك استخدام `WebView`، فإن الرحلة تتطلب تمكين JavaScript وتخزين DOM وتشغيل الوسائط تلقائيًا وأذونات الكاميرا/الموقع الجغرافي بشكل صريح. بدون هذه الإعدادات، لن يتم تحميل إطار الالتقاط أو لن يتم تفعيل الكاميرا.

```kotlin
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.mediaPlaybackRequiresUserGesture = false
webView.settings.setGeolocationEnabled(true)

webView.webChromeClient = object : WebChromeClient() {
    override fun onPermissionRequest(request: PermissionRequest) {
        if (PermissionRequest.RESOURCE_VIDEO_CAPTURE in request.resources) {
            request.grant(arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE))
        } else {
            request.deny()
        }
    }

    override fun onGeolocationPermissionsShowPrompt(
        origin: String,
        callback: GeolocationPermissions.Callback
    ) {
        callback.invoke(origin, true, false)
    }
}
```

يجب أيضًا الإعلان عن أذونات `CAMERA` و`INTERNET` و`ACCESS_FINE_LOCATION` في `AndroidManifest.xml` وطلب أذونات الكاميرا والموقع في وقت التشغيل قبل تحميل عنوان URL للرحلة.

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
```