Commit b2aee152 authored by pham tuan dat's avatar pham tuan dat

init commit

parent 8e62fa32
Pipeline #8224 canceled with stages
#Tue Mar 11 13:49:45 ICT 2025
gradle.version=8.7
#Tue Mar 11 13:47:42 ICT 2025
java.home=E\:\\Android_Install\\jbr
# Default ignored files
/shelf/
/workspace.xml
Equalizes
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/audiovisualizer2" />
<option value="$PROJECT_DIR$/equalizer" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.7.20" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
# Gradle files
.gradle/
build/
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Local configuration file (sdk path, etc)
local.properties
*.iml
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
# Log/OS Files
*.log
# Android Studio generated files and folders
captures/
.externalNativeBuild/
.cxx/
*.apk
output.json
# IntelliJ
*.iml
.idea/
misc.xml
deploymentTargetDropDown.xml
render.experimental.xml
# Google Services (e.g. APIs or Firebase)
google-services.json
# Android Profiling
*.hprof
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
id "io.sentry.android.gradle" version "3.11.1"
// id 'com.google.gms.google-services'
// id 'com.google.firebase.crashlytics'
}
android {
compileSdk 34
namespace = "com.bassbooster.equalizer"
defaultConfig {
applicationId "com.bassbooster.equalizer"
minSdk 21
targetSdk 34
versionCode 14
versionName "1.0.2"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
def formattedDate = new Date().format("MM.dd.yyyy")
archivesBaseName = "Equalizer_v${versionName}(${versionCode})_${formattedDate}"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// signingConfig signingConfigs.release
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
dataBinding true
}
viewBinding {
enabled = true
}
kapt {
correctErrorTypes = true
}
packagingOptions {
resources {
excludes += "META-INF/native-image/io.sentry/sentry/native-image.properties"
}
}
// kapt {
// correctErrorTypes true
// }
// flavorDimensions "default"
// productFlavors {
// appDev {
// //add your id ad here
// manifestPlaceholders = [ ad_app_id:"ca-app-pub-3940256099942544~3347511713"]
// buildConfigField "String", "App_open_resume", "\"ca-app-pub-3940256099942544/9257395921\""
// buildConfigField "String", "Inter_splash", "\"ca-app-pub-3940256099942544/1033173712\""
// buildConfigField "String", "Native_language", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Native_tutorial", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Native_home", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Inter_home", "\"ca-app-pub-3940256099942544/1033173712\""
// buildConfigField "String", "Inter_save", "\"ca-app-pub-3940256099942544/1033173712\""
// buildConfigField "String", "Native_music", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Banner", "\"ca-app-pub-3940256099942544/6300978111\""
// buildConfigField "String", "Native_saving", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_language", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_tutorial", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_home", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_music", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_banner", "\"ca-app-pub-3940256099942544/6300978111\""
// buildConfigField "Boolean", "env_dev", "true"
// }
// appProduct {
// //add your id ad here
// // ADS CONFIG BEGIN
// manifestPlaceholders = [ ad_app_id:"ca-app-pub-3940256099942544~3347511713"]
// buildConfigField "String", "App_open_resume", "\"ca-app-pub-3940256099942544/9257395921\""
// buildConfigField "String", "Inter_splash", "\"ca-app-pub-3940256099942544/1033173712\""
// buildConfigField "String", "Native_language", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Native_tutorial", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Native_home", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Inter_home", "\"ca-app-pub-3940256099942544/1033173712\""
// buildConfigField "String", "Inter_save", "\"ca-app-pub-3940256099942544/1033173712\""
// buildConfigField "String", "Native_music", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "Banner", "\"ca-app-pub-3940256099942544/6300978111\""
// buildConfigField "String", "Native_saving", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_language", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_tutorial", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_home", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_native_music", "\"ca-app-pub-3940256099942544/2247696110\""
// buildConfigField "String", "allow_reload_banner", "\"ca-app-pub-3940256099942544/6300978111\""
// // ADS CONFIG END
// buildConfigField "Boolean", "env_dev", "false"
// }
// }
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.20"
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation project(path: ':equalizer')
implementation project(path: ':audiovisualizer2')
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// Added Dependencies
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'com.github.bumptech.glide:glide:4.9.0'
// implementation 'com.amitshekhar.android:rx2-android-networking:1.0.2'
implementation("com.github.amitshekhariitbhu.Fast-Android-Networking:rx-android-networking:1.0.4")
implementation 'io.reactivex.rxjava2:rxjava:2.2.18'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'androidx.fragment:fragment-ktx:1.1.0'
//noinspection GradleCompatible
// implementation 'com.android.support:support-compat:28.0.0'
//noinspection GradleCompatible
// implementation 'com.android.support:support-media-compat:28.0.0'
//sdp
implementation 'com.intuit.sdp:sdp-android:1.1.0'
implementation("androidx.room:room-runtime:2.5.2")
annotationProcessor "androidx.room:room-compiler:2.5.2"
// To use Kotlin annotation processing tool (kapt)
kapt("androidx.room:room-compiler:2.5.2")
// optional - Kotlin Extensions and Coroutines support for Room
implementation("androidx.room:room-ktx:2.5.2")
// optional - RxJava2 support for Room
implementation "androidx.room:room-rxjava2:2.5.2"
// optional - RxJava3 support for Room
implementation "androidx.room:room-rxjava3:2.5.2"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:2.5.2"
// optional - Test helpers
testImplementation("androidx.room:room-testing:2.5.2")
implementation("com.android.support:multidex:1.0.3")
implementation 'com.h6ah4i.android.widget.verticalseekbar:verticalseekbar:0.7.0'
//add show log
implementation 'io.sentry:sentry-android:5.0.0'
implementation 'org.greenrobot:eventbus:3.2.0'
implementation 'androidx.media:media:1.6.0'
//ads
// implementation 'apero-inhouse:apero-ads:1.10.0-snapshot14'
// implementation 'com.facebook.android:facebook-android-sdk:12.0.0'
//firebase
// implementation 'com.google.firebase:firebase-crashlytics:18.3.7'
// implementation 'com.google.firebase:firebase-analytics:21.3.0'
// // Import the BoM for the Firebase platform
// implementation(platform("com.google.firebase:firebase-bom:32.1.1"))
// Add the dependencies for the Remote Config and Analytics libraries
// When using the BoM, you don't specify versions in Firebase library dependencies
// implementation("com.google.firebase:firebase-config-ktx")
// implementation("com.google.firebase:firebase-analytics-ktx")
//loading
implementation 'com.github.ybq:Android-SpinKit:1.4.0'
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep public class com.google.android.gms.** { public protected *; }
\ No newline at end of file
package com.bassbooster.soundeffects
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.demomvvm", appContext.packageName)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:name="com.bassbooster.soundeffects.equalizer.App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Equalizes">
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.ActivityTutorialSplash"
android:screenOrientation="portrait"
android:exported="false" />
<!-- <receiver-->
<!-- android:name="com.bassbooster.soundeffects.equalizer.EqualizerWidget"-->
<!-- android:exported="false">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />-->
<!-- </intent-filter>-->
<!-- <meta-data-->
<!-- android:name="android.appwidget.provider"-->
<!-- android:resource="@xml/equalizer_widget_info" />-->
<!-- </receiver>-->
<!-- Required: set your sentry.io project identifier (DSN) -->
<meta-data
android:name="io.sentry.dsn"
android:value="https://15a8b5333393585da92e43e1b61f619c@log.toprate.io/20" /> <!-- enable automatic breadcrumbs for user interactions (clicks, swipes, scrolls) -->
<meta-data
android:name="io.sentry.traces.user-interaction.enable"
android:value="true" /> <!-- enable screenshot for crashes -->
<meta-data
android:name="io.sentry.attach-screenshot"
android:value="true" /> <!-- enable view hierarchy for crashes -->
<meta-data
android:name="io.sentry.attach-view-hierarchy"
android:value="true" /> <!-- enable the performance API by setting a sample-rate, adjust in production env -->
<meta-data
android:name="io.sentry.traces.sample-rate"
android:value="1.0" /> <!-- enable profiling when starting transactions, adjust in production env -->
<meta-data
android:name="io.sentry.traces.profiling.sample-rate"
android:value="1.0" />
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.activity.setting.permissions.PermissionsActivity"
android:screenOrientation="portrait"
android:exported="false"
tools:ignore="NewApi" />
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.activity.setting.language.LanguageActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.activity.setting.SettingActivity"
android:screenOrientation="portrait"
android:exported="false"
tools:targetApi="m" />
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.activity.SplashActivity"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.MainActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.activity.effects.EffectsActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.activity.edgelighting.activity.EdgeLightingActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name="com.bassbooster.soundeffects.equalizer.view.activity.policy.PolicyActivity"
android:screenOrientation="portrait"
android:exported="false" />
<service
android:name="com.bassbooster.soundeffects.equalizer.utils.NotificationListener"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
<service
android:name="com.bassbooster.soundeffects.equalizer.view.MainService"
android:exported="false" />
<receiver
android:name="com.bassbooster.soundeffects.equalizer.utils.MyBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="EXTRA_BUTTON_CLICKED" />
</intent-filter>
</receiver>
<!-- <receiver-->
<!-- android:name="com.bassbooster.soundeffects.equalizer.EqualizerWidget"-->
<!-- android:enabled="true"-->
<!-- android:exported="false">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />-->
<!-- </intent-filter>-->
<!-- <meta-data-->
<!-- android:name="android.appwidget.provider"-->
<!-- android:resource="@xml/equalizer_widget_info" />-->
<!-- </receiver>-->
<!-- <meta-data-->
<!-- android:name="com.google.android.gms.ads.APPLICATION_ID"-->
<!-- android:value="${ad_app_id}" />-->
<!-- <meta-data-->
<!-- android:name="com.facebook.sdk.ApplicationId"-->
<!-- android:value="@string/facebook_app_id" />-->
<!-- <meta-data-->
<!-- android:name="com.facebook.sdk.ClientToken"-->
<!-- android:value="@string/facebook_client_token" />-->
<meta-data
android:name="com.facebook.sdk.AutoInitEnabled"
android:value="true" />
<meta-data
android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
android:value="true" />
<meta-data
android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled"
android:value="true" />
<meta-data
android:name="io.sentry.additional-context"
android:value="false"
/>
<meta-data android:name="io.sentry.auto-init" android:value="false" />
</application>
</manifest>
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer
import android.app.Application
class App : Application() {
private val ADJUST_TOKEN = "v9p8b749aby8"
private val EVENT_PURCHASE_ADJUST = "6ml7tp"
private val EVENT_AD_IMPRESSION_ADJUST = "j5arsn"
// private var mFirebaseAnalytics: FirebaseAnalytics? = null
override fun onCreate() {
super.onCreate()
// Khởi tạo Firebase Analytics
// mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
//
// // Khởi tạo Firebase
// FirebaseApp.initializeApp(this)
// // Kích hoạt Crashlytics
// FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(true)
}
}
\ No newline at end of file
package com.bassbooster.equalizer
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
/**
* Implementation of App Widget functionality.
*/
class AppWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId,"mmmmm")
}
}
override fun onEnabled(context: Context) {
// Enter relevant functionality for when the first widget is created
}
override fun onDisabled(context: Context) {
// Enter relevant functionality for when the last widget is disabled
}
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
val views = RemoteViews(context?.packageName, R.layout.app_widget)
views.apply {
setTextViewText(R.id.mTxtNameBass, "Bass:")
setTextViewText(R.id.mTxtNameStereo, "Stereo")
setTextViewText(R.id.textView, "text")
setTextViewText(R.id.mTxtStereo, "100")
// setOnClickPendingIntent(
// R.id.icLeft,
// CustomNotificationService.onButtonNotificationClick(
// context = context,
// id = R.id.icLeft,
// text = text
// )
// )
// setOnClickPendingIntent(
// R.id.icRight,
// CustomNotificationService.onButtonNotificationClick(
// context = context,
// id = R.id.icRight,
// text = text
// )
// )
// setOnClickPendingIntent(
// R.id.icLight,
// CustomNotificationService.onButtonNotificationClick(
// context = context,
// id = R.id.icLight
// )
// )
// setOnClickPendingIntent(
// R.id.mOff,
// CustomNotificationService.onButtonNotificationClick(context = context, id = R.id.mOff)
// )
}
// Instruct the widget manager to update the widget
// appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
internal fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
text: String
) {
// val widgetText = context.getString(R.string.appwidget_text)
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.app_widget)
views.apply {
setTextViewText(R.id.mTxtNameBass, "Bass:")
setTextViewText(R.id.mTxtNameStereo, "Stereo")
setTextViewText(R.id.textView, text)
setTextViewText(R.id.mTxtStereo, "100")
// setOnClickPendingIntent(
// R.id.icLeft,
// CustomNotificationService.onButtonNotificationClick(
// context = context,
// id = R.id.icLeft,
// text = text
// )
// )
// setOnClickPendingIntent(
// R.id.icRight,
// CustomNotificationService.onButtonNotificationClick(
// context = context,
// id = R.id.icRight,
// text = text
// )
// )
// setOnClickPendingIntent(
// R.id.icLight,
// CustomNotificationService.onButtonNotificationClick(
// context = context,
// id = R.id.icLight
// )
// )
// setOnClickPendingIntent(
// R.id.mOff,
// CustomNotificationService.onButtonNotificationClick(context = context, id = R.id.mOff)
// )
}
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.widget.RemoteViews
import com.bassbooster.equalizer.R
/**
* Implementation of App Widget functionality.
*/
class EqualizerWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
override fun onEnabled(context: Context) {
// Enter relevant functionality for when the first widget is created
}
override fun onDisabled(context: Context) {
// Enter relevant functionality for when the last widget is disabled
}
}
internal fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
val widgetText = context.getString(R.string.appwidget_text)
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.equalizer_widget)
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
class MyAppWidgetProvider : AppWidgetProvider() {
override fun onUpdate(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetIds: IntArray?
) {
// Thực hiện cập nhật giao diện của App Widget tại đây
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.adapter
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.bassbooster.equalizer.R
import com.bassbooster.soundeffects.equalizer.data.model.AppMedia
class ChooseAppAdapter(
private val apps: ArrayList<AppMedia>, val onItemClicked:(String) -> Unit
) : RecyclerView.Adapter<ChooseAppAdapter.DataViewHolder>() {
class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(app: AppMedia) {
itemView.findViewById<ImageView>(R.id.imageViewAvatar).setImageBitmap(app.avatar)
itemView.findViewById<TextView>(R.id.textViewName).text = app.name
itemView.findViewById<ImageView>(R.id.ivCheck).isVisible = app.check
if(app.check){
itemView.setBackgroundResource(R.drawable.custom_image_nation_red)
}else{
itemView.setBackgroundResource(R.drawable.dra_custom_layout_play)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
DataViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_app, parent,
false
)
)
override fun getItemCount(): Int = apps.size
@SuppressLint("NotifyDataSetChanged")
override fun onBindViewHolder(holder: DataViewHolder, position: Int) {
holder.bind(apps[position])
holder.itemView.setOnClickListener{
resetCheck()
apps[position].check = true
notifyDataSetChanged()
onItemClicked(apps[position].packageName)
}
}
private fun resetCheck(){
for (item in this.apps){
item.check = false
}
}
fun addData(list: List<AppMedia>) {
apps.addAll(list)
}
}
package com.bassbooster.soundeffects.equalizer.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bassbooster.equalizer.R
import com.bassbooster.soundeffects.equalizer.data.model.User
class MainAdapter(
private val users: ArrayList<User>
) : RecyclerView.Adapter<MainAdapter.DataViewHolder>() {
class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(user: User) {
itemView.findViewById<AppCompatTextView>(R.id.textViewUserName).text = user.name
itemView.findViewById<AppCompatTextView>(R.id.textViewUserEmail).text = user.email
val imageView : ImageView = itemView.findViewById(R.id.imageViewAvatar)
Glide.with(imageView.context)
.load(user.avatar)
.into(imageView)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
DataViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_layout, parent,
false
)
)
override fun getItemCount(): Int = users.size
override fun onBindViewHolder(holder: DataViewHolder, position: Int) =
holder.bind(users[position])
fun addData(list: List<User>) {
users.addAll(list)
}
}
package com.bassbooster.soundeffects.equalizer.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.viewpager.widget.PagerAdapter
import com.bassbooster.equalizer.R
import com.bassbooster.soundeffects.equalizer.data.model.Tutorial
class TutorialSplashAdapter(private val itemList: ArrayList<Tutorial>) : PagerAdapter() {
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view = LayoutInflater.from(container.context).inflate(
R.layout.item_viewpager_splash,
container,
false
)
view.findViewById<ImageView>(R.id.imgSplash).setImageResource(itemList[position].imgTutorial)
view.findViewById<TextView>(R.id.tvTitleSplash).text = itemList[position].tvTitle
container.addView(view)
return view
}
override fun getCount(): Int {
return itemList.size
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object`
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View?)
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.adapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
class ViewPagerAdapter(
fa: FragmentActivity, private val fragments: ArrayList<Fragment>
) : FragmentStateAdapter(fa) {
override fun getItemCount(): Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
fun getFragment(position: Int): Fragment? {
if (position < 0 || position >= fragments.size) {
return null
}
return fragments[position]
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.cardview.widget.CardView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.RecyclerView
import com.bassbooster.equalizer.R
import com.bassbooster.soundeffects.equalizer.data.model.VisualizerModel
import com.bassbooster.soundeffects.equalizer.view.fragment.PlayFragment
class VisualizerAdapter(val context: Context, val listImage: ArrayList<VisualizerModel>, val mListener: OnItemClickListener) : RecyclerView.Adapter<VisualizerAdapter.VisualizerViewHolder>() {
interface OnItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VisualizerViewHolder {
val inflater = LayoutInflater.from(parent.getContext())
val view = inflater.inflate(R.layout.adapter_visualizer, parent, false)
return VisualizerViewHolder(view)
}
override fun onBindViewHolder(holder: VisualizerViewHolder, position: Int) {
if (PlayFragment.positionType == position){
holder.isSelected.visibility = View.VISIBLE
}else{
holder.isSelected.visibility = View.GONE
}
holder.mImgVisual.setImageDrawable(listImage[position].image)
holder.mRlView.setOnClickListener {
PlayFragment.positionType = position
mListener.onItemClick(position)
}
}
override fun getItemCount(): Int {
return listImage.size
}
class VisualizerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var mRlView : CardView = view.findViewById(R.id.mRlView)
var isSelected : ConstraintLayout = view.findViewById(R.id.isSelectView)
var mImgVisual : ImageView = view.findViewById(R.id.mImgVisual)
}
}
package com.bassbooster.soundeffects.equalizer.base
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.bassbooster.soundeffects.equalizer.data.api.ApiHelper
import com.bassbooster.soundeffects.equalizer.data.repository.MainRepository
import com.bassbooster.soundeffects.equalizer.viewmodel.MainViewModel
class ViewModelFactory(private val apiHelper: ApiHelper) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(MainRepository(apiHelper)) as T
}
throw IllegalArgumentException("Unknown class name")
}
}
package com.bassbooster.soundeffects.equalizer.data.api
class ApiHelper(private val apiService: ApiService) {
fun getUsers() = apiService.getUsers()
}
package com.bassbooster.soundeffects.equalizer.data.api
import com.bassbooster.soundeffects.equalizer.data.model.User
import rx.Single
interface ApiService {
fun getUsers(): Single<MutableList<User>>
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.api
import com.bassbooster.soundeffects.equalizer.data.model.User
import com.rxandroidnetworking.RxAndroidNetworking
import rx.Single
class ApiServiceImpl : ApiService {
override fun getUsers(): Single<MutableList<User>> {
return RxAndroidNetworking.get("https://5e510330f2c0d300147c034c.mockapi.io/users").build()
.getObjectListSingle(User::class.java)
}
}
package com.bassbooster.soundeffects.equalizer.data.model
import android.graphics.Bitmap
import com.google.gson.annotations.SerializedName
class AppMedia(
@SerializedName("name")
val name: String = "",
@SerializedName("avatar")
val avatar: Bitmap,
val packageName: String,
var check: Boolean = false,
var startActivity: String = ""
)
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.model
class ColorEdgeModel(var image:Int, var color: String?) {
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.model
import android.graphics.drawable.Drawable
class EffectsModel(var name:String, var image: Drawable?)
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.model
import com.google.gson.annotations.SerializedName
class MediaInfo(
@SerializedName("title")
val title: String = "",
@SerializedName("description")
val description: String = ""
)
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.model
data class Nation(
val colorBorder: Int = 0,
val imgAvatar: Int = 0,
val name: String = "",
val imgVector: Int = 0,
)
package com.bassbooster.soundeffects.equalizer.data.model
data class Permissions(
val imgAvatar: Int = 0,
val tvTitle: String = "",
val tvBody: String = "",
)
package com.bassbooster.soundeffects.equalizer.data.model
data class Tutorial(
val imgTutorial: Int = 0,
val tvTitle: String = "",
)
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.model
import com.google.gson.annotations.SerializedName
data class User(
@SerializedName("id")
val id: Int = 0,
@SerializedName("name")
val name: String = "",
@SerializedName("email")
val email: String = "",
@SerializedName("avatar")
val avatar: String = ""
)
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.model
import android.graphics.drawable.Drawable
class VisualizerModel(var type:String, var image: Drawable?)
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.data.repository
import com.bassbooster.soundeffects.equalizer.data.api.ApiHelper
import com.bassbooster.soundeffects.equalizer.data.model.User
class MainRepository(private val apiHelper: ApiHelper) {
fun getUsers(): rx.Single<MutableList<User>> {
return apiHelper.getUsers()
}
}
package com.bassbooster.soundeffects.equalizer.database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.bassbooster.soundeffects.equalizer.database.dao.EffectsDao
@Database(entities = [EffectsData::class], version = 1, exportSchema = false)
abstract class AppDatabase() : RoomDatabase() {
abstract fun mEffectsDAO(): EffectsDao
companion object {
// Singleton prevents multiple instances of database opening at the
// same time.
@Volatile
private var INSTANCE: AppDatabase? = null
@Synchronized
fun getDatabase(context: Context): AppDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"contact_database"
) // Wipes and rebuilds instead of migrating if no Migration object.
// Migration is not part of this codelab.
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
return instance
}
}
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.database
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "effects")
class EffectsData {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
@ColumnInfo(name = "name")
var name: String = ""
@ColumnInfo(name = "seekbar0")
var seekbar0: Int = 0
@ColumnInfo(name = "seekbar1")
var seekbar1: Int = 0
@ColumnInfo(name = "seekbar2")
var seekbar2: Int = 0
@ColumnInfo(name = "seekbar3")
var seekbar3: Int = 0
@ColumnInfo(name = "seekbar4")
var seekbar4: Int = 0
@ColumnInfo(name = "bass_strength")
var bassStrength: Short = 0
@ColumnInfo(name = "reverb_preset")
var reverbPreset: Short = 0
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.database
import androidx.lifecycle.LiveData
import com.bassbooster.soundeffects.equalizer.database.EffectsData
import com.bassbooster.soundeffects.equalizer.database.dao.EffectsDao
class EffectsRepository(private val effectsDAO: EffectsDao) {
fun getAllData(): LiveData<List<EffectsData>> {
return effectsDAO.getAll()
}
suspend fun insert(myEntity: EffectsData) {
effectsDAO.insert(myEntity)
}
suspend fun delete(myEntity: EffectsData) {
effectsDAO.delete(myEntity)
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.database.dao
import androidx.lifecycle.LiveData
import androidx.room.*
import com.bassbooster.soundeffects.equalizer.database.EffectsData
@Dao
interface EffectsDao {
@Insert
suspend fun insert(myEntity: EffectsData)
@Query("SELECT * FROM effects")
fun getAll(): LiveData<List<EffectsData>>
@Delete
suspend fun delete(myEntity: EffectsData)
}
package com.bassbooster.soundeffects.equalizer.event
data class MessageEvent(val message: String)
data class PlayAdsEvent(val status: Boolean = false)
data class ServiceHideNavigationBarEvent(val status: Boolean)
/*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bassbooster.soundeffects.equalizer.tasks
import android.os.AsyncTask
import com.bassbooster.soundeffects.equalizer.utils.MediaAppDetails
/**
* Base class for an async task that fetches a list of media apps.
*/
abstract class FindMediaAppsTask constructor(
private val callback: AppListUpdatedCallback, private val sortAlphabetical: Boolean
) : AsyncTask<Void, Void, List<MediaAppDetails>>() {
/**
* Callback used by [FindMediaAppsTask].
*/
interface AppListUpdatedCallback {
fun onAppListUpdated(mediaAppEntries: List<MediaAppDetails>)
}
protected abstract val mediaApps: List<MediaAppDetails>
override fun doInBackground(vararg params: Void): List<MediaAppDetails> {
val mediaApps = ArrayList(mediaApps)
if(sortAlphabetical) {
// Sort the list by localized app name for convenience.
mediaApps.sortWith(Comparator { left, right ->
left.appName.compareTo(right.appName, ignoreCase = true)
})
}
return mediaApps
}
override fun onPostExecute(mediaAppEntries: List<MediaAppDetails>) {
callback.onAppListUpdated(mediaAppEntries)
}
}
\ No newline at end of file
/*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bassbooster.soundeffects.equalizer.tasks
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Resources
import androidx.media.MediaBrowserServiceCompat
import com.bassbooster.soundeffects.equalizer.tasks.FindMediaAppsTask
import com.bassbooster.soundeffects.equalizer.utils.MediaAppDetails
import java.util.ArrayList
/**
* Implementation of [FindMediaAppsTask] that uses available implementations of
* MediaBrowser to populate the list of apps.
*/
class FindMediaBrowserAppsTask constructor(
context: Context, callback: AppListUpdatedCallback
) : FindMediaAppsTask(callback, sortAlphabetical = true) {
private val packageManager: PackageManager = context.packageManager
private val resources: Resources = context.resources
/**
* Finds installed packages that have registered a
* [android.service.media.MediaBrowserService] or
* [android.support.v4.media.MediaBrowserServiceCompat] service by
* looking for packages that have services that respond to the
* "android.media.browse.MediaBrowserService" action.
*/
override val mediaApps: List<MediaAppDetails>
get() {
val mediaApps = ArrayList<MediaAppDetails>()
val mediaBrowserIntent = Intent(MediaBrowserServiceCompat.SERVICE_INTERFACE)
// Build an Intent that only has the MediaBrowserService action and query
// the PackageManager for apps that have services registered that can
// receive it.
val services = packageManager.queryIntentServices(
mediaBrowserIntent,
PackageManager.GET_RESOLVED_FILTER
)
if (services != null && !services.isEmpty()) {
for (info in services) {
mediaApps.add(
MediaAppDetails(
info.serviceInfo,
packageManager,
resources
)
)
}
}
return mediaApps
}
}
\ No newline at end of file
/*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bassbooster.soundeffects.equalizer.tasks
import android.annotation.TargetApi
import android.content.ComponentName
import android.content.pm.PackageManager
import android.content.res.Resources
import android.media.session.MediaSessionManager
import android.os.Build
import com.bassbooster.soundeffects.equalizer.utils.MediaAppDetails
/**
* Implementation of [FindMediaAppsTask] that uses active media sessions to populate the
* list of media apps.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
class FindMediaSessionAppsTask constructor(
private val mediaSessionManager: MediaSessionManager,
private val listenerComponent: ComponentName,
private val packageManager: PackageManager,
private val resources: Resources,
callback: AppListUpdatedCallback
) : FindMediaAppsTask(callback, sortAlphabetical = false) {
override val mediaApps: List<MediaAppDetails>
get() = MediaAppControllerUtils.getMediaAppsFromControllers(
mediaSessionManager.getActiveSessions(listenerComponent),
packageManager,
resources
)
}
\ No newline at end of file
/*
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bassbooster.soundeffects.equalizer.tasks
import android.annotation.TargetApi
import android.content.ContentValues
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.res.Resources
import android.media.session.MediaController
import android.os.Build
import com.bassbooster.soundeffects.equalizer.utils.MediaAppDetails
import java.util.ArrayList
object MediaAppControllerUtils {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@JvmStatic
fun getMediaAppsFromControllers(
controllers: Collection<MediaController>,
packageManager: PackageManager,
resources: Resources
): List<MediaAppDetails> {
val mediaApps = ArrayList<MediaAppDetails>()
for (controller in controllers) {
val packageName = controller.packageName
mediaApps.add(
MediaAppDetails(
packageName,
controller.sessionToken,
resources
)
)
}
return mediaApps
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* Created by Harjot on 23-May-16.
*/
public class AnalogController extends View {
float midx, midy;
Paint textPaint, circlePaint, circlePaint2, linePaint;
String angle;
float currdeg, deg = 3, downdeg;
int progressColor, lineColor;
onProgressChangedListener mListener;
String label;
public interface onProgressChangedListener {
void onProgressChanged(int progress);
}
public void setOnProgressChangedListener(onProgressChangedListener listener) {
mListener = listener;
}
public AnalogController(Context context) {
super(context);
init();
}
public AnalogController(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AnalogController(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
void init() {
textPaint = new Paint();
textPaint.setColor(Color.WHITE);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextSize(33);
textPaint.setFakeBoldText(true);
textPaint.setTextAlign(Paint.Align.CENTER);
circlePaint = new Paint();
circlePaint.setColor(Color.parseColor("#222222"));
circlePaint.setStyle(Paint.Style.FILL);
circlePaint2 = new Paint();
circlePaint2.setColor(Color.parseColor("#E83565"));
circlePaint2.setStyle(Paint.Style.FILL);
linePaint = new Paint();
linePaint.setColor(Color.parseColor("#08E0FF"));
linePaint.setStrokeWidth(18);
angle = "0.0";
label = "Label";
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
midx = getWidth() / 2;
midy = getHeight() / 2;
int ang = 0;
float x = 0, y = 0;
int radius = (int) (Math.min(midx, midy) * ((float) 14.5 / 16));
float deg2 = Math.max(3, deg);
float deg3 = Math.min(deg, 21);
for (int i = (int) (deg2); i < 22; i++) {
float tmp = (float) i / 24;
x = midx + (float) (radius * Math.sin(2 * Math.PI * (1.0 - tmp)));
y = midy + (float) (radius * Math.cos(2 * Math.PI * (1.0 - tmp)));
circlePaint.setColor(Color.parseColor("#626262"));
canvas.drawCircle(x, y, ((float) radius / 15), circlePaint);
}
for (int i = 3; i <= deg3; i++) {
float tmp = (float) i / 24;
x = midx + (float) (radius * Math.sin(2 * Math.PI * (1.0 - tmp)));
y = midy + (float) (radius * Math.cos(2 * Math.PI * (1.0 - tmp)));
circlePaint2.setColor(Color.parseColor("#E83565"));
canvas.drawCircle(x, y, ((float) radius / 15), circlePaint2);
}
float tmp2 = deg / 24;
float x1 = midx + (float) (radius * ((float) 2 / 5) * Math.sin(2 * Math.PI * (1.0 - tmp2)));
float y1 = midy + (float) (radius * ((float) 2 / 5) * Math.cos(2 * Math.PI * (1.0 - tmp2)));
float x2 = midx + (float) (radius * ((float) 3 / 5) * Math.sin(2 * Math.PI * (1.0 - tmp2)));
float y2 = midy + (float) (radius * ((float) 3 / 5) * Math.cos(2 * Math.PI * (1.0 - tmp2)));
canvas.drawCircle(midx, midy, radius * ((float) 11.5 / 15), circlePaint);
circlePaint.setColor(Color.parseColor("#08E0FF"));
// paint.setShader(new LinearGradient(0, 0, 0, getHeight(), Color.BLACK, Color.WHITE, Shader.TileMode.MIRROR));
canvas.drawCircle(midx, midy, radius * ((float) 11.5 / 15), circlePaint);
circlePaint.setColor(Color.parseColor("#434343"));
canvas.drawCircle(midx, midy, radius * ((float) 11 / 15), circlePaint);
canvas.drawText(label, midx, midy + (float) (radius * 1.1), textPaint);
canvas.drawLine(x1, y1, x2, y2, linePaint);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent e) {
mListener.onProgressChanged((int) (deg - 2));
if (e.getAction() == MotionEvent.ACTION_DOWN) {
float dx = e.getX() - midx;
float dy = e.getY() - midy;
downdeg = (float) ((Math.atan2(dy, dx) * 180) / Math.PI);
downdeg -= 90;
if (downdeg < 0) {
downdeg += 360;
}
downdeg = (float) Math.floor(downdeg / 15);
return true;
}
if (e.getAction() == MotionEvent.ACTION_MOVE) {
float dx = e.getX() - midx;
float dy = e.getY() - midy;
currdeg = (float) ((Math.atan2(dy, dx) * 180) / Math.PI);
currdeg -= 90;
if (currdeg < 0) {
currdeg += 360;
}
currdeg = (float) Math.floor(currdeg / 15);
if (currdeg == 0 && downdeg == 23) {
deg++;
if (deg > 21) {
deg = 21;
}
downdeg = currdeg;
} else if (currdeg == 23 && downdeg == 0) {
deg--;
if (deg < 3) {
deg = 3;
}
downdeg = currdeg;
} else {
deg += (currdeg - downdeg);
if (deg > 21) {
deg = 21;
}
if (deg < 3) {
deg = 3;
}
downdeg = currdeg;
}
angle = String.valueOf(deg);
invalidate();
return true;
}
return e.getAction() == MotionEvent.ACTION_UP || super.onTouchEvent(e);
}
public int getProgress() {
return (int) (deg - 2);
}
public void setProgress(int param) {
deg = param + 2;
}
public String getLabel() {
return label;
}
public void setLabel(String txt) {
label = txt;
}
public int getLineColor() {
return lineColor;
}
public void setLineColor(int lineColor) {
this.lineColor = lineColor;
}
public int getProgressColor() {
return progressColor;
}
public void setProgressColor(int progressColor) {
this.progressColor = progressColor;
}
}
package com.bassbooster.soundeffects.equalizer.utils;
import android.graphics.Bitmap;
public class AppInfo {
private String packageName;
private String appName;
private Bitmap icon;
private String startActivityName;
AppInfo(String appName, String startActivityName, Bitmap icon){
this.appName = appName;
this.icon = icon;
this.startActivityName = startActivityName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public Bitmap getIcon() {
return icon;
}
public void setIcon(Bitmap icon) {
this.icon = icon;
}
public String getStartActivityName() {
return startActivityName;
}
public void setStartActivityName(String startActivityName) {
this.startActivityName = startActivityName;
}
}
package com.bassbooster.soundeffects.equalizer.utils;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.text.TextPaint;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.bassbooster.equalizer.R;
public class AppUtils {
public static boolean haveNetworkConnection(Context context) {
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
return haveConnectedWifi || haveConnectedMobile;
}
public static void setMargins(View view, int left, int top, int right, int bottom) {
if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
p.setMargins(left, top, right, bottom);
view.requestLayout();
}
}
public static void setGradientTextView(TextView textView) {
Context context = textView.getContext();
TextPaint paint = textView.getPaint();
float width = paint.measureText(textView.getText().toString());
Shader textShader = new LinearGradient(0, 0, width, textView.getTextSize(), new int[]{
// ContextCompat.getColor(context, R.color.clr_05F1FF),
// ContextCompat.getColor(context, R.color.clr_005BE0)
},
null, Shader.TileMode.CLAMP);
textView.getPaint().setShader(textShader);
}
public static void hideNavigationBar(AppCompatActivity activity) {
int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
if (activity != null){
View decorView = activity.getWindow().getDecorView();
Handler handler = new Handler(Looper.getMainLooper());
handler.removeCallbacksAndMessages(null);
handler.postDelayed(()->decorView.setSystemUiVisibility(flags),1000);
}
}
public static AppInfo getAppInfo(String packageName, Resources resources){
AppInfo app;
switch (packageName) {
case "com.gaana" :
app = new AppInfo("Gaana", "com.gaana.SplashScreenActivity",
BitmapFactory.decodeResource(resources,R.drawable.ic_gaana));
app.setPackageName(packageName);
return app;
case "com.spotify.music" :
app = new AppInfo("Spotify", "com.spotify.music.MainActivity",
BitmapFactory.decodeResource(resources,R.drawable.ic_spotify));
return app;
case "com.soundcloud.android" :
app = new AppInfo("Soundcloud", "com.soundcloud.android.launcher.LauncherActivity",
BitmapFactory.decodeResource(resources,R.drawable.ic_soundcloud));
return app;
case "com.google.android.apps.youtube.music" :
app = new AppInfo("Youtube Music", "com.google.android.apps.youtube.music.activities.MusicActivity",
BitmapFactory.decodeResource(resources,R.drawable.ic_ytbmusic));
return app;
default: return new AppInfo("","",null);
//"com.soundcloud.android.playback.players.MediaService"
}
}
}
package com.bassbooster.soundeffects.equalizer.utils
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import androidx.core.app.ActivityCompat
class AudioSessionIdHelper {
fun getMicrophoneAudioSessionId(context: Context): Int? {
val audioRecord: AudioRecord?
val bufferSize = AudioRecord.getMinBufferSize(
44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT
)
try {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.RECORD_AUDIO
) != PackageManager.PERMISSION_GRANTED
) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return 0
}
audioRecord = AudioRecord(
MediaRecorder.AudioSource.MIC,
44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize
)
} catch (e: Exception) {
e.printStackTrace()
return null
}
val audioSessionId = audioRecord.audioSessionId
audioRecord.release()
return audioSessionId
}
}
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bassbooster.soundeffects.equalizer.utils;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import com.bassbooster.equalizer.R;
/**
* Utility class for {@link Bitmap}s.
*/
public final class BitmapUtils {
private BitmapUtils() {
// Utility class.
}
/**
* Converts a {@link Drawable} to an appropriately sized {@link Bitmap}.
*
* @param resources Resources for the current {@link android.content.Context}.
* @param drawable The {@link Drawable} to convert to a Bitmap.
* @param downScale Will downscale the Bitmap to {@code R.dimen.app_icon_size} dp.
* @return A Bitmap, no larger than {@code R.dimen.app_icon_size} dp if desired.
*/
public static Bitmap convertDrawable(@NonNull final Resources resources,
@NonNull final Drawable drawable,
final boolean downScale) {
final Bitmap bitmap;
if (drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
}
if (!downScale) {
return bitmap;
}
final int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
if (bitmap.getHeight() > iconSize || bitmap.getWidth() > iconSize) {
// Which needs to be scaled to fit.
final int height = bitmap.getHeight();
final int width = bitmap.getWidth();
final int scaleHeight;
final int scaleWidth;
// Calculate the new size based on which dimension is larger.
if (height > width) {
scaleHeight = iconSize;
scaleWidth = (int) (width * ((float) iconSize) / height);
} else {
scaleWidth = iconSize;
scaleHeight = (int) (height * ((float) iconSize) / width);
}
return Bitmap.createScaledBitmap(bitmap, scaleWidth, scaleHeight, false);
} else {
return bitmap;
}
}
/**
* Creates a Material Design compliant {@link androidx.appcompat.widget.Toolbar} icon
* from a given full sized icon.
*
* @param resources Resources for the current {@link android.content.Context}.
* @param icon The bitmap to convert.
* @return A scaled Bitmap of the appropriate size and in-built padding.
*/
public static Bitmap createToolbarIcon(@NonNull Resources resources,
@NonNull final Bitmap icon) {
final int padding = resources.getDimensionPixelSize(R.dimen.margin_small);
final int iconSize = resources.getDimensionPixelSize(R.dimen.toolbar_icon_size);
final int sizeWithPadding = iconSize + (2 * padding);
// Create a Bitmap backed Canvas to be the toolbar icon.
final Bitmap toolbarIcon =
Bitmap.createBitmap(sizeWithPadding, sizeWithPadding, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(toolbarIcon);
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
// Resize the app icon to Material Design size.
final Bitmap scaledIcon = Bitmap.createScaledBitmap(icon, iconSize, iconSize, false);
canvas.drawBitmap(scaledIcon, padding, padding, null);
return toolbarIcon;
}
}
package com.bassbooster.soundeffects.equalizer.utils;
public interface Constants {
//Ads
String App_open_resume = "App_open_resume";
String Inter_splash = "Inter_splash";
String Native_language = "Native_language";
String Native_tutorial = "Native_tutorial";
String Native_home = "Native_home";
String Inter_home = "Inter_home";
String Inter_save = "Inter_save";
String Native_music = "Native_music";
String Banner = "Banner";
String Native_saving = "Native_saving";
String allow_reload_native_language = "allow_reload_native_language";
String allow_reload_native_tutorial = "allow_reload_native_tutorial";
String allow_reload_native_home = "allow_reload_native_home";
String allow_reload_native_music = "allow_reload_native_music";
String allow_reload_banner = "allow_reload_banner";
}
package com.bassbooster.soundeffects.equalizer.utils
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.view.View
import android.widget.RemoteViews
import androidx.annotation.IdRes
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.bassbooster.equalizer.R
class CustomNotificationService {
companion object {
const val EXTRA_BUTTON_CLICKED = "EXTRA_BUTTON_CLICKED"
const val EXTRA_BUTTON = "EXTRA_BUTTON"
const val EXTRA_BUTTON_TEXT = "EXTRA_BUTTON_TEXT"
const val EXTRA_BUTTON_NEXT = "EXTRA_BUTTON_NEXT"
const val EXTRA_BUTTON_LIGHT = "EXTRA_BUTTON_LIGHT"
const val EXTRA_BUTTON_OFF = "EXTRA_BUTTON_OFF"
var nameType = ""
var bass = 0
var stereo = 0
fun createNotificationChannel(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "My Channel"
val descriptionText = "My Channel Description"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel("channel_id", name, importance).apply {
description = descriptionText
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Tạo và đăng ký kênh thông báo nếu bạn đang chạy trên Android 8.0 (API level 26) trở lên
channel.setSound(null, null) // Tắt âm thanh
channel.enableVibration(false)
}
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
@SuppressLint("MissingPermission")
fun showBasicNotification(context: Context, text: String, statusOnOff : Boolean = false,isLightOn: Boolean = false) {
if (text.isNotEmpty()){
nameType = text
}
val notificationLayout = RemoteViews(context.packageName, R.layout.notification_custom)
notificationLayout.apply {
if (statusOnOff){
setViewVisibility(R.id.mOff,View.VISIBLE)
setViewVisibility(R.id.mOn,View.GONE)
}else{
setViewVisibility(R.id.mOff,View.GONE)
setViewVisibility(R.id.mOn,View.VISIBLE)
}
if(isLightOn){
setViewVisibility(R.id.icLightOff,View.GONE)
setViewVisibility(R.id.icLight,View.VISIBLE)
}else{
setViewVisibility(R.id.icLightOff,View.VISIBLE)
setViewVisibility(R.id.icLight,View.GONE)
}
setTextViewText(R.id.mTxtNameBass, "Bass:")
setTextViewText(R.id.mTxtNameStereo, "Stereo")
setTextViewText(R.id.textView, nameType)
setTextViewText(R.id.mTxtStereo, "100")
setOnClickPendingIntent(
R.id.icLeft,
onButtonNotificationClick(context = context, id = R.id.icLeft,text=text)
)
setOnClickPendingIntent(
R.id.icRight,
onButtonNotificationClick(context = context, id = R.id.icRight,text=text)
)
setOnClickPendingIntent(
R.id.icLightOff,
onButtonNotificationClick(context = context, id = R.id.icLightOff)
)
setOnClickPendingIntent(
R.id.icLight,
onButtonNotificationClick(context = context, id = R.id.icLight)
)
setOnClickPendingIntent(
R.id.mOff,
onButtonNotificationClick(context = context, id = R.id.mOff)
)
setOnClickPendingIntent(
R.id.mOn,
onButtonNotificationClick(context = context, id = R.id.mOn)
)
}
val builder = NotificationCompat.Builder(context, "channel_id")
.setSmallIcon(R.drawable.ic_logo)
.setContentTitle("Tiêu đề thông báo")
.setContentText("Nội dung thông báo")
.setOnlyAlertOnce(true)
.setAutoCancel(true)
.setOngoing(true)
.setCustomContentView(notificationLayout)
.setCustomBigContentView(notificationLayout)
.setPriority(NotificationCompat.PRIORITY_HIGH)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(
"channel_id",
"channel_name",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = "Channel Equalizer"
notificationManager.createNotificationChannel(channel)
}
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(0, builder.build())
}
private fun onButtonNotificationClick(context: Context, @IdRes id: Int,text: String? = null): PendingIntent? {
val intent: Intent = Intent(EXTRA_BUTTON_CLICKED)
intent.putExtra(EXTRA_BUTTON, id)
intent.putExtra(EXTRA_BUTTON_TEXT,text)
// Sử dụng FLAG_MUTABLE nếu bạn muốn thay đổi PendingIntent sau khi đã tạo nó.
// Sử dụng FLAG_IMMUTABLE nếu bạn không cần thay đổi PendingIntent sau khi đã tạo nó.
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_MUTABLE
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
return PendingIntent.getBroadcast(
context,
id,
intent,
flags
)
}
}
}
open class MyBroadcastReceiver : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.N)
override fun onReceive(context: Context?, intent: Intent?) {
}
}
package com.bassbooster.equalizer.utils
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.view.View
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
import com.bassbooster.equalizer.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
object DialogUtils {
fun showDialogConfirmPer(context: Context?, title:String?,description: String?,
listenerOK:(() -> Unit)? = null, listenerCancel:(() -> Unit)? = null): AlertDialog? {
if (context == null) return null
val dialog : AlertDialog =
AlertDialog.Builder(context)
.setView(R.layout.layout_dialog_permission)
.create().apply {
setCancelable(false)
setCanceledOnTouchOutside(false)
}
dialog.apply {
window?.setBackgroundDrawableResource(R.drawable.custom_dialog)
show()
findViewById<AppCompatTextView>(R.id.tvTitle)?.text = title
findViewById<AppCompatTextView>(R.id.tvDescription)?.text = description
findViewById<AppCompatButton>(R.id.btnOK)?.setOnClickListener {
listenerOK?.invoke()
this.dismiss()
}
findViewById<AppCompatButton>(R.id.btnCancel)?.setOnClickListener {
listenerCancel?.invoke()
this.dismiss()
}
}
return dialog
}
fun showDialog(context: Context?,description: String?,
listenerOK:(() -> Unit)? = null, listenerCancel:(() -> Unit)? = null): AlertDialog? {
if (context == null) return null
val dialog : AlertDialog =
AlertDialog.Builder(context)
.setView(R.layout.layout_dialog)
.create().apply {
setCancelable(false)
setCanceledOnTouchOutside(false)
}
dialog.apply {
window?.setBackgroundDrawableResource(R.drawable.custom_dialog)
show()
findViewById<AppCompatTextView>(R.id.tvTitle)?.text = context.resources.getString(R.string.title_opp)
findViewById<AppCompatTextView>(R.id.tvDescription)?.text = description
findViewById<AppCompatButton>(R.id.btnOK)?.setOnClickListener {
listenerOK?.invoke()
this.dismiss()
}
}
return dialog
}
@SuppressLint("SetTextI18n")
fun showDialogSaveSuccess(
context: Context?,
title: String?,
listenerOK: (() -> Unit)? = null,
activity: Activity?
): AlertDialog? {
var progressStatus = 0
val handler = Handler(Looper.getMainLooper())
val totalTime = 4000 // 4 giây (4000 milliseconds)
val interval = 40 // Cập nhật giá trị mỗi 40 milliseconds
val steps = totalTime / interval // Số bước cần để đạt được tổng thời gian
var homeAdsLoaded = false
if (context == null) return null
val dialog: AlertDialog =
AlertDialog.Builder(context)
.setView(R.layout.layout_dialog_save)
.create().apply {
setCancelable(false)
setCanceledOnTouchOutside(false)
}
dialog.apply {
window?.setBackgroundDrawableResource(R.drawable.custom_dialog)
show()
val progressBar = findViewById<ProgressBar>(R.id.Prog)
val countProg = findViewById<TextView>(R.id.countProg)
val btnOK = findViewById<AppCompatButton>(R.id.btnOK)
Thread {
for (i in 0 until steps) {
progressStatus =
(i * 100) / steps // Tính giá trị của progressStatus từ 0 đến 100
handler.post {
progressBar?.progress = progressStatus + 1
countProg?.text = "${progressStatus + 1}%"
}
try {
Thread.sleep(interval.toLong()) // Đợi `interval` milliseconds trước khi cập nhật giá trị tiếp theo
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
handler.post {
btnOK?.isEnabled = true
btnOK?.background = context.resources.getDrawable(R.drawable.button_border)
}
}.start()
findViewById<AppCompatTextView>(R.id.tvTitle)?.text = title
btnOK?.setOnClickListener {
listenerOK?.invoke()
this.dismiss()
}
}
return dialog
}
}
\ No newline at end of file
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bassbooster.soundeffects.equalizer.utils;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.media.session.MediaSessionCompat;
import android.util.Log;
import androidx.annotation.Nullable;
import java.util.List;
/**
* Stores details about a media app.
*/
public class MediaAppDetails implements Parcelable {
public String packageName;
public String appName;
public Bitmap icon;
@Nullable
public Bitmap banner;
public MediaSessionCompat.Token sessionToken;
public ComponentName componentName;
public boolean supportsAutomotive = false;
public boolean supportsAuto = false;
public MediaAppDetails(String packageName, String name, Bitmap appIcon,
@Nullable Bitmap appBanner, MediaSessionCompat.Token token) {
this.packageName = packageName;
appName = name;
sessionToken = token;
icon = appIcon;
// This TV app targets min sdk version 21, and a banner will only be present for the TV app
banner = appBanner;
componentName = null;
}
public MediaAppDetails(String packageName, String name, Bitmap appIcon,
@Nullable Bitmap appBanner, MediaSession.Token token) {
this(packageName, name, appIcon, appBanner, MediaSessionCompat.Token.fromToken(token));
}
public MediaAppDetails(String packageName,
@Nullable MediaSession.Token token, @Nullable Resources resources) {
this.packageName = packageName;
if (resources != null) {
this.appName = AppUtils.getAppInfo(packageName, resources).getAppName();
this.icon = AppUtils.getAppInfo(packageName, resources).getIcon();
}
if (token != null) {
// If we have a MediaSession Token, then we don't need to connect to the
// MediaBrowserService implementation, so componentName is null.
componentName = null;
sessionToken = MediaSessionCompat.Token.fromToken(token);
} else {
// If we don't have a MediaSession Token, then we need to connect to the
// MediaBrowserService implementation.
componentName = new ComponentName(packageName, AppUtils.getAppInfo(packageName, resources).getStartActivityName());
sessionToken = null;
}
}
public MediaAppDetails(PackageItemInfo info, PackageManager pm, Resources resources,
MediaSession.Token token) {
packageName = info.packageName;
appName = info.loadLabel(pm).toString();
Drawable appIcon = info.loadIcon(pm);
icon = BitmapUtils.convertDrawable(resources, appIcon, true);
// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
// Drawable appBanner = info.loadBanner(pm);
// if (appBanner != null) {
// banner = BitmapUtils.convertDrawable(resources, appBanner, false);
// }
// }
if (token != null) {
// If we have a MediaSession Token, then we don't need to connect to the
// MediaBrowserService implementation, so componentName is null.
// componentName = null;
// sessionToken = MediaSessionCompat.Token.fromToken(token);
} else {
// If we don't have a MediaSession Token, then we need to connect to the
// MediaBrowserService implementation.
// componentName = new ComponentName(info.packageName, info.name);
// sessionToken = null;
}
try {
FeatureInfo[] features = pm.getPackageInfo(
packageName, PackageManager.GET_CONFIGURATIONS).reqFeatures;
supportsAutomotive = false;
if (features != null) {
for (FeatureInfo f : features) {
if (f.name != null && f.name.equals("android.hardware.type.automotive")) {
supportsAutomotive = true;
break;
}
}
}
Bundle metaData = pm.getApplicationInfo(packageName,
PackageManager.GET_META_DATA).metaData;
if (metaData != null) {
if (metaData.containsKey("com.google.android.gms.car.application")) {
supportsAuto = true;
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.w("MediaAppDetails", "package name not found" + packageName);
}
}
public MediaAppDetails(PackageItemInfo info, PackageManager pm, Resources resources) {
// this(info, pm, resources, null);
}
/**
* Helper function to get the service info for the packagemanager for a given package.
*/
// public static ServiceInfo findServiceInfo(String packageName, PackageManager pm) {
// final Intent mediaBrowserIntent = new Intent(MediaBrowserServiceCompat.SERVICE_INTERFACE);
// final List<ResolveInfo> services =
// pm.queryIntentServices(mediaBrowserIntent,
// PackageManager.GET_RESOLVED_FILTER);
// for (ResolveInfo info : services) {
// if (info.serviceInfo.packageName.equals(packageName)) {
// return (info.serviceInfo);
// }
// }
// return null;
// }
public static List<ResolveInfo> findResolveInfo(
String packageName, PackageManager pm, String action) {
if (packageName != null) {
Intent prefsIntent = new Intent(action);
prefsIntent.setPackage(packageName);
return pm.queryIntentActivities(prefsIntent, 0);
}
return null;
}
private MediaAppDetails(final Parcel parcel) {
packageName = parcel.readString();
appName = parcel.readString();
icon = parcel.readParcelable(MediaAppDetails.class.getClassLoader());
// sessionToken = parcel.readParcelable(MediaAppDetails.class.getClassLoader());
// componentName = parcel.readParcelable(MediaAppDetails.class.getClassLoader());
supportsAuto = parcel.readInt() == 1;
supportsAutomotive = parcel.readInt() == 1;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(packageName);
dest.writeString(appName);
dest.writeParcelable(icon, flags);
// dest.writeParcelable(sessionToken, flags);
// dest.writeParcelable(componentName, flags);
dest.writeInt(supportsAuto ? 1 : 0);
dest.writeInt(supportsAutomotive ? 1 : 0);
}
public static final Creator<MediaAppDetails> CREATOR =
new Creator<MediaAppDetails>() {
public MediaAppDetails createFromParcel(Parcel source) {
return new MediaAppDetails(source);
}
public MediaAppDetails[] newArray(int size) {
return new MediaAppDetails[size];
}
};
}
package com.bassbooster.soundeffects.equalizer.utils;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build.VERSION_CODES;
import android.service.notification.NotificationListenerService;
import androidx.core.app.NotificationManagerCompat;
/**
* A notification listener service to allows us to grab active media sessions from their
* notifications.
* This class is only used on API 21+ because the Android media framework added getActiveSessions
* in API 21.
*/
@SuppressLint("ObsoleteSdkInt")
@TargetApi(VERSION_CODES.LOLLIPOP)
public class NotificationListener extends NotificationListenerService {
// Helper method to check if our notification listener is enabled. In order to get active media
// sessions, we need an enabled notification listener component.
public static boolean isEnabled(Context context) {
return NotificationManagerCompat
.getEnabledListenerPackages(context)
.contains(context.getPackageName());
}
}
package com.bassbooster.soundeffects.equalizer.utils
data class Resource<out T>(val status: Status, val data: T?, val message: String?) {
companion object {
fun <T> success(data: T?): Resource<T> {
return Resource(Status.SUCCESS, data, null)
}
fun <T> error(msg: String, data: T?): Resource<T> {
return Resource(Status.ERROR, data, msg)
}
fun <T> loading(data: T?): Resource<T> {
return Resource(Status.LOADING, data, null)
}
}
}
package com.bassbooster.soundeffects.equalizer.utils
import android.content.Context
import android.content.SharedPreferences
class SharedPreferencesUtil(private val context: Context) {
private val sharedPreferences: SharedPreferences =
context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
private val editor: SharedPreferences.Editor = sharedPreferences.edit()
fun saveString(key: String, value: String) {
editor.putString(key, value)
editor.apply()
}
fun getString(key: String, defaultValue: String = ""): String {
return sharedPreferences.getString(key, defaultValue) ?: defaultValue
}
fun saveInt(key: String, value: Int) {
editor.putInt(key, value)
editor.apply()
}
fun getInt(key: String, defaultValue: Int = 0): Int {
return sharedPreferences.getInt(key, defaultValue)
}
fun saveBoolean(key: String, value: Boolean) {
editor.putBoolean(key, value)
editor.apply()
}
fun getBoolean(key: String, defaultValue: Boolean = true): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
fun saveBooleanPlayControl(key: String, value: Boolean) {
editor.putBoolean(key, value)
editor.apply()
}
fun getBooleanPlayControl(key: String, defaultValue: Boolean = true): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
fun saveStatusWidgetEdge(key: String, value: Boolean) {
editor.putBoolean(key, value)
editor.apply()
}
fun getStatusWidgetEdge(key: String, defaultValue: Boolean = false): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
fun isFirstSplash(key: String, value: Boolean) {
editor.putBoolean(key, value)
editor.apply()
}
fun getIsFirstSplash(key: String, defaultValue: Boolean = false): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
fun saveStatusRestart(key: String, value: Boolean) {
editor.putBoolean(key, value)
editor.apply()
}
fun getStatusRestart(key: String, defaultValue: Boolean = false): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
fun saveIsOverLay(key: String, value: Boolean) {
editor.putBoolean(key, value)
editor.apply()
}
fun getIsOverLay(key: String, defaultValue: Boolean = false): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
fun saveIsStatusSelectMusic(key: String, value: Boolean) {
editor.putBoolean(key, value)
editor.apply()
}
fun getIsStatusSelectMusic(key: String, defaultValue: Boolean = false): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
fun removeValue(key: String) {
editor.remove(key)
editor.apply()
}
fun clearAll() {
editor.clear()
editor.apply()
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.utils
enum class Status {
SUCCESS,
ERROR,
LOADING
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.utils
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import com.bassbooster.soundeffects.equalizer.database.EffectsData
import com.bassbooster.soundeffects.equalizer.database.EffectsRepository
object Utils {
suspend fun insertDateEffects(effectsRepository: EffectsRepository){
val newEffects = EffectsData()
newEffects.seekbar0 = 987
newEffects.seekbar1 = 0
newEffects.seekbar2 = 0
newEffects.seekbar3 = 0
newEffects.seekbar4 = 0
newEffects.bassStrength = 0
newEffects.reverbPreset = 2
effectsRepository.insert(newEffects)
}
fun hideKeyboard(view: View, context: Context) {
val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
fun hideAdsResume(){
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.view
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.IBinder
import android.util.Log
import android.view.*
import android.view.WindowManager.LayoutParams
import android.widget.FrameLayout
import com.bassbooster.equalizer.R
import com.bassbooster.soundeffects.equalizer.data.model.ColorEdgeModel
import com.bassbooster.soundeffects.equalizer.event.ServiceHideNavigationBarEvent
import com.bassbooster.soundeffects.equalizer.view.activity.edgelighting.customview.ImageBorderView2
import org.greenrobot.eventbus.EventBus
class MainService : Service() {
private lateinit var windowManager: WindowManager
private var floatyView: View? = null
private val listShape: ArrayList<Int> = arrayListOf(
R.drawable.ic_ess,R.drawable.ic_fire,
R.drawable.icon_record,R.drawable.icon_stop,R.drawable.ic_play,
R.drawable.icon_record,R.drawable.icon_stop,R.drawable.ic_play)
val listColor: ArrayList<ColorEdgeModel> = arrayListOf(
ColorEdgeModel(R.drawable.ic_rectangle_red,"#EE2929"),
ColorEdgeModel(R.drawable.ic_rectangle_yel,"#EAB93D"),
ColorEdgeModel(R.drawable.ic_rectangle_blue,"#19E73A"),
ColorEdgeModel(R.drawable.ic_rectangle_blues,"#1188DD"),
ColorEdgeModel(R.drawable.ic_rectangle_t,"#CE1EEB")
)
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
EventBus.getDefault().post(ServiceHideNavigationBarEvent(true))
windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
val durationTop = intent?.getFloatExtra("changeDurationTop",0f) ?: 0f
val durationBottom = intent?.getFloatExtra("changeDurationBottom",0f) ?: 0f
val with = intent?.getIntExtra("changeWith",0) ?: 0
val duration = intent?.getIntExtra("changeDuration",0) ?: 0
val shape = intent?.getIntExtra("createBitmapByShape",0) ?:0
val color = intent?.getStringExtra("changeColor")
addOverlayView()
floatyView?.findViewById<ImageBorderView2>(R.id.mImageBorder)?.apply {
if (durationTop != 0f) {
changeDurationTop(durationTop,durationTop)
}
if (durationBottom != 0f) {
changeDurationBottom(durationBottom,durationBottom)
}
if (with != 0) {
changeScaleFactor(with)
}
if (duration != 0) {
changeDuration(duration)
}
if (shape != 0) {
createBitmapByShape(shape)
}
if (color != null) {
changeColor(Color.parseColor(color))
}
}
return super.onStartCommand(intent, flags, startId)
}
// override fun onCreate() {
// super.onCreate()
//
// }
private fun addOverlayView() {
val params: LayoutParams
val layoutParamsType: Int = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
@Suppress("DEPRECATION")
LayoutParams.TYPE_PHONE
}
// 0
// FLAG_NOT_TOUCHABLE
params = LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT,
layoutParamsType,
LayoutParams.TYPE_WALLPAPER,
PixelFormat.TRANSLUCENT)
params.gravity = Gravity.CENTER or Gravity.START
params.x = 0
params.y = 0
val interceptorLayout = object : FrameLayout(this) {
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
// Only fire on the ACTION_DOWN event, or you'll get two events (one for _DOWN, one for _UP)
if (event.action == KeyEvent.ACTION_DOWN) {
// Check if the HOME button is pressed
if (event.keyCode == KeyEvent.KEYCODE_BACK) {
Log.v(TAG, "BACK Button Pressed")
// val intent = packageManager.getLaunchIntentForPackage(applicationContext.packageName)
// intent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
// startActivity(intent)
// EventBus.getDefault()
// .post(ServiceEvent(true))
// As we've taken action, we'll return true to prevent other apps from consuming the event as well
return true
}
}
if (event.action == KeyEvent.KEYCODE_BACK){
Log.d("qqq", "dispatchKeyEvent: "+"dfdsf")
}
// Otherwise don't intercept the event
return super.dispatchKeyEvent(event)
}
}
val inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
floatyView = inflater.inflate(R.layout.floating_view, interceptorLayout)
floatyView?.let {
windowManager.addView(floatyView, params)
} ?: run {
Log.e(TAG, "Layout Inflater Service is null; can't inflate and display R.layout.floating_view")
}
}
override fun onDestroy() {
super.onDestroy()
floatyView?.let {
windowManager.removeView(it)
floatyView = null
}
}
companion object {
private val TAG = MainService::class.java.simpleName
}
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.view.activity.edgelighting.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.bassbooster.equalizer.R
import com.bassbooster.equalizer.databinding.ItemColorBorderBinding
import com.bassbooster.soundeffects.equalizer.data.model.ColorEdgeModel
import com.bassbooster.soundeffects.equalizer.utils.SharedPreferencesUtil
class ColorBorderAdapter(val context: Context, val list: ArrayList<ColorEdgeModel>, val mListener: OnItemClickListener) : RecyclerView.Adapter<ColorBorderAdapter.ViewHolder>() {
var isSelect = -1
private var sharedPreferencesUtil = SharedPreferencesUtil(context)
interface OnItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemColorBorderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (isSelect == position){
holder.binding.mLlColor.background = ContextCompat.getDrawable(context, R.drawable.custome_border_rectangle_select)
}else{
holder.binding.mLlColor.background = ContextCompat.getDrawable(context,R.drawable.custome_border_rectangle)
}
if (sharedPreferencesUtil.getInt("positionList") == position) {
holder.binding.mLlColor.background = ContextCompat.getDrawable(context,R.drawable.custome_border_rectangle_select)
}
holder.binding.mImgColor.background = ContextCompat.getDrawable(context,list[position].image)
holder.binding.mLlColor.setOnClickListener {
isSelect = position
mListener.onItemClick(position)
}
}
override fun getItemCount(): Int {
return list.size
}
inner class ViewHolder(val binding: ItemColorBorderBinding) : RecyclerView.ViewHolder(binding.root)
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.view.activity.edgelighting.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bassbooster.equalizer.databinding.AdapterEffectsBinding
import com.bassbooster.soundeffects.equalizer.data.model.EffectsModel
class EdgeLightingAdapter(val context: Context, val list: ArrayList<EffectsModel>, val mListener: OnItemClickListener) : RecyclerView.Adapter<EdgeLightingAdapter.ViewHolder>() {
var isSelect = 0
interface OnItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = AdapterEffectsBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// if (isSelect == position){
// holder.mRlView.background = ContextCompat.getDrawable(context,R.drawable.dra_custom_layout_play_select)
// }else{
// holder.mRlView.background = ContextCompat.getDrawable(context,R.drawable.dra_custom_layout_play)
// }
holder.binding.mTxtName.text = list[position].name
holder.binding.mImgType.setImageDrawable(list[position].image)
holder.binding.mLlView.setOnClickListener {
mListener.onItemClick(position)
}
}
override fun getItemCount(): Int {
return list.size
}
inner class ViewHolder(val binding: AdapterEffectsBinding) : RecyclerView.ViewHolder(binding.root)
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.view.activity.edgelighting.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.bassbooster.equalizer.R
import com.bassbooster.equalizer.databinding.AdapterImageBoderBinding
class ImageBoderAdapter(val context: Context, val list: ArrayList<Int>, val mListener: OnItemClickListener) : RecyclerView.Adapter<ImageBoderAdapter.ViewHolder>() {
var isSelect = 0
interface OnItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = AdapterImageBoderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (isSelect == position){
holder.binding.mllImage.background = ContextCompat.getDrawable(context, R.drawable.custom_boder_select_grad)
}else{
holder.binding.mllImage.background = ContextCompat.getDrawable(context,R.drawable.boder_radius_style)
}
holder.binding.mImgStyle.background = ContextCompat.getDrawable(context,list[position])
holder.binding.mllImage.setOnClickListener {
isSelect = position
mListener.onItemClick(position)
}
}
override fun getItemCount(): Int {
return list.size
}
inner class ViewHolder(val binding: AdapterImageBoderBinding) : RecyclerView.ViewHolder(binding.root)
}
\ No newline at end of file
package com.bassbooster.soundeffects.equalizer.view.activity.edgelighting.customview
import android.animation.ArgbEvaluator
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.bassbooster.equalizer.R
class ColoredBorderView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
private val borderPaint = Paint()
private val borderRect = RectF()
private val borderWidth = 10f // Độ rộng của đường viền
private val padding = 30f // Padding bên trong view
private val startColor = ContextCompat.getColor(context, R.color.end)
private val endColor = ContextCompat.getColor(context, R.color.start)
private val center = ContextCompat.getColor(context, R.color.center)
private var currentColor = startColor // Màu sắc hiện tại của đường viền
private val colorAnimator: ValueAnimator
private val cornerRadius = 0f
init {
borderPaint.style = Paint.Style.STROKE
borderPaint.strokeWidth = borderWidth
borderPaint.pathEffect = DashPathEffect(floatArrayOf(30f, 30f), 0f) // Định dạng line nét đứt
// Tính toán khu vực bao quanh đường viền với padding
borderRect.set(
padding,
padding,
width.toFloat() - padding,
height.toFloat() - padding
)
// Khởi tạo và chạy animator để thay đổi màu sắc
colorAnimator = ValueAnimator.ofObject(
ArgbEvaluator(),
startColor,
center,
endColor
)
colorAnimator.addUpdateListener { animator ->
currentColor = animator.animatedValue as Int
invalidate()
}
colorAnimator.interpolator = FastOutSlowInInterpolator()
colorAnimator.duration = 1200 // Thời gian hoàn thành animation (ms)
colorAnimator.repeatCount = ValueAnimator.INFINITE
colorAnimator.start()
}
fun setColorAnimatorDuration(duration: Long) {
colorAnimator.duration = duration
invalidate()
}
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// Vẽ đường viền với màu sắc hiện tại
val width = width.toFloat()
val height = height.toFloat()
borderPaint.color = currentColor
// canvas.drawPath(path, borderPaint)
// Vẽ một đường viền dọc theo biên của view
// Tính toán khu vực bao quanh đường viền với padding
val borderRect = RectF(
padding,
padding,
width - padding,
height - padding
)
// Vẽ một đường viền dọc theo biên của view
// Log.d("qqq", "onDraw: "+cornerRadius)
val path = Path()
canvas.drawRoundRect(
borderRect,
cornerRadius.toFloat(), // Bán kính đường viền
cornerRadius.toFloat(), // Bán kính đường viền
borderPaint
)
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment