Update: 2026-05-16 22:03:25
This commit is contained in:
@@ -1,29 +1,155 @@
|
|||||||
package com.jordanbot.autoride
|
package com.jordanbot.autoride
|
||||||
|
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
import android.media.MediaPlayer
|
import android.media.MediaPlayer
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.ProgressBar
|
||||||
|
import android.widget.ScrollView
|
||||||
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
class TutorialActivity : AppCompatActivity() {
|
class TutorialActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private var mediaPlayer: MediaPlayer? = null
|
private var mediaPlayer: MediaPlayer? = null
|
||||||
|
|
||||||
|
// Tutorial steps: image URL + title + description
|
||||||
|
private data class TutorialStep(
|
||||||
|
val imageUrl: String,
|
||||||
|
val title: String,
|
||||||
|
val description: String,
|
||||||
|
val titleColor: String
|
||||||
|
)
|
||||||
|
|
||||||
|
private val steps = listOf(
|
||||||
|
TutorialStep(
|
||||||
|
imageUrl = "https://lawer.tripz-egypt.com/jordan_bot/tutorial/step1.png",
|
||||||
|
title = "الخطوة ١: ابحث عن التطبيق",
|
||||||
|
description = "اذهب إلى إعدادات الهاتف → إدارة التطبيقات → ابحث عن Jordan Bot واضغط عليه.",
|
||||||
|
titleColor = "#4CAF50"
|
||||||
|
),
|
||||||
|
TutorialStep(
|
||||||
|
imageUrl = "https://lawer.tripz-egypt.com/jordan_bot/tutorial/step2.png",
|
||||||
|
title = "الخطوة ٢: فك القيود (أهم خطوة!)",
|
||||||
|
description = "اضغط على النقاط الثلاث ⋮ في أعلى الصفحة واختر 'السماح بالإعدادات المقيدة' أو 'Allow restricted settings'.",
|
||||||
|
titleColor = "#FF5252"
|
||||||
|
),
|
||||||
|
TutorialStep(
|
||||||
|
imageUrl = "https://lawer.tripz-egypt.com/jordan_bot/tutorial/step3.png",
|
||||||
|
title = "الخطوة ٣: فعّل الصلاحية",
|
||||||
|
description = "ارجع إلى التطبيق وقم بتفعيل صلاحيات إمكانية الوصول والإشعارات. اضغط 'سماح' عند ظهور التأكيد.",
|
||||||
|
titleColor = "#4CAF50"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_tutorial)
|
setContentView(R.layout.activity_tutorial)
|
||||||
|
|
||||||
|
// Load images from server
|
||||||
|
loadTutorialImages()
|
||||||
|
|
||||||
|
// Audio button
|
||||||
findViewById<Button>(R.id.btn_play_audio).setOnClickListener {
|
findViewById<Button>(R.id.btn_play_audio).setOnClickListener {
|
||||||
playTutorialAudio()
|
playTutorialAudio()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadTutorialImages() {
|
||||||
|
val container = findViewById<LinearLayout>(R.id.tutorial_steps_container)
|
||||||
|
container.removeAllViews()
|
||||||
|
|
||||||
|
for (step in steps) {
|
||||||
|
// Create step card
|
||||||
|
val card = LinearLayout(this).apply {
|
||||||
|
orientation = LinearLayout.VERTICAL
|
||||||
|
setBackgroundColor(android.graphics.Color.parseColor("#1E1E1E"))
|
||||||
|
setPadding(dp(16), dp(16), dp(16), dp(16))
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
).apply { bottomMargin = dp(20) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Title
|
||||||
|
val title = TextView(this).apply {
|
||||||
|
text = step.title
|
||||||
|
setTextColor(android.graphics.Color.parseColor(step.titleColor))
|
||||||
|
textSize = 20f
|
||||||
|
setTypeface(typeface, android.graphics.Typeface.BOLD)
|
||||||
|
setPadding(0, 0, 0, dp(8))
|
||||||
|
}
|
||||||
|
card.addView(title)
|
||||||
|
|
||||||
|
// Description
|
||||||
|
val desc = TextView(this).apply {
|
||||||
|
text = step.description
|
||||||
|
setTextColor(android.graphics.Color.parseColor("#BBBBBB"))
|
||||||
|
textSize = 15f
|
||||||
|
setPadding(0, 0, 0, dp(12))
|
||||||
|
}
|
||||||
|
card.addView(desc)
|
||||||
|
|
||||||
|
// Loading indicator
|
||||||
|
val progress = ProgressBar(this).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
).apply { gravity = android.view.Gravity.CENTER }
|
||||||
|
}
|
||||||
|
card.addView(progress)
|
||||||
|
|
||||||
|
// Image
|
||||||
|
val imageView = ImageView(this).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
dp(350)
|
||||||
|
)
|
||||||
|
scaleType = ImageView.ScaleType.FIT_CENTER
|
||||||
|
setBackgroundColor(android.graphics.Color.parseColor("#2C2C2C"))
|
||||||
|
visibility = View.GONE
|
||||||
|
}
|
||||||
|
card.addView(imageView)
|
||||||
|
|
||||||
|
container.addView(card)
|
||||||
|
|
||||||
|
// Load image async
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val url = URL(step.imageUrl)
|
||||||
|
val bitmap = BitmapFactory.decodeStream(url.openStream())
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
progress.visibility = View.GONE
|
||||||
|
imageView.setImageBitmap(bitmap)
|
||||||
|
imageView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
progress.visibility = View.GONE
|
||||||
|
// Image failed to load - text instructions remain visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun playTutorialAudio() {
|
private fun playTutorialAudio() {
|
||||||
if (mediaPlayer?.isPlaying == true) {
|
if (mediaPlayer?.isPlaying == true) {
|
||||||
mediaPlayer?.stop()
|
mediaPlayer?.stop()
|
||||||
mediaPlayer?.release()
|
mediaPlayer?.release()
|
||||||
mediaPlayer = null
|
mediaPlayer = null
|
||||||
|
findViewById<Button>(R.id.btn_play_audio).text = "استمع للشرح الصوتي 🔊"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,14 +158,20 @@ class TutorialActivity : AppCompatActivity() {
|
|||||||
mediaPlayer?.setOnCompletionListener {
|
mediaPlayer?.setOnCompletionListener {
|
||||||
it.release()
|
it.release()
|
||||||
mediaPlayer = null
|
mediaPlayer = null
|
||||||
|
findViewById<Button>(R.id.btn_play_audio).text = "استمع للشرح الصوتي 🔊"
|
||||||
}
|
}
|
||||||
mediaPlayer?.start()
|
mediaPlayer?.start()
|
||||||
|
findViewById<Button>(R.id.btn_play_audio).text = "إيقاف الشرح ⏸"
|
||||||
Toast.makeText(this, "جاري تشغيل الشرح الصوتي... 🔊", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "جاري تشغيل الشرح الصوتي... 🔊", Toast.LENGTH_SHORT).show()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Toast.makeText(this, "خطأ في تشغيل الصوت", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "خطأ في تشغيل الصوت", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun dp(value: Int): Int {
|
||||||
|
return (value * resources.displayMetrics.density).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
mediaPlayer?.release()
|
mediaPlayer?.release()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="24dp">
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -19,109 +20,36 @@
|
|||||||
android:textSize="24sp"
|
android:textSize="24sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginBottom="16dp"/>
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="إذا كانت الصلاحيات تظهر باللون الرمادي، يرجى اتباع الخطوات التالية بدقة:"
|
android:text="إذا كانت الصلاحيات تظهر باللون الرمادي، اتبع الخطوات التالية:"
|
||||||
android:textColor="#BBBBBB"
|
android:textColor="#BBBBBB"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:textAlignment="center"/>
|
android:textAlignment="center"/>
|
||||||
|
|
||||||
<!-- Step 1 -->
|
<!-- Steps will be loaded dynamically here -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/tutorial_steps_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="vertical"/>
|
||||||
android:background="#1E1E1E"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<TextView
|
<!-- Audio Guide Button -->
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:text="1"
|
|
||||||
android:background="@drawable/circle_background"
|
|
||||||
android:textColor="#FFFFFF"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_marginEnd="16dp"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="افتح 'معلومات التطبيق'"
|
|
||||||
android:textColor="#FFFFFF"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="اضغط مطولاً على أيقونة البوت واختر (معلومات التطبيق)."
|
|
||||||
android:textColor="#AAAAAA"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Step 2 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:background="#1E1E1E"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:text="2"
|
|
||||||
android:background="@drawable/circle_background_red"
|
|
||||||
android:textColor="#FFFFFF"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_marginEnd="16dp"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="فك القيود (أهم خطوة)"
|
|
||||||
android:textColor="#FF5252"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="اضغط على النقاط الثلاث ⋮ في الأعلى واختر 'السماح بالإعدادات المقيدة'."
|
|
||||||
android:textColor="#AAAAAA"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Audio Guide -->
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btn_play_audio"
|
android:id="@+id/btn_play_audio"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="استمع للشرح الصوتي 🔊"
|
android:text="استمع للشرح الصوتي 🔊"
|
||||||
android:backgroundTint="#2196F3"
|
android:backgroundTint="#2196F3"
|
||||||
android:layout_gravity="center"
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="18sp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginBottom="32dp"/>
|
android:layout_marginBottom="32dp"
|
||||||
|
android:padding="16dp"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|||||||
@@ -35,62 +35,46 @@ class MainActivity : AppCompatActivity() {
|
|||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
updateButtonState()
|
updateButtonState()
|
||||||
|
|
||||||
binding.btnInstall.setOnClickListener {
|
|
||||||
if (isAppInstalled()) {
|
|
||||||
showUninstallDialog()
|
|
||||||
} else {
|
|
||||||
startDownloadAndInstall()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
// Scenario 1: Returning after uninstalling old version -> Start fresh install
|
// Returning after uninstalling old version -> Start fresh install
|
||||||
if (pendingInstallAfterUninstall && !isAppInstalled()) {
|
if (pendingInstallAfterUninstall && !isAppInstalled()) {
|
||||||
pendingInstallAfterUninstall = false
|
pendingInstallAfterUninstall = false
|
||||||
startDownloadAndInstall()
|
startDownloadAndInstall()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scenario 2: Returning after successful install -> Immediate cleanup
|
|
||||||
if (isAppInstalled() && !pendingInstallAfterUninstall) {
|
|
||||||
performImmediateCleanup()
|
|
||||||
}
|
|
||||||
|
|
||||||
updateButtonState()
|
updateButtonState()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateButtonState() {
|
private fun updateButtonState() {
|
||||||
if (isAppInstalled()) {
|
|
||||||
binding.btnInstall.text = "تم التثبيت ✅"
|
|
||||||
binding.tvStatus.text = "سيتم حذف هذا المخلص الآن..."
|
|
||||||
} else {
|
|
||||||
binding.btnInstall.text = "تثبيت Jordan Bot"
|
|
||||||
binding.tvStatus.text = "جاهز للتثبيت ✅"
|
|
||||||
}
|
|
||||||
binding.btnInstall.isEnabled = !isAppInstalled()
|
|
||||||
binding.progressBar.visibility = View.GONE
|
binding.progressBar.visibility = View.GONE
|
||||||
}
|
|
||||||
|
|
||||||
private fun performImmediateCleanup() {
|
if (isAppInstalled()) {
|
||||||
// 1. Launch the Bot
|
// App is installed - show success state, no install prompt
|
||||||
|
binding.tvStatus.text = "✅ Jordan Bot مثبت بنجاح على جهازك"
|
||||||
|
binding.btnInstall.text = "فتح Jordan Bot"
|
||||||
|
binding.btnInstall.isEnabled = true
|
||||||
|
binding.btnInstall.setOnClickListener {
|
||||||
val launchIntent = packageManager.getLaunchIntentForPackage(JORDAN_BOT_PACKAGE)
|
val launchIntent = packageManager.getLaunchIntentForPackage(JORDAN_BOT_PACKAGE)
|
||||||
launchIntent?.let {
|
if (launchIntent != null) {
|
||||||
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
startActivity(launchIntent)
|
||||||
startActivity(it)
|
} else {
|
||||||
|
android.widget.Toast.makeText(this, "تعذر فتح التطبيق", android.widget.Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// App is NOT installed - show install button
|
||||||
|
binding.tvStatus.text = "جاهز للتثبيت ✅"
|
||||||
|
binding.btnInstall.text = "تثبيت Jordan Bot"
|
||||||
|
binding.btnInstall.isEnabled = true
|
||||||
|
binding.btnInstall.setOnClickListener {
|
||||||
|
startDownloadAndInstall()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Trigger self-uninstall
|
|
||||||
val intent = Intent(Intent.ACTION_DELETE)
|
|
||||||
intent.data = Uri.parse("package:$packageName")
|
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
startActivity(intent)
|
|
||||||
|
|
||||||
// 3. Close the installer
|
|
||||||
finish()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isAppInstalled(): Boolean {
|
private fun isAppInstalled(): Boolean {
|
||||||
|
|||||||
BIN
tutorial/step1.png
Normal file
BIN
tutorial/step1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 336 KiB |
BIN
tutorial/step2.png
Normal file
BIN
tutorial/step2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 368 KiB |
BIN
tutorial/step3.png
Normal file
BIN
tutorial/step3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 395 KiB |
Reference in New Issue
Block a user