diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 2f633b6..0ed1383 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -8,19 +8,26 @@ on: jobs: build: - runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: set up JDK 11 + + - name: Set up JDK 17 uses: actions/setup-java@v4 with: - java-version: '11' + java-version: '17' distribution: 'temurin' cache: gradle - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew build + + - name: Build APK + run: ./gradlew assembleDebug + + - name: Upload APK as artifact + uses: actions/upload-artifact@v3 + with: + name: app-debug + path: app/build/outputs/apk/debug/app-debug.apk \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7c6e814..b6bc011 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,83 @@ +# Built application files +*.apk +*.aar +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +/bin/ +/gen/ +/out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# Gradle files +.gradle/ +/build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ *.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later .externalNativeBuild -.cxx +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml -.idea/discord.xml \ No newline at end of file +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 681f41a..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
-
-
\ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 61a9130..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml deleted file mode 100644 index d67c625..0000000 --- a/.idea/deploymentTargetSelector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/deviceManager.xml b/.idea/deviceManager.xml deleted file mode 100644 index a6c0bfd..0000000 --- a/.idea/deviceManager.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 7b3006b..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index a5f05cd..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml deleted file mode 100644 index f8051a6..0000000 --- a/.idea/migrations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 1776bbc..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 72f00ed..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 3a5267f..c7106fd 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # zz-android-old -> use API 33 to build and api 28 to test +> use API 33 to build and api 28 to test, estimated time to finish: 6 weeks - 7 months, hehe diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 9c9be5a..0000000 --- a/app/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'com.google.gms.google-services' - -android { - compileSdkVersion 33 - buildToolsVersion "30.0.2" - - defaultConfig { - applicationId "tw.music.streamer" - minSdkVersion 27 - targetSdkVersion 33 - renderscriptTargetApi 30 - renderscriptSupportModeEnabled true - versionCode 27301 - versionName "2.7.3.01" - } - buildTypes { - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - multiDexEnabled true - } - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.2.1' - implementation 'com.google.firebase:firebase-analytics:17.5.0' - implementation 'com.google.firebase:firebase-auth:19.3.2' - implementation 'com.google.firebase:firebase-database:19.4.0' - implementation 'com.google.firebase:firebase-storage:19.2.0' - implementation 'com.github.bumptech.glide:glide:4.11.0' - implementation 'com.google.code.gson:gson:2.8.6' - implementation 'com.squareup.okhttp3:okhttp:4.8.1' -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..18cb271 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,57 @@ +plugins { + id("com.android.application") + id("com.google.gms.google-services") +} + +android { + namespace = "tw.music.streamer" + compileSdk = 33 + + defaultConfig { + applicationId = "tw.music.streamer" + minSdk = 27 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + + vectorDrawables { + useSupportLibrary = true + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + buildTypes { + release { + isMinifyEnabled = true + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + + buildFeatures { + viewBinding = true + } +} + +dependencies { + implementation("androidx.lifecycle:lifecycle-livedata:2.5.1") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + implementation("com.google.android.material:material:1.9.0") + implementation("androidx.navigation:navigation-ui:2.5.3") + implementation("androidx.lifecycle:lifecycle-viewmodel:2.5.1") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("androidx.navigation:navigation-fragment:2.5.3") + implementation("com.google.code.gson:gson:2.10.1") + implementation("com.github.bumptech.glide:glide:4.15.1") + annotationProcessor("com.github.bumptech.glide:compiler:4.15.1") + implementation("com.google.firebase:firebase-auth:22.1.1") + implementation("com.google.firebase:firebase-database:20.3.1") + implementation("com.google.firebase:firebase-storage:20.3.0") + implementation("com.google.android.gms:play-services-tasks:18.0.2") + implementation("com.squareup.okhttp3:okhttp:4.11.0") +} + +apply(plugin = "com.google.gms.google-services") \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5a007af..d5b10ba 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,7 @@ - + + + @@ -9,19 +11,15 @@ + android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar" + android:largeHeap="true"> + android:exported="true"> @@ -47,103 +45,66 @@ + android:exported="true"/> + android:exported="true"/> + android:name=".DebugActivity"/> + android:exported="true"/> + android:name=".ProfileActivity"/> + android:exported="true"/> + android:name=".ChgpicActivity"/> + android:exported="true"/> + android:name=".CropActivity"/> + android:name=".MessageActivity"/> + android:name=".StreamerActivity"/> + android:screenOrientation="landscape"/> + android:name=".FilepickerActivity"/> + android:name=".UpdateappActivity"/> + android:exported="true"/> + android:exported="true"/> + android:exported="true"/> + android:name=".LyricsActivity"/> map = new HashMap<>(); private boolean isBanned = false; @@ -92,25 +92,25 @@ public class MainActivity extends AppCompatActivity { private TextView textview4; private SharedPreferences data; - private DatabaseReference update_db = _firebase.getReference("update/version"); + private DatabaseReference update_db;// = FirebaseDatabase.getInstance().getReference("update/version"); private ChildEventListener _update_db_child_listener; private Intent intent = new Intent(); private AlertDialog.Builder d; - private DatabaseReference profile = _firebase.getReference("profile/text"); + private DatabaseReference profile;// = FirebaseDatabase.getInstance().getReference("profile/text"); private ChildEventListener _profile_child_listener; private FirebaseAuth Auth; private OnCompleteListener _Auth_create_user_listener; private OnCompleteListener _Auth_sign_in_listener; private OnCompleteListener _Auth_reset_password_listener; private Intent activityChanger = new Intent(); - private DatabaseReference prof_img = _firebase.getReference("profile/image"); + private DatabaseReference prof_img;// = FirebaseDatabase.getInstance().getReference("profile/image"); private ChildEventListener _prof_img_child_listener; private TimerTask timer; private ObjectAnimator objectanim3 = new ObjectAnimator(); private RequestNetwork internetchecker; private RequestNetwork.RequestListener _internetchecker_request_listener; private TimerTask delaynointernet; - private DatabaseReference prof_bans = _firebase.getReference("profile/bans"); + private DatabaseReference prof_bans;// = FirebaseDatabase.getInstance().getReference("profile/bans"); private ChildEventListener _prof_bans_child_listener; private RequestNetwork rn; private RequestNetwork.RequestListener _rn_request_listener; @@ -121,11 +121,13 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle _savedInstanceState) { super.onCreate(_savedInstanceState); setContentView(R.layout.main); - com.google.firebase.FirebaseApp.initializeApp(this); - initialize(_savedInstanceState); - initializeLogic(); + //com.google.firebase.FirebaseApp.initializeApp(this); + //initialize(_savedInstanceState); + //initializeLogic(); } + /* + private void initialize(Bundle _savedInstanceState) { linear1 = findViewById(R.id.linear1); @@ -791,9 +793,6 @@ private void initializeLogic() { } } _checkCookie(); - /* -Glide.with(getApplicationContext()).load(Uri.parse("'-'")).into(image_user); -*/ } private boolean _checkPermission() { @@ -823,7 +822,7 @@ public void onBackPressed() { @Override public void onStart() { super.onStart(); - _DarkMode(); + //_DarkMode(); } @Override @@ -845,7 +844,6 @@ public void onStop() { } private void _customNav(final String _color) { - //Code From StackOverFlow.com And Converted By TeamWorks DEV if (Build.VERSION.SDK_INT >= 21) { Window w = this.getWindow(); w.setNavigationBarColor(Color.parseColor(_color)); @@ -854,15 +852,10 @@ private void _customNav(final String _color) { private void _customSnack(final String _txt, final double _icon) { - // Create the Snackbar ViewGroup containerLayout = (ViewGroup) ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0); - com.google.android.material.snackbar.Snackbar snackbar = com.google.android.material.snackbar.Snackbar.make(containerLayout, "", com.google.android.material.snackbar.Snackbar.LENGTH_LONG); - // Get the Snackbar's layout view com.google.android.material.snackbar.Snackbar.SnackbarLayout layout = (com.google.android.material.snackbar.Snackbar.SnackbarLayout) snackbar.getView(); - // Inflate our custom view View snackview = getLayoutInflater().inflate(R.layout.custom_snack, null); - // Configure the view ImageView image = snackview.findViewById(R.id.imageview); if (_icon == 0) { image.setImageResource(R.drawable.ic_info_outline_white); @@ -883,9 +876,7 @@ private void _customSnack(final String _txt, final double _icon) { text.setTextColor(Color.WHITE); text.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); layout.setPadding(0, 0, 0, 0); - // Add the view to the Snackbar's layout layout.addView(snackview, 0); - // Show the Snackbar snackbar.show(); } @@ -1038,61 +1029,21 @@ private void _checkCookie() { } } + */ private void _shadow(final View _v, final double _n) { _v.setElevation((float) _n); } - - @Deprecated - public void showMessage(String _s) { - Toast.makeText(getApplicationContext(), _s, Toast.LENGTH_SHORT).show(); - } - - @Deprecated - public int getLocationX(View _v) { - int[] _location = new int[2]; - _v.getLocationInWindow(_location); - return _location[0]; - } - - @Deprecated - public int getLocationY(View _v) { - int[] _location = new int[2]; - _v.getLocationInWindow(_location); - return _location[1]; - } - @Deprecated public int getRandom(int _min, int _max) { Random random = new Random(); return random.nextInt(_max - _min + 1) + _min; } - @Deprecated - public ArrayList getCheckedItemPositionsToArray(ListView _list) { - ArrayList _result = new ArrayList(); - SparseBooleanArray _arr = _list.getCheckedItemPositions(); - for (int _iIdx = 0; _iIdx < _arr.size(); _iIdx++) { - if (_arr.valueAt(_iIdx)) - _result.add((double) _arr.keyAt(_iIdx)); - } - return _result; - } - @Deprecated public float getDip(int _input) { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, _input, getResources().getDisplayMetrics()); } - @Deprecated - public int getDisplayWidthPixels() { - return getResources().getDisplayMetrics().widthPixels; - } - - @Deprecated - public int getDisplayHeightPixels() { - return getResources().getDisplayMetrics().heightPixels; - } - } diff --git a/app/src/main/java/tw/music/streamer/MainActivity2.java b/app/src/main/java/tw/music/streamer/MainActivity2.java new file mode 100644 index 0000000..6d5c341 --- /dev/null +++ b/app/src/main/java/tw/music/streamer/MainActivity2.java @@ -0,0 +1,18 @@ +package tw.music.streamer; + +import androidx.appcompat.app.AppCompatActivity; +import android.app.Activity; +import android.os.Bundle; + +public class MainActivity2 extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } +} \ No newline at end of file diff --git a/app/src/main/java/tw/music/streamer/StreamerActivity.java b/app/src/main/java/tw/music/streamer/StreamerActivity.java index 02dbad8..3bf2117 100644 --- a/app/src/main/java/tw/music/streamer/StreamerActivity.java +++ b/app/src/main/java/tw/music/streamer/StreamerActivity.java @@ -814,12 +814,11 @@ public void onClick(View _view) { image_play.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View _view) { - /*if (tmservice._isPlaying()) { - tmservice._mpPause(); - tmservice._removeFocus(); - } else { - tmservice._requestFocus(); - }*/ + if (zz.isPlaying()) { + zz.requestAction("pause"); + } else if (zz.isInitialized()) { + zz.requestAction("resume"); + } } }); @@ -1650,38 +1649,24 @@ public void onComplete(Task _param1) { private void initializeLogic() { overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); - getSupportActionBar().hide(); - hscroll1.setVerticalScrollBarEnabled(false); hscroll1.setHorizontalScrollBarEnabled(false); - setVolumeControlStream(AudioManager.STREAM_MUSIC); x_tab = new com.google.android.material.tabs.TabLayout(StreamerActivity.this); - x_tab.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); - x_tab.setTabMode(TabLayout.MODE_SCROLLABLE); - x_tab.setTabGravity(TabLayout.GRAVITY_CENTER); - x_tab.setSelectedTabIndicatorHeight(6); - x_tab.addTab(x_tab.newTab().setText("Library")); - x_tab.getChildAt(0).setPadding(70, 0, 70, 0); - x_tab.addTab(x_tab.newTab().setText("My Favs")); - x_tab.addTab(x_tab.newTab().setText("Most Played")); - x_tab.addTab(x_tab.newTab().setText("My Playlists")); linear_title.removeView(linear_title_shdw); - linear_title.addView(x_tab); - linear_title.addView(linear_title_shdw); x_tab.addOnTabSelectedListener(new com.google.android.material.tabs.TabLayout.OnTabSelectedListener() { @@ -1777,19 +1762,12 @@ public boolean onLongClick(View _view) { listview2 = new GridView(StreamerActivity.this); listview2.setLayoutParams(new GridView.LayoutParams(GridLayout.LayoutParams.MATCH_PARENT, GridLayout.LayoutParams.WRAP_CONTENT)); - listview2.setNumColumns(GridView.AUTO_FIT); - listview2.setVerticalSpacing(2); - listview2.setHorizontalSpacing(2); - listview2.setColumnWidth((int) SketchwareUtil.getDip(getApplicationContext(), 118)); - listview2.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); - linear1.addView(listview2); - listview2.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int _pos, long id) { @@ -1801,7 +1779,6 @@ public void onItemClick(AdapterView parent, View view, int _pos, long id) { _bindSvc(); try { android.content.pm.PackageInfo packageInfo = StreamerActivity.this.getPackageManager().getPackageInfo(getPackageName(), 0); - } catch (Exception _e) { } text_title.setEllipsize(TextUtils.TruncateAt.MARQUEE); @@ -1825,43 +1802,34 @@ public void onItemClick(AdapterView parent, View view, int _pos, long id) { } text_playlist.setVisibility(View.GONE); edittext_search.setVisibility(View.GONE); - text_zryte.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - text_zene.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesansbold.ttf"), 0); - text_playlist.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - text_data.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - text_title.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - text_artist.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - text_current.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - text_duration.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - edittext_search.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - _drawer_text_zryte.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_zene.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesansbold.ttf"), 0); - - _drawer_text_user.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_email.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_upload.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_theme.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_themesstr.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_info.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_logcat.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_discord.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_daedit.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); - - _drawer_text_settings.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"), 0); + Typeface tsans = Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf"); + Typeface tbold = Typeface.createFromAsset(getAssets(), "fonts/googlesansbold.ttf"); + text_zryte.setTypeface(tsans, 0); + text_zene.setTypeface(tbold, 0); + text_playlist.setTypeface(tsans, 0); + text_data.setTypeface(tsans, 0); + text_title.setTypeface(tsans, 0); + text_artist.setTypeface(tsans, 0); + text_current.setTypeface(tsans, 0); + text_duration.setTypeface(tsans, 0); + edittext_search.setTypeface(tsans, 0); + _drawer_text_zryte.setTypeface(tsans, 0); + _drawer_text_zene.setTypeface(tbold, 0); + _drawer_text_user.setTypeface(tsans, 0); + _drawer_text_email.setTypeface(tsans, 0); + _drawer_text_upload.setTypeface(tsans, 0); + _drawer_text_theme.setTypeface(tsans, 0); + _drawer_text_themesstr.setTypeface(tsans, 0); + _drawer_text_info.setTypeface(tsans, 0); + _drawer_text_logcat.setTypeface(tsans, 0); + _drawer_text_discord.setTypeface(tsans, 0); + _drawer_text_daedit.setTypeface(tsans, 0); + _drawer_text_settings.setTypeface(tsans, 0); if (data.getString("taptarget", "").equals("1")) { - _NewTapTarget(image_user, "Account", "Click here or by clicking account information on the drawer for accessing your account info & settings", "#2196F3"); + //_NewTapTarget(image_user, "Account", "Click here or by clicking account information on the drawer for accessing your account info & settings", "#2196F3"); } else { if (!data.getString("taptarget", "").equals("2")) { - _NewTapTarget(image_drawer, "Menu", "Click here for accessing some extra menu", "#2196F3"); + //_NewTapTarget(image_drawer, "Menu", "Click here for accessing some extra menu", "#2196F3"); } } if (data.getString("nightcore", "").equals("1")) { @@ -1890,9 +1858,6 @@ public void onItemClick(AdapterView parent, View view, int _pos, long id) { IntentFilter filr = new IntentFilter(ZryteZenePlay.ACTION_UPDATE); registerReceiver(listenerReceiver, filr); zz.requestAction("request-media"); - /* -Glide.with(getApplicationContext()).load(Uri.parse("c")).into(image_album); -*/ } private BroadcastReceiver listenerReceiver = new BroadcastReceiver() { @@ -1903,6 +1868,36 @@ public void onReceive(Context context, Intent intent) { String m = intent.getStringExtra("update"); if (m.equals("on-prepared")) { _CoreProgressLoading(false); + zz.setPlaying(true); + zz.setCurrentDuration(0); + zz.setDuration(intent.getIntExtra("data",0)/1000); + seekbar1.setProgress(0); + seekbar1.setMax(zz.getDuration()); + _showPlayer(); + } else if (m.equals("on-reqmedia")) { + } else if (m.equals("on-tick")) { + zz.setCurrentDuration(intent.getIntExtra("data",0)); + seekbar1.setProgress(zz.getCurrentDuration()/1000); + } else if (m.equals("on-completion")) { + zz.setPlaying(false); + } else if (m.equals("on-error")) { + zz.addError(intent.getStringExtra("data")); + } else if (m.equals("on-seekerror")) { + } else if (m.equals("on-initialized")) { + } else if (m.equals("on-bufferupdate")) { + zz.setBufferingUpdate(intent.getIntExtra("data",0)); + } else if (m.equals("request-play")) { + } else if (m.equals("request-pause")) { + zz.setPlaying(false); + } else if (m.equals("request-resume")) { + zz.setPlaying(true); + } else if (m.equals("request-stop")) { + zz.setPlaying(false); + } else if (m.equals("request-seek")) { + zz.setCurrentDuration(intent.getIntExtra("data",0)/1000); + } else if (m.equals("request-restart")) { + zz.setCurrentDuration(0); + } else if (m.equals("request-reset")) { } } } @@ -1952,11 +1947,7 @@ public void onBackPressed() { _setMenu(tabsPos); _abandonFocus(); } else { - //if (!tmservice._isMpNull()) { - //moveTaskToBack(true); - //} else { - //finish(); - //} + finish(); } } } @@ -2308,19 +2299,12 @@ private void _downloadFile(final String _url, final String _path) { String _fileName = URLUtil.guessFileName(_url, null, null); java.io.File _filePath = new java.io.File(_path + "/" + _fileName); DownloadManager.Request request = new DownloadManager.Request(Uri.parse(_url)); - request.setDescription(_url); - request.setTitle(_fileName); - request.allowScanningByMediaScanner(); - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); - request.setDestinationUri(Uri.fromFile(_filePath)); - final DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); - final long downloadID = downloadManager.enqueue(request); } catch (Exception _error) { _customSnack(_error.getMessage(), 2); @@ -2572,16 +2556,12 @@ private void _addGrid(final double _position) { } else { LinearLayout mylayout = new LinearLayout(StreamerActivity.this); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - mylayout.setLayoutParams(params); mylayout.setOrientation(LinearLayout.VERTICAL); - final EditText myedittext = new EditText(StreamerActivity.this); myedittext.setLayoutParams(new LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT)); myedittext.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); - mylayout.addView(myedittext); d.setView(mylayout); myedittext.setHint("Enter your Playlist name"); @@ -2597,7 +2577,6 @@ public void onClick(DialogInterface _dialog, int _which) { _item.put("name", myedittext.getText().toString()); playlistMap.add(_item); } - playlistMap.get(playlistMap.size() - 1).put("keys", "[]"); data.edit().putString("playlist", new Gson().toJson(playlistMap)).commit(); playKeys.clear(); @@ -2647,9 +2626,7 @@ public void onClick(DialogInterface _dialog, int _which) { private void _play(final String _key) { _CoreProgressLoading(true); - //tmservice._resetMp(); final double _position = currentlyChild.indexOf(_key); - //tmservice._playSongFromURL(currentlyMap.get((int) _position).get("url").toString()); currentlyPlaying = _key; text_title.setText(currentlyMap.get((int) _position).get("name").toString()); if (usrname_list.contains(currentlyMap.get((int) _position).get("uid").toString())) { @@ -2672,42 +2649,6 @@ private void _play(final String _key) { zz.requestAction("play", currentlyMap.get((int) _position).get("url").toString()); } - private void _NewTapTarget(final View _view, final String _title, final String _msg, final String _bgcolor) { - TapTargetView.showFor(StreamerActivity.this, - TapTarget.forView(_view, _title, _msg) - .outerCircleColorInt(Color.parseColor(_bgcolor)) - .outerCircleAlpha(0.96f) - .targetCircleColorInt(Color.parseColor("#FFFFFF")) - .titleTextSize(25) - .titleTextColorInt(Color.parseColor("#FFFFFF")) - .descriptionTextSize(18) - .descriptionTextColor(android.R.color.white) - .textColorInt(Color.parseColor("#FFFFFF")) - .textTypeface(Typeface.createFromAsset(getAssets(), "fonts/googlesans.ttf")) - .dimColor(android.R.color.black) - .drawShadow(true) - .cancelable(true) - .tintTarget(true) - .transparentTarget(true) - //.icon(Drawable) - .targetRadius(60), - - //LISTENER// - - new TapTargetView.Listener() { - @Override - public void onTargetClick(TapTargetView view) { - super.onTargetClick(view); - if (data.getString("taptarget", "").equals("1")) { - data.edit().putString("taptarget", "2").commit(); - } else { - data.edit().putString("taptarget", "1").commit(); - _NewTapTarget(image_user, "Account", "Click here or by clicking account information on the drawer for accessing your account info & settings", "#2196F3"); - } - } - }); - } - private void _shape(final double _tl, final double _tr, final double _bl, final double _br, final String _BGcolor, final String _Scolor, final double _Swidth, final View _view) { Double tlr = _tl; Double trr = _tr; @@ -2742,7 +2683,6 @@ private void _mpPreparedListener() { _customSnack("Android Lollipop or lower doesn't support nightcore feature!", 2); } } - //tmservice._requestFocus(); _CoreProgressLoading(false); _refreshLikes(); if (openNum == 0) { @@ -2752,8 +2692,6 @@ private void _mpPreparedListener() { upload_map = currentlyMap.get((int) _position); upload_map.put("view", String.valueOf((long) (Double.parseDouble(upload_map.get("view").toString()) + 1))); upload_text.child(currentlyPlaying).updateChildren(upload_map); - //text_duration.setText(new DecimalFormat("00").format(tmservice._getSongDuration() / 60000).concat(":".concat(new DecimalFormat("00").format((tmservice._getSongDuration() / 1000) % 60)))); - //seekbar1.setMax(tmservice._getSongDuration() / 1000); } private void _mpErrorListener(final String _errorMsg) { @@ -2768,8 +2706,6 @@ private void _mpErrorListener(final String _errorMsg) { obj.setDuration(500); obj.start(); _customNav(theme_map.get(0).get("colorBackground").toString()); - //tmservice._removeFocus(); - //tmservice._resetMp(); zz.clear(); currentlyMap.clear(); currentlyChild.clear(); @@ -2797,8 +2733,6 @@ private void _mpCompletionListener() { obj.setDuration(500); obj.start(); _customNav(theme_map.get(0).get("colorBackground").toString()); - //tmservice._removeFocus(); - //tmservice._resetMp(); zz.clear(); currentlyMap.clear(); currentlyChild.clear(); @@ -2850,24 +2784,15 @@ private void _handleMpError(final String _msg) { obj.setDuration(500); obj.start(); _customNav(theme_map.get(0).get("colorBackground").toString()); - //tmservice._removeFocus(); - //tmservice._resetMp(); zz.requestAction("reset"); currentlyMap.clear(); currentlyChild.clear(); } private void _bindSvc() { - /*if (tmservice == null) { - Intent svcintent = new Intent(StreamerActivity.this, ZryteZeneService.class); - bindService(svcintent, serviceConnection, Context.BIND_AUTO_CREATE); - }*/ } private void _unbindSvc() { - /*if (tmservice != null) { - unbindService(serviceConnection); - }*/ } @Deprecated @@ -2895,17 +2820,6 @@ public int getRandom(int _min, int _max) { return random.nextInt(_max - _min + 1) + _min; } - @Deprecated - public ArrayList getCheckedItemPositionsToArray(ListView _list) { - ArrayList _result = new ArrayList(); - SparseBooleanArray _arr = _list.getCheckedItemPositions(); - for (int _iIdx = 0; _iIdx < _arr.size(); _iIdx++) { - if (_arr.valueAt(_iIdx)) - _result.add((double) _arr.keyAt(_iIdx)); - } - return _result; - } - @Deprecated public float getDip(int _input) { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, _input, getResources().getDisplayMetrics()); @@ -3119,1411 +3033,6 @@ private static int lightenColor(int color, double fraction) { } } - static class UiUtil { - UiUtil() { - } - - static int dp(Context context, int val) { - return (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, val, context.getResources().getDisplayMetrics()); - } - - static int sp(Context context, int val) { - return (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_SP, val, context.getResources().getDisplayMetrics()); - } - - static int themeIntAttr(Context context, String attr) { - final android.content.res.Resources.Theme theme = context.getTheme(); - if (theme == null) { - return -1; - } - final TypedValue value = new TypedValue(); - final int id = context.getResources().getIdentifier(attr, "attr", context.getPackageName()); - - if (id == 0) { - // Not found - return -1; - } - theme.resolveAttribute(id, value, true); - return value.data; - } - - static int setAlpha(int argb, float alpha) { - if (alpha > 1.0f) { - alpha = 1.0f; - } else if (alpha <= 0.0f) { - alpha = 0.0f; - } - return ((int) ((argb >>> 24) * alpha) << 24) | (argb & 0x00FFFFFF); - } - } - - static class FloatValueAnimatorBuilder { - - private final ValueAnimator animator; - - private EndListener endListener; - - protected FloatValueAnimatorBuilder() { - this(false); - } - - FloatValueAnimatorBuilder(boolean reverse) { - if (reverse) { - this.animator = ValueAnimator.ofFloat(1.0f, 0.0f); - } else { - this.animator = ValueAnimator.ofFloat(0.0f, 1.0f); - } - } - - public FloatValueAnimatorBuilder delayBy(long millis) { - animator.setStartDelay(millis); - return this; - } - - public FloatValueAnimatorBuilder duration(long millis) { - animator.setDuration(millis); - return this; - } - - public FloatValueAnimatorBuilder interpolator(TimeInterpolator lerper) { - animator.setInterpolator(lerper); - return this; - } - - public FloatValueAnimatorBuilder repeat(int times) { - animator.setRepeatCount(times); - return this; - } - - public FloatValueAnimatorBuilder onUpdate(final UpdateListener listener) { - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - listener.onUpdate((float) animation.getAnimatedValue()); - } - }); - return this; - } - - public FloatValueAnimatorBuilder onEnd(final EndListener listener) { - this.endListener = listener; - return this; - } - - public ValueAnimator build() { - if (endListener != null) { - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - endListener.onEnd(); - } - }); - } - return animator; - } - - interface UpdateListener { - void onUpdate(float lerpTime); - } - - interface EndListener { - void onEnd(); - } - } - - static class ReflectUtil { - ReflectUtil() { - } - - static Object getPrivateField(Object source, String fieldName) - throws NoSuchFieldException, IllegalAccessException { - final java.lang.reflect.Field objectField = source.getClass().getDeclaredField(fieldName); - objectField.setAccessible(true); - return objectField.get(source); - } - } - - static class TapTarget extends Activity { - final CharSequence title; - final CharSequence description; - float outerCircleAlpha = 0.96f; - int targetRadius = 44; - Rect bounds; - android.graphics.drawable.Drawable icon; - Typeface titleTypeface; - Typeface descriptionTypeface; - int id = -1; - boolean drawShadow = false; - boolean cancelable = true; - boolean tintTarget = true; - boolean transparentTarget = false; - float descriptionTextAlpha = 0.54f; - private int outerCircleColorRes = -1; - private int targetCircleColorRes = -1; - private int dimColorRes = -1; - private int titleTextColorRes = -1; - private int descriptionTextColorRes = -1; - private Integer outerCircleColor = null; - private Integer targetCircleColor = null; - private Integer dimColor = null; - private Integer titleTextColor = null; - private Integer descriptionTextColor = null; - private int titleTextDimen = -1; - private int descriptionTextDimen = -1; - private int titleTextSize = 20; - private int descriptionTextSize = 18; - - protected TapTarget(Rect bounds, CharSequence title, CharSequence description) { - this(title, description); - if (bounds == null) { - throw new IllegalArgumentException("Cannot pass null bounds or title"); - } - this.bounds = bounds; - } - - protected TapTarget(CharSequence title, CharSequence description) { - if (title == null) { - throw new IllegalArgumentException("Cannot pass null title"); - } - this.title = title; - this.description = description; - } - - public static TapTarget forView(View view, CharSequence title) { - return forView(view, title, null); - } - - public static TapTarget forView(View view, CharSequence title, CharSequence description) { - return new ViewTapTarget(view, title, description); - } - - public static TapTarget forBounds(Rect bounds, CharSequence title) { - return forBounds(bounds, title, null); - } - - public static TapTarget forBounds(Rect bounds, CharSequence title, CharSequence description) { - return new TapTarget(bounds, title, description); - } - - public TapTarget transparentTarget(boolean transparent) { - this.transparentTarget = transparent; - return this; - } - - public TapTarget outerCircleColor(int color) { - this.outerCircleColorRes = color; - return this; - } - - public TapTarget outerCircleColorInt(int color) { - this.outerCircleColor = color; - return this; - } - - public TapTarget outerCircleAlpha(float alpha) { - if (alpha < 0.0f || alpha > 1.0f) { - throw new IllegalArgumentException("Given an invalid alpha value: " + alpha); - } - this.outerCircleAlpha = alpha; - return this; - } - - public TapTarget targetCircleColor(int color) { - this.targetCircleColorRes = color; - return this; - } - - public TapTarget targetCircleColorInt(int color) { - this.targetCircleColor = color; - return this; - } - - public TapTarget textColor(int color) { - this.titleTextColorRes = color; - this.descriptionTextColorRes = color; - return this; - } - - public TapTarget textColorInt(int color) { - this.titleTextColor = color; - this.descriptionTextColor = color; - return this; - } - - public TapTarget titleTextColor(int color) { - this.titleTextColorRes = color; - return this; - } - - public TapTarget titleTextColorInt(int color) { - this.titleTextColor = color; - return this; - } - - public TapTarget descriptionTextColor(int color) { - this.descriptionTextColorRes = color; - return this; - } - - public TapTarget descriptionTextColorInt(int color) { - this.descriptionTextColor = color; - return this; - } - - public TapTarget textTypeface(Typeface typeface) { - if (typeface == null) throw new IllegalArgumentException("Cannot use a null typeface"); - titleTypeface = typeface; - descriptionTypeface = typeface; - return this; - } - - public TapTarget titleTypeface(Typeface titleTypeface) { - if (titleTypeface == null) - throw new IllegalArgumentException("Cannot use a null typeface"); - this.titleTypeface = titleTypeface; - return this; - } - - public TapTarget descriptionTypeface(Typeface descriptionTypeface) { - if (descriptionTypeface == null) - throw new IllegalArgumentException("Cannot use a null typeface"); - this.descriptionTypeface = descriptionTypeface; - return this; - } - - public TapTarget titleTextSize(int sp) { - if (sp < 0) throw new IllegalArgumentException("Given negative text size"); - this.titleTextSize = sp; - return this; - } - - public TapTarget descriptionTextSize(int sp) { - if (sp < 0) throw new IllegalArgumentException("Given negative text size"); - this.descriptionTextSize = sp; - return this; - } - - public TapTarget titleTextDimen(int dimen) { - this.titleTextDimen = dimen; - return this; - } - - public TapTarget descriptionTextAlpha(float descriptionTextAlpha) { - if (descriptionTextAlpha < 0 || descriptionTextAlpha > 1f) { - throw new IllegalArgumentException("Given an invalid alpha value: " + descriptionTextAlpha); - } - this.descriptionTextAlpha = descriptionTextAlpha; - return this; - } - - public TapTarget descriptionTextDimen(int dimen) { - this.descriptionTextDimen = dimen; - return this; - } - - public TapTarget dimColor(int color) { - this.dimColorRes = color; - return this; - } - - public TapTarget dimColorInt(int color) { - this.dimColor = color; - return this; - } - - public TapTarget drawShadow(boolean draw) { - this.drawShadow = draw; - return this; - } - - public TapTarget cancelable(boolean status) { - this.cancelable = status; - return this; - } - - public TapTarget tintTarget(boolean tint) { - this.tintTarget = tint; - return this; - } - - public TapTarget icon(android.graphics.drawable.Drawable icon) { - return icon(icon, false); - } - - public TapTarget icon(android.graphics.drawable.Drawable icon, boolean hasSetBounds) { - if (icon == null) throw new IllegalArgumentException("Cannot use null drawable"); - this.icon = icon; - if (!hasSetBounds) { - this.icon.setBounds(new Rect(0, 0, this.icon.getIntrinsicWidth(), this.icon.getIntrinsicHeight())); - } - return this; - } - - public TapTarget id(int id) { - this.id = id; - return this; - } - - public TapTarget targetRadius(int targetRadius) { - this.targetRadius = targetRadius; - return this; - } - - public int id() { - return id; - } - - public void onReady(Runnable runnable) { - runnable.run(); - } - - public Rect bounds() { - if (bounds == null) { - throw new IllegalStateException("Requesting bounds that are not set! Make sure your target is ready"); - } - return bounds; - } - - Integer outerCircleColorInt(Context context) { - return colorResOrInt(context, outerCircleColor, outerCircleColorRes); - } - - Integer targetCircleColorInt(Context context) { - return colorResOrInt(context, targetCircleColor, targetCircleColorRes); - } - - Integer dimColorInt(Context context) { - return colorResOrInt(context, dimColor, dimColorRes); - } - - Integer titleTextColorInt(Context context) { - return colorResOrInt(context, titleTextColor, titleTextColorRes); - } - - Integer descriptionTextColorInt(Context context) { - return colorResOrInt(context, descriptionTextColor, descriptionTextColorRes); - } - - int titleTextSizePx(Context context) { - return dimenOrSize(context, titleTextSize, titleTextDimen); - } - - int descriptionTextSizePx(Context context) { - return dimenOrSize(context, descriptionTextSize, descriptionTextDimen); - } - - private Integer colorResOrInt(Context context, Integer value, int resource) { - if (resource != -1) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - return context.getColor(resource); - } - } - return value; - } - - private int dimenOrSize(Context context, int size, int dimen) { - if (dimen != -1) { - return context.getResources().getDimensionPixelSize(dimen); - } - return UiUtil.sp(context, size); - } - } - - static class TapTargetView extends View { - final int TARGET_PADDING; - final int TARGET_RADIUS; - final int TARGET_PULSE_RADIUS; - final int TEXT_PADDING; - final int TEXT_SPACING; - final int TEXT_MAX_WIDTH; - final int TEXT_POSITIONING_BIAS; - final int CIRCLE_PADDING; - final int GUTTER_DIM; - final int SHADOW_DIM; - final int SHADOW_JITTER_DIM; - final ViewGroup boundingParent; - final ViewManager parent; - final TapTarget target; - final Rect targetBounds; - final TextPaint titlePaint; - final TextPaint descriptionPaint; - final Paint outerCirclePaint; - final Paint outerCircleShadowPaint; - final Paint targetCirclePaint; - final Paint targetCirclePulsePaint; - private final ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener; - CharSequence title; - StaticLayout titleLayout; - CharSequence description; - StaticLayout descriptionLayout; - boolean isDark; - boolean debug; - boolean shouldTintTarget; - boolean shouldDrawShadow; - boolean cancelable; - boolean visible; - SpannableStringBuilder debugStringBuilder; - DynamicLayout debugLayout; - - // Debug related variables - TextPaint debugTextPaint; - Paint debugPaint; - // Drawing properties - Rect drawingBounds; - Rect textBounds; - Path outerCirclePath; - float outerCircleRadius; - int calculatedOuterCircleRadius; - int[] outerCircleCenter; - int outerCircleAlpha; - float targetCirclePulseRadius; - int targetCirclePulseAlpha; - float targetCircleRadius; - int targetCircleAlpha; - int textAlpha; - int dimColor; - float lastTouchX; - float lastTouchY; - int topBoundary; - int bottomBoundary; - Bitmap tintedTarget; - Listener listener; - ViewOutlineProvider outlineProvider; - final FloatValueAnimatorBuilder.UpdateListener expandContractUpdateListener = new FloatValueAnimatorBuilder.UpdateListener() { - @Override - public void onUpdate(float lerpTime) { - final float newOuterCircleRadius = calculatedOuterCircleRadius * lerpTime; - final boolean expanding = newOuterCircleRadius > outerCircleRadius; - if (!expanding) { - // When contracting we need to invalidate the old drawing bounds. Otherwise - // you will see artifacts as the circle gets smaller - calculateDrawingBounds(); - } - - final float targetAlpha = target.outerCircleAlpha * 255; - outerCircleRadius = newOuterCircleRadius; - outerCircleAlpha = (int) Math.min(targetAlpha, (lerpTime * 1.5f * targetAlpha)); - outerCirclePath.reset(); - outerCirclePath.addCircle(outerCircleCenter[0], outerCircleCenter[1], outerCircleRadius, Path.Direction.CW); - - targetCircleAlpha = (int) Math.min(255.0f, (lerpTime * 1.5f * 255.0f)); - - if (expanding) { - targetCircleRadius = TARGET_RADIUS * Math.min(1.0f, lerpTime * 1.5f); - } else { - targetCircleRadius = TARGET_RADIUS * lerpTime; - targetCirclePulseRadius *= lerpTime; - } - - textAlpha = (int) (delayedLerp(lerpTime, 0.7f) * 255); - - if (expanding) { - calculateDrawingBounds(); - } - - invalidateViewAndOutline(drawingBounds); - } - }; - final ValueAnimator pulseAnimation = new FloatValueAnimatorBuilder() - .duration(1000) - .repeat(ValueAnimator.INFINITE) - .interpolator(new AccelerateDecelerateInterpolator()) - .onUpdate(new FloatValueAnimatorBuilder.UpdateListener() { - @Override - public void onUpdate(float lerpTime) { - final float pulseLerp = delayedLerp(lerpTime, 0.5f); - targetCirclePulseRadius = (1.0f + pulseLerp) * TARGET_RADIUS; - targetCirclePulseAlpha = (int) ((1.0f - pulseLerp) * 255); - targetCircleRadius = TARGET_RADIUS + halfwayLerp(lerpTime) * TARGET_PULSE_RADIUS; - - if (outerCircleRadius != calculatedOuterCircleRadius) { - outerCircleRadius = calculatedOuterCircleRadius; - } - - calculateDrawingBounds(); - invalidateViewAndOutline(drawingBounds); - } - }) - .build(); - private boolean isDismissed = false; - private boolean isDismissing = false; - private boolean isInteractable = true; - final ValueAnimator expandAnimation = new FloatValueAnimatorBuilder() - .duration(250) - .delayBy(250) - .interpolator(new AccelerateDecelerateInterpolator()) - .onUpdate(new FloatValueAnimatorBuilder.UpdateListener() { - @Override - public void onUpdate(float lerpTime) { - expandContractUpdateListener.onUpdate(lerpTime); - } - }) - .onEnd(new FloatValueAnimatorBuilder.EndListener() { - @Override - public void onEnd() { - pulseAnimation.start(); - isInteractable = true; - } - }) - .build(); - final ValueAnimator dismissAnimation = new FloatValueAnimatorBuilder(true) - .duration(250) - .interpolator(new AccelerateDecelerateInterpolator()) - .onUpdate(new FloatValueAnimatorBuilder.UpdateListener() { - @Override - public void onUpdate(float lerpTime) { - expandContractUpdateListener.onUpdate(lerpTime); - } - }) - .onEnd(new FloatValueAnimatorBuilder.EndListener() { - @Override - public void onEnd() { - onDismiss(true); - ViewUtil.removeView(parent, TapTargetView.this); - } - }) - .build(); - private final ValueAnimator dismissConfirmAnimation = new FloatValueAnimatorBuilder() - .duration(250) - .interpolator(new AccelerateDecelerateInterpolator()) - .onUpdate(new FloatValueAnimatorBuilder.UpdateListener() { - @Override - public void onUpdate(float lerpTime) { - final float spedUpLerp = Math.min(1.0f, lerpTime * 2.0f); - outerCircleRadius = calculatedOuterCircleRadius * (1.0f + (spedUpLerp * 0.2f)); - outerCircleAlpha = (int) ((1.0f - spedUpLerp) * target.outerCircleAlpha * 255.0f); - outerCirclePath.reset(); - outerCirclePath.addCircle(outerCircleCenter[0], outerCircleCenter[1], outerCircleRadius, Path.Direction.CW); - targetCircleRadius = (1.0f - lerpTime) * TARGET_RADIUS; - targetCircleAlpha = (int) ((1.0f - lerpTime) * 255.0f); - targetCirclePulseRadius = (1.0f + lerpTime) * TARGET_RADIUS; - targetCirclePulseAlpha = (int) ((1.0f - lerpTime) * targetCirclePulseAlpha); - textAlpha = (int) ((1.0f - spedUpLerp) * 255.0f); - calculateDrawingBounds(); - invalidateViewAndOutline(drawingBounds); - } - }) - .onEnd(new FloatValueAnimatorBuilder.EndListener() { - @Override - public void onEnd() { - onDismiss(true); - ViewUtil.removeView(parent, TapTargetView.this); - } - }) - .build(); - private ValueAnimator[] animators = new ValueAnimator[] - {expandAnimation, pulseAnimation, dismissConfirmAnimation, dismissAnimation}; - - public TapTargetView(final Context context, - final ViewManager parent, - final ViewGroup boundingParent, - final TapTarget target, - final Listener userListener) { - super(context); - if (target == null) throw new IllegalArgumentException("Target cannot be null"); - - this.target = target; - this.parent = parent; - this.boundingParent = boundingParent; - this.listener = userListener != null ? userListener : new Listener(); - this.title = target.title; - this.description = target.description; - - TARGET_PADDING = UiUtil.dp(context, 20); - CIRCLE_PADDING = UiUtil.dp(context, 40); - TARGET_RADIUS = UiUtil.dp(context, target.targetRadius); - TEXT_PADDING = UiUtil.dp(context, 40); - TEXT_SPACING = UiUtil.dp(context, 8); - TEXT_MAX_WIDTH = UiUtil.dp(context, 360); - TEXT_POSITIONING_BIAS = UiUtil.dp(context, 20); - GUTTER_DIM = UiUtil.dp(context, 88); - SHADOW_DIM = UiUtil.dp(context, 8); - SHADOW_JITTER_DIM = UiUtil.dp(context, 1); - TARGET_PULSE_RADIUS = (int) (0.1f * TARGET_RADIUS); - - outerCirclePath = new Path(); - targetBounds = new Rect(); - drawingBounds = new Rect(); - - titlePaint = new TextPaint(); - titlePaint.setTextSize(target.titleTextSizePx(context)); - titlePaint.setTypeface(Typeface.create("sans-serif-medium", Typeface.NORMAL)); - titlePaint.setAntiAlias(true); - - descriptionPaint = new TextPaint(); - descriptionPaint.setTextSize(target.descriptionTextSizePx(context)); - descriptionPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL)); - descriptionPaint.setAntiAlias(true); - descriptionPaint.setAlpha((int) (0.54f * 255.0f)); - - outerCirclePaint = new Paint(); - outerCirclePaint.setAntiAlias(true); - outerCirclePaint.setAlpha((int) (target.outerCircleAlpha * 255.0f)); - - outerCircleShadowPaint = new Paint(); - outerCircleShadowPaint.setAntiAlias(true); - outerCircleShadowPaint.setAlpha(50); - outerCircleShadowPaint.setStyle(Paint.Style.STROKE); - outerCircleShadowPaint.setStrokeWidth(SHADOW_JITTER_DIM); - outerCircleShadowPaint.setColor(Color.BLACK); - - targetCirclePaint = new Paint(); - targetCirclePaint.setAntiAlias(true); - - targetCirclePulsePaint = new Paint(); - targetCirclePulsePaint.setAntiAlias(true); - - applyTargetOptions(context); - - globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - if (isDismissing) { - return; - } - updateTextLayouts(); - target.onReady(new Runnable() { - @Override - public void run() { - final int[] offset = new int[2]; - - targetBounds.set(target.bounds()); - - getLocationOnScreen(offset); - targetBounds.offset(-offset[0], -offset[1]); - - if (boundingParent != null) { - final WindowManager windowManager - = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - final DisplayMetrics displayMetrics = new DisplayMetrics(); - windowManager.getDefaultDisplay().getMetrics(displayMetrics); - - final Rect rect = new Rect(); - boundingParent.getWindowVisibleDisplayFrame(rect); - - // We bound the boundaries to be within the screen's coordinates to - // handle the case where the layout bounds do not match - // (like when FLAG_LAYOUT_NO_LIMITS is specified) - topBoundary = Math.max(0, rect.top); - bottomBoundary = Math.min(rect.bottom, displayMetrics.heightPixels); - } - - drawTintedTarget(); - requestFocus(); - calculateDimensions(); - - startExpandAnimation(); - } - }); - } - }; - - getViewTreeObserver().addOnGlobalLayoutListener(globalLayoutListener); - - setFocusableInTouchMode(true); - setClickable(true); - setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (listener == null || outerCircleCenter == null || !isInteractable) return; - - final boolean clickedInTarget = - distance(targetBounds.centerX(), targetBounds.centerY(), (int) lastTouchX, (int) lastTouchY) <= targetCircleRadius; - final double distanceToOuterCircleCenter = distance(outerCircleCenter[0], outerCircleCenter[1], - (int) lastTouchX, (int) lastTouchY); - final boolean clickedInsideOfOuterCircle = distanceToOuterCircleCenter <= outerCircleRadius; - - if (clickedInTarget) { - isInteractable = false; - listener.onTargetClick(TapTargetView.this); - } else if (clickedInsideOfOuterCircle) { - listener.onOuterCircleClick(TapTargetView.this); - } else if (cancelable) { - isInteractable = false; - listener.onTargetCancel(TapTargetView.this); - } - } - }); - - setOnLongClickListener(new OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - if (listener == null) return false; - - if (targetBounds.contains((int) lastTouchX, (int) lastTouchY)) { - listener.onTargetLongClick(TapTargetView.this); - return true; - } - - return false; - } - }); - } - - public static TapTargetView showFor(Activity activity, TapTarget target) { - return showFor(activity, target, null); - } - - public static TapTargetView showFor(Activity activity, TapTarget target, Listener listener) { - if (activity == null) throw new IllegalArgumentException("Activity is null"); - - final ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView(); - final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - final ViewGroup content = decor.findViewById(android.R.id.content); - final TapTargetView tapTargetView = new TapTargetView(activity, decor, content, target, listener); - decor.addView(tapTargetView, layoutParams); - - return tapTargetView; - } - - public static TapTargetView showFor(Dialog dialog, TapTarget target) { - return showFor(dialog, target, null); - } - - public static TapTargetView showFor(Dialog dialog, TapTarget target, Listener listener) { - if (dialog == null) throw new IllegalArgumentException("Dialog is null"); - - final Context context = dialog.getContext(); - final WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); - params.type = WindowManager.LayoutParams.TYPE_APPLICATION; - params.format = PixelFormat.RGBA_8888; - params.flags = 0; - params.gravity = Gravity.START | Gravity.TOP; - params.x = 0; - params.y = 0; - params.width = WindowManager.LayoutParams.MATCH_PARENT; - params.height = WindowManager.LayoutParams.MATCH_PARENT; - - final TapTargetView tapTargetView = new TapTargetView(context, windowManager, null, target, listener); - windowManager.addView(tapTargetView, params); - - return tapTargetView; - } - - private void startExpandAnimation() { - if (!visible) { - isInteractable = false; - expandAnimation.start(); - visible = true; - } - } - - protected void applyTargetOptions(Context context) { - shouldTintTarget = target.tintTarget; - shouldDrawShadow = target.drawShadow; - cancelable = target.cancelable; - - // We can't clip out portions of a view outline, so if the user specified a transparent - // target, we need to fallback to drawing a jittered shadow approximation - if (shouldDrawShadow && Build.VERSION.SDK_INT >= 21 && !target.transparentTarget) { - outlineProvider = new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - if (outerCircleCenter == null) return; - outline.setOval( - (int) (outerCircleCenter[0] - outerCircleRadius), (int) (outerCircleCenter[1] - outerCircleRadius), - (int) (outerCircleCenter[0] + outerCircleRadius), (int) (outerCircleCenter[1] + outerCircleRadius)); - outline.setAlpha(outerCircleAlpha / 255.0f); - if (Build.VERSION.SDK_INT >= 22) { - outline.offset(0, SHADOW_DIM); - } - } - }; - - setOutlineProvider(outlineProvider); - setElevation(SHADOW_DIM); - } - - if (shouldDrawShadow && outlineProvider == null && Build.VERSION.SDK_INT < 18) { - setLayerType(LAYER_TYPE_SOFTWARE, null); - } else { - setLayerType(LAYER_TYPE_HARDWARE, null); - } - - final android.content.res.Resources.Theme theme = context.getTheme(); - isDark = UiUtil.themeIntAttr(context, "isLightTheme") == 0; - - final Integer outerCircleColor = target.outerCircleColorInt(context); - if (outerCircleColor != null) { - outerCirclePaint.setColor(outerCircleColor); - } else if (theme != null) { - outerCirclePaint.setColor(UiUtil.themeIntAttr(context, "colorPrimary")); - } else { - outerCirclePaint.setColor(Color.WHITE); - } - - final Integer targetCircleColor = target.targetCircleColorInt(context); - if (targetCircleColor != null) { - targetCirclePaint.setColor(targetCircleColor); - } else { - targetCirclePaint.setColor(isDark ? Color.BLACK : Color.WHITE); - } - - if (target.transparentTarget) { - targetCirclePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); - } - - targetCirclePulsePaint.setColor(targetCirclePaint.getColor()); - - final Integer targetDimColor = target.dimColorInt(context); - if (targetDimColor != null) { - dimColor = UiUtil.setAlpha(targetDimColor, 0.3f); - } else { - dimColor = -1; - } - - final Integer titleTextColor = target.titleTextColorInt(context); - if (titleTextColor != null) { - titlePaint.setColor(titleTextColor); - } else { - titlePaint.setColor(isDark ? Color.BLACK : Color.WHITE); - } - - final Integer descriptionTextColor = target.descriptionTextColorInt(context); - if (descriptionTextColor != null) { - descriptionPaint.setColor(descriptionTextColor); - } else { - descriptionPaint.setColor(titlePaint.getColor()); - } - - if (target.titleTypeface != null) { - titlePaint.setTypeface(target.titleTypeface); - } - - if (target.descriptionTypeface != null) { - descriptionPaint.setTypeface(target.descriptionTypeface); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - onDismiss(false); - } - - void onDismiss(boolean userInitiated) { - if (isDismissed) return; - - isDismissing = false; - isDismissed = true; - - for (final ValueAnimator animator : animators) { - animator.cancel(); - animator.removeAllUpdateListeners(); - } - ViewUtil.removeOnGlobalLayoutListener(getViewTreeObserver(), globalLayoutListener); - visible = false; - - if (listener != null) { - listener.onTargetDismissed(this, userInitiated); - } - } - - @Override - protected void onDraw(Canvas c) { - if (isDismissed || outerCircleCenter == null) return; - - if (topBoundary > 0 && bottomBoundary > 0) { - c.clipRect(0, topBoundary, getWidth(), bottomBoundary); - } - - if (dimColor != -1) { - c.drawColor(dimColor); - } - - int saveCount; - outerCirclePaint.setAlpha(outerCircleAlpha); - if (shouldDrawShadow && outlineProvider == null) { - saveCount = c.save(); - { - c.clipPath(outerCirclePath, Region.Op.DIFFERENCE); - drawJitteredShadow(c); - } - c.restoreToCount(saveCount); - } - c.drawCircle(outerCircleCenter[0], outerCircleCenter[1], outerCircleRadius, outerCirclePaint); - - targetCirclePaint.setAlpha(targetCircleAlpha); - if (targetCirclePulseAlpha > 0) { - targetCirclePulsePaint.setAlpha(targetCirclePulseAlpha); - c.drawCircle(targetBounds.centerX(), targetBounds.centerY(), - targetCirclePulseRadius, targetCirclePulsePaint); - } - c.drawCircle(targetBounds.centerX(), targetBounds.centerY(), - targetCircleRadius, targetCirclePaint); - - saveCount = c.save(); - { - c.translate(textBounds.left, textBounds.top); - titlePaint.setAlpha(textAlpha); - if (titleLayout != null) { - titleLayout.draw(c); - } - - if (descriptionLayout != null && titleLayout != null) { - c.translate(0, titleLayout.getHeight() + TEXT_SPACING); - descriptionPaint.setAlpha((int) (target.descriptionTextAlpha * textAlpha)); - descriptionLayout.draw(c); - } - } - c.restoreToCount(saveCount); - - saveCount = c.save(); - { - if (tintedTarget != null) { - c.translate(targetBounds.centerX() - tintedTarget.getWidth() / 2, - targetBounds.centerY() - tintedTarget.getHeight() / 2); - c.drawBitmap(tintedTarget, 0, 0, targetCirclePaint); - } else if (target.icon != null) { - c.translate(targetBounds.centerX() - target.icon.getBounds().width() / 2, - targetBounds.centerY() - target.icon.getBounds().height() / 2); - target.icon.setAlpha(targetCirclePaint.getAlpha()); - target.icon.draw(c); - } - } - c.restoreToCount(saveCount); - - if (debug) { - drawDebugInformation(c); - } - } - - @Override - public boolean onTouchEvent(MotionEvent e) { - lastTouchX = e.getX(); - lastTouchY = e.getY(); - return super.onTouchEvent(e); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (isVisible() && cancelable && keyCode == KeyEvent.KEYCODE_BACK) { - event.startTracking(); - return true; - } - - return false; - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (isVisible() && isInteractable && cancelable - && keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) { - isInteractable = false; - - if (listener != null) { - listener.onTargetCancel(this); - } else { - new Listener().onTargetCancel(this); - } - - return true; - } - - return false; - } - - /** - * Dismiss this view - * - * @param tappedTarget If the user tapped the target or not - * (results in different dismiss animations) - */ - public void dismiss(boolean tappedTarget) { - isDismissing = true; - pulseAnimation.cancel(); - expandAnimation.cancel(); - if (tappedTarget) { - dismissConfirmAnimation.start(); - } else { - dismissAnimation.start(); - } - } - - /** - * Specify whether to draw a wireframe around the view, useful for debugging - **/ - public void setDrawDebug(boolean status) { - if (debug != status) { - debug = status; - postInvalidate(); - } - } - - /** - * Returns whether this view is visible or not - **/ - public boolean isVisible() { - return !isDismissed && visible; - } - - void drawJitteredShadow(Canvas c) { - final float baseAlpha = 0.20f * outerCircleAlpha; - outerCircleShadowPaint.setStyle(Paint.Style.FILL_AND_STROKE); - outerCircleShadowPaint.setAlpha((int) baseAlpha); - c.drawCircle(outerCircleCenter[0], outerCircleCenter[1] + SHADOW_DIM, outerCircleRadius, outerCircleShadowPaint); - outerCircleShadowPaint.setStyle(Paint.Style.STROKE); - final int numJitters = 7; - for (int i = numJitters - 1; i > 0; --i) { - outerCircleShadowPaint.setAlpha((int) ((i / (float) numJitters) * baseAlpha)); - c.drawCircle(outerCircleCenter[0], outerCircleCenter[1] + SHADOW_DIM, - outerCircleRadius + (numJitters - i) * SHADOW_JITTER_DIM, outerCircleShadowPaint); - } - } - - void drawDebugInformation(Canvas c) { - if (debugPaint == null) { - debugPaint = new Paint(); - debugPaint.setARGB(255, 255, 0, 0); - debugPaint.setStyle(Paint.Style.STROKE); - debugPaint.setStrokeWidth(UiUtil.dp(getContext(), 1)); - } - - if (debugTextPaint == null) { - debugTextPaint = new TextPaint(); - debugTextPaint.setColor(0xFFFF0000); - debugTextPaint.setTextSize(UiUtil.sp(getContext(), 16)); - } - - // Draw wireframe - debugPaint.setStyle(Paint.Style.STROKE); - c.drawRect(textBounds, debugPaint); - c.drawRect(targetBounds, debugPaint); - c.drawCircle(outerCircleCenter[0], outerCircleCenter[1], 10, debugPaint); - c.drawCircle(outerCircleCenter[0], outerCircleCenter[1], calculatedOuterCircleRadius - CIRCLE_PADDING, debugPaint); - c.drawCircle(targetBounds.centerX(), targetBounds.centerY(), TARGET_RADIUS + TARGET_PADDING, debugPaint); - - // Draw positions and dimensions - debugPaint.setStyle(Paint.Style.FILL); - final String debugText = - "Text bounds: " + textBounds.toShortString() + "\n" + "Target bounds: " + targetBounds.toShortString() + "\n" + "Center: " + outerCircleCenter[0] + " " + outerCircleCenter[1] + "\n" + "View size: " + getWidth() + " " + getHeight() + "\n" + "Target bounds: " + targetBounds.toShortString(); - - if (debugStringBuilder == null) { - debugStringBuilder = new SpannableStringBuilder(debugText); - } else { - debugStringBuilder.clear(); - debugStringBuilder.append(debugText); - } - - if (debugLayout == null) { - debugLayout = new DynamicLayout(debugText, debugTextPaint, getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); - } - - final int saveCount = c.save(); - { - debugPaint.setARGB(220, 0, 0, 0); - c.translate(0.0f, topBoundary); - c.drawRect(0.0f, 0.0f, debugLayout.getWidth(), debugLayout.getHeight(), debugPaint); - debugPaint.setARGB(255, 255, 0, 0); - debugLayout.draw(c); - } - c.restoreToCount(saveCount); - } - - void drawTintedTarget() { - final android.graphics.drawable.Drawable icon = target.icon; - if (!shouldTintTarget || icon == null) { - tintedTarget = null; - return; - } - - if (tintedTarget != null) return; - - tintedTarget = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), - Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(tintedTarget); - icon.setColorFilter(new PorterDuffColorFilter( - outerCirclePaint.getColor(), PorterDuff.Mode.SRC_ATOP)); - icon.draw(canvas); - icon.setColorFilter(null); - } - - void updateTextLayouts() { - final int textWidth = Math.min(getWidth(), TEXT_MAX_WIDTH) - TEXT_PADDING * 2; - if (textWidth <= 0) { - return; - } - - titleLayout = new StaticLayout(title, titlePaint, textWidth, - Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); - - if (description != null) { - descriptionLayout = new StaticLayout(description, descriptionPaint, textWidth, - Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); - } else { - descriptionLayout = null; - } - } - - float halfwayLerp(float lerp) { - if (lerp < 0.5f) { - return lerp / 0.5f; - } - - return (1.0f - lerp) / 0.5f; - } - - float delayedLerp(float lerp, float threshold) { - if (lerp < threshold) { - return 0.0f; - } - - return (lerp - threshold) / (1.0f - threshold); - } - - void calculateDimensions() { - textBounds = getTextBounds(); - outerCircleCenter = getOuterCircleCenterPoint(); - calculatedOuterCircleRadius = getOuterCircleRadius(outerCircleCenter[0], outerCircleCenter[1], textBounds, targetBounds); - } - - void calculateDrawingBounds() { - if (outerCircleCenter == null) { - // Called dismiss before we got a chance to display the tap target - // So we have no center -> cant determine the drawing bounds - return; - } - drawingBounds.left = (int) Math.max(0, outerCircleCenter[0] - outerCircleRadius); - drawingBounds.top = (int) Math.min(0, outerCircleCenter[1] - outerCircleRadius); - drawingBounds.right = (int) Math.min(getWidth(), - outerCircleCenter[0] + outerCircleRadius + CIRCLE_PADDING); - drawingBounds.bottom = (int) Math.min(getHeight(), - outerCircleCenter[1] + outerCircleRadius + CIRCLE_PADDING); - } - - int getOuterCircleRadius(int centerX, int centerY, Rect textBounds, Rect targetBounds) { - final int targetCenterX = targetBounds.centerX(); - final int targetCenterY = targetBounds.centerY(); - final int expandedRadius = (int) (1.1f * TARGET_RADIUS); - final Rect expandedBounds = new Rect(targetCenterX, targetCenterY, targetCenterX, targetCenterY); - expandedBounds.inset(-expandedRadius, -expandedRadius); - - final int textRadius = maxDistanceToPoints(centerX, centerY, textBounds); - final int targetRadius = maxDistanceToPoints(centerX, centerY, expandedBounds); - return Math.max(textRadius, targetRadius) + CIRCLE_PADDING; - } - - Rect getTextBounds() { - final int totalTextHeight = getTotalTextHeight(); - final int totalTextWidth = getTotalTextWidth(); - - final int possibleTop = targetBounds.centerY() - TARGET_RADIUS - TARGET_PADDING - totalTextHeight; - final int top; - if (possibleTop > topBoundary) { - top = possibleTop; - } else { - top = targetBounds.centerY() + TARGET_RADIUS + TARGET_PADDING; - } - - final int relativeCenterDistance = (getWidth() / 2) - targetBounds.centerX(); - final int bias = relativeCenterDistance < 0 ? -TEXT_POSITIONING_BIAS : TEXT_POSITIONING_BIAS; - final int left = Math.max(TEXT_PADDING, targetBounds.centerX() - bias - totalTextWidth); - final int right = Math.min(getWidth() - TEXT_PADDING, left + totalTextWidth); - return new Rect(left, top, right, top + totalTextHeight); - } - - int[] getOuterCircleCenterPoint() { - if (inGutter(targetBounds.centerY())) { - return new int[]{targetBounds.centerX(), targetBounds.centerY()}; - } - - final int targetRadius = Math.max(targetBounds.width(), targetBounds.height()) / 2 + TARGET_PADDING; - final int totalTextHeight = getTotalTextHeight(); - - final boolean onTop = targetBounds.centerY() - TARGET_RADIUS - TARGET_PADDING - totalTextHeight > 0; - - final int left = Math.min(textBounds.left, targetBounds.left - targetRadius); - final int right = Math.max(textBounds.right, targetBounds.right + targetRadius); - final int titleHeight = titleLayout == null ? 0 : titleLayout.getHeight(); - final int centerY = onTop ? - targetBounds.centerY() - TARGET_RADIUS - TARGET_PADDING - totalTextHeight + titleHeight - : - targetBounds.centerY() + TARGET_RADIUS + TARGET_PADDING + titleHeight; - - return new int[]{(left + right) / 2, centerY}; - } - - int getTotalTextHeight() { - if (titleLayout == null) { - return 0; - } - - if (descriptionLayout == null) { - return titleLayout.getHeight() + TEXT_SPACING; - } - - return titleLayout.getHeight() + descriptionLayout.getHeight() + TEXT_SPACING; - } - - int getTotalTextWidth() { - if (titleLayout == null) { - return 0; - } - - if (descriptionLayout == null) { - return titleLayout.getWidth(); - } - - return Math.max(titleLayout.getWidth(), descriptionLayout.getWidth()); - } - - boolean inGutter(int y) { - if (bottomBoundary > 0) { - return y < GUTTER_DIM || y > bottomBoundary - GUTTER_DIM; - } else { - return y < GUTTER_DIM || y > getHeight() - GUTTER_DIM; - } - } - - int maxDistanceToPoints(int x1, int y1, Rect bounds) { - final double tl = distance(x1, y1, bounds.left, bounds.top); - final double tr = distance(x1, y1, bounds.right, bounds.top); - final double bl = distance(x1, y1, bounds.left, bounds.bottom); - final double br = distance(x1, y1, bounds.right, bounds.bottom); - return (int) Math.max(tl, Math.max(tr, Math.max(bl, br))); - } - - double distance(int x1, int y1, int x2, int y2) { - return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); - } - - void invalidateViewAndOutline(Rect bounds) { - invalidate(bounds); - if (outlineProvider != null && Build.VERSION.SDK_INT >= 21) { - invalidateOutline(); - } - } - - public static class Listener { - /** - * Signals that the user has clicked inside of the target - **/ - public void onTargetClick(TapTargetView view) { - view.dismiss(true); - } - - /** - * Signals that the user has long clicked inside of the target - **/ - public void onTargetLongClick(TapTargetView view) { - onTargetClick(view); - } - - /** - * If cancelable, signals that the user has clicked outside of the outer circle - **/ - public void onTargetCancel(TapTargetView view) { - view.dismiss(false); - } - - /** - * Signals that the user clicked on the outer circle portion of the tap target - **/ - public void onOuterCircleClick(TapTargetView view) { - // no-op as default - } - - /** - * Signals that the tap target has been dismissed - * - * @param userInitiated Whether the user caused this action - */ - public void onTargetDismissed(TapTargetView view, boolean userInitiated) { - } - } - } - - static class ViewUtil { - - ViewUtil() { - } - - private static boolean isLaidOut(View view) { - return true; - } - - static void onLaidOut(final View view, final Runnable runnable) { - if (isLaidOut(view)) { - runnable.run(); - return; - } - final ViewTreeObserver observer = view.getViewTreeObserver(); - observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - final ViewTreeObserver trueObserver; - if (observer.isAlive()) { - trueObserver = observer; - } else { - trueObserver = view.getViewTreeObserver(); - } - removeOnGlobalLayoutListener(trueObserver, this); - runnable.run(); - } - }); - } - - @SuppressWarnings("deprecation") - static void removeOnGlobalLayoutListener(ViewTreeObserver observer, - ViewTreeObserver.OnGlobalLayoutListener listener) { - if (Build.VERSION.SDK_INT >= 16) { - observer.removeOnGlobalLayoutListener(listener); - } else { - observer.removeGlobalOnLayoutListener(listener); - } - } - - static void removeView(ViewManager parent, View child) { - if (parent == null || child == null) { - return; - } - try { - parent.removeView(child); - } catch (Exception ignored) { - } - } - } - - static class ViewTapTarget extends TapTarget { - final View view; - - ViewTapTarget(View view, CharSequence title, CharSequence description) { - super(title, description); - if (view == null) { - throw new IllegalArgumentException("Given null view to target"); - } - this.view = view; - } - - @Override - public void onReady(final Runnable runnable) { - ViewUtil.onLaidOut(view, new Runnable() { - @Override - public void run() { - // Cache bounds - final int[] location = new int[2]; - view.getLocationOnScreen(location); - bounds = new Rect(location[0], location[1], - location[0] + view.getWidth(), location[1] + view.getHeight()); - - if (icon == null && view.getWidth() > 0 && view.getHeight() > 0) { - final Bitmap viewBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(viewBitmap); - view.draw(canvas); - icon = new android.graphics.drawable.BitmapDrawable(view.getContext().getResources(), viewBitmap); - icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); - } - - runnable.run(); - } - }); - } - } - public class Listview1Adapter extends BaseAdapter { ArrayList> _data; diff --git a/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java b/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java index 611895a..1ac7412 100644 --- a/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java +++ b/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java @@ -9,19 +9,31 @@ public class ZryteZeneAdaptor { - private boolean isr, isp; - private int cd, bu; + private boolean isr, isp, isi; + private int cd, bu, d; private ArrayList e; private Context ctx; + private String sp, n; public ZryteZeneAdaptor(Context a) { isr = false; isp = false; + isi = false; cd = 0; + d = 0; + bu = 0; e = new ArrayList<>(); ctx = a; } + public void setInitialized(boolean a) { + isi = a; + } + + public boolean isInitialized() { + return isi; + } + public void setRunning(boolean a) { isr = a; } @@ -46,6 +58,14 @@ public int getCurrentDuration() { return cd; } + public void setDuration(int a) { + d = a; + } + + public int getDuration() { + return d; + } + public void setBufferingUpdate(int a) { bu = a; } @@ -80,5 +100,6 @@ public void requestAction(String a, String b) { jof.putExtra("action", a); jof.putExtra("req-data", b); ctx.sendBroadcast(jof); + if (a.equals("play")) sp = b; } } \ No newline at end of file diff --git a/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java b/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java index 3a3d62a..fde6cf1 100644 --- a/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java +++ b/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java @@ -69,5 +69,81 @@ public static void update(Context a, String b) { } notificationManager.notify(ZryteZenePlay.NOTIFICATION_ID, notification); } + + public static void update(Context a, boolean b) { + NotificationManager notificationManager = (NotificationManager) a.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) return; + Intent actionIntent; + PendingIntent actionPendingIntent; + String actionTitle; + int actionIcon; + if (b) { + actionIntent = new Intent(a, ZryteZenePlay.class); + actionIntent.setAction(ZryteZenePlay.ACTION_BROADCAST); + actionIntent.putExtra("action","pause"); + actionPendingIntent = PendingIntent.getService(a, 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + actionTitle = "Pause"; + actionIcon = android.R.drawable.ic_media_pause; + } else { + actionIntent = new Intent(a, ZryteZenePlay.class); + actionIntent.setAction(ZryteZenePlay.ACTION_BROADCAST); + actionIntent.putExtra("action","resume"); + actionPendingIntent = PendingIntent.getService(a, 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + actionTitle = "Resume"; + actionIcon = android.R.drawable.ic_media_play; + } + Intent openAppIntent = new Intent(a, StreamerActivity.class); + PendingIntent openAppPendingIntent = PendingIntent.getActivity(a, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + Notification updatedNotification = new Notification.Builder(a, ZryteZenePlay.CHANNEL_ID) + .setContentTitle("ZryteZene") + .setContentText(b ? "Music is playing" : "Paused") + .setSmallIcon(android.R.drawable.ic_media_play) + .setContentIntent(openAppPendingIntent) + .addAction(actionIcon, actionTitle, actionPendingIntent) + .setOngoing(true) + .build(); + notificationManager.notify(ZryteZenePlay.NOTIFICATION_ID, updatedNotification); + } + + public static void updateWithControls(Context a, boolean b) { + NotificationManager notificationManager = (NotificationManager) a.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) return; + + Intent playPauseIntent = new Intent(a, ZryteZenePlay.class); + playPauseIntent.setAction(ZryteZenePlay.ACTION_BROADCAST); + playPauseIntent.putExtra("action", b ? "pause" : "resume"); + PendingIntent playPausePendingIntent = PendingIntent.getService(a, 0, playPauseIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + + Intent previousIntent = new Intent(a, ZryteZenePlay.class); + previousIntent.setAction(ZryteZenePlay.ACTION_BROADCAST); + previousIntent.putExtra("action", "previous"); + PendingIntent previousPendingIntent = PendingIntent.getService(a, 1, previousIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + + Intent nextIntent = new Intent(a, ZryteZenePlay.class); + nextIntent.setAction(ZryteZenePlay.ACTION_BROADCAST); + nextIntent.putExtra("action", "forward"); + PendingIntent nextPendingIntent = PendingIntent.getService(a, 3, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + + Intent stopIntent = new Intent(a, ZryteZenePlay.class); + stopIntent.setAction(ZryteZenePlay.ACTION_BROADCAST); + stopIntent.putExtra("action", "stop"); + PendingIntent stopPendingIntent = PendingIntent.getService(a, 2, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + + Intent openAppIntent = new Intent(a, StreamerActivity.class); + PendingIntent openAppPendingIntent = PendingIntent.getActivity(a, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + + Notification updatedNotification = new Notification.Builder(a, ZryteZenePlay.CHANNEL_ID) + .setContentTitle("ZryteZene") + .setContentText(b ? "Music is playing" : "Paused") + .setSmallIcon(android.R.drawable.ic_media_play) + .setContentIntent(openAppPendingIntent) + .addAction(android.R.drawable.ic_media_previous, "Previous", previousPendingIntent) + .addAction(b ? android.R.drawable.ic_media_pause : android.R.drawable.ic_media_play, b ? "Pause" : "Play", playPausePendingIntent) + .addAction(android.R.drawable.ic_menu_close_clear_cancel, "Stop", stopPendingIntent) + .addAction(android.R.drawable.ic_media_next, "Next", nextPendingIntent) + .setOngoing(true) + .build(); + notificationManager.notify(ZryteZenePlay.NOTIFICATION_ID, updatedNotification); + } } diff --git a/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java b/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java index f560bf4..845ceb3 100644 --- a/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java +++ b/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java @@ -90,14 +90,14 @@ public void onReceive(Context a, Intent b) { ief = new IntentFilter(ACTION_BROADCAST); registerReceiver(br, ief); applyMediaListener(); - tellActivity("Initialization completed"); + tellActivity("on-initialized"); } @Override public void onPrepared(MediaPlayer a) { a.start(); pd = true; - ZryteZeneNotification.update(getApplicationContext(), "Playing music..."); + ZryteZeneNotification.update(getApplicationContext(), true); tellActivity("on-prepared",a.getDuration()); ha.post(pr); } @@ -179,7 +179,7 @@ private void pauseSong() { if (mp==null) return; if (mp.isPlaying()) { mp.pause(); - ZryteZeneNotification.update(getApplicationContext(), "Music paused"); + ZryteZeneNotification.update(getApplicationContext(), false); tellActivity("request-pause"); } } @@ -188,7 +188,7 @@ private void resumeSong() { if (mp==null) return; if (isPrepared() && !mp.isPlaying()) { mp.start(); - ZryteZeneNotification.update(getApplicationContext(), "Playing music..."); + ZryteZeneNotification.update(getApplicationContext(), true); tellActivity("request-resume"); } } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 7853b68..d9e5f99 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -4,4 +4,12 @@ #F50057 #000000 #F50057 + + #6200EE + #3700B3 + #FFFFFF + #121212 + #3700B3 + #FFFFFF + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 516c3fa..d357690 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,19 +1,47 @@ - + + - - + + -