diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a1..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 15a15b2..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 2996d53..d291b3d 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -9,6 +9,7 @@ diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml deleted file mode 100644 index f2aa065..0000000 --- a/.idea/markdown-navigator.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml deleted file mode 100644 index db06266..0000000 --- a/.idea/markdown-navigator/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 51b39f7..dfd2c79 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,41 +1,6 @@ - - - - - + diff --git a/.idea/render.experimental.xml b/.idea/render.experimental.xml deleted file mode 100644 index 8ec256a..0000000 --- a/.idea/render.experimental.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index b7a4e58..f9e1bad 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 defaultConfig { applicationId "com.RichardLuo.notificationpush" minSdkVersion 21 - targetSdkVersion 28 - versionCode 24 - versionName "1.1.3(4)" + targetSdkVersion 29 + versionCode 25 + versionName "1.1.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -20,12 +20,13 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'com.google.android.material:material:1.2.0-alpha02' implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.media:media:1.1.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.google.firebase:firebase-core:17.2.0' - implementation 'com.google.firebase:firebase-messaging:20.0.0' + implementation 'com.google.firebase:firebase-core:17.2.1' + implementation 'com.google.firebase:firebase-messaging:20.0.1' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/app/release/app-release.apk b/app/release/app-release.apk index dec4ba1..d5f3766 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/release/output.json b/app/release/output.json index b3b48e9..b273f2e 100644 --- a/app/release/output.json +++ b/app/release/output.json @@ -1 +1 @@ -[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":24,"versionName":"1.1.3(4)","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] \ No newline at end of file +[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":25,"versionName":"1.1.4","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 55ae406..17ef367 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="com.RichardLuo.notificationpush"> + + android:theme="@style/base.DayNight.AppTheme_teal"> @@ -24,10 +25,17 @@ + + + + packageInfo; + List displayItem = new ArrayList<>(); + List tempItem; + Info[] displayInfo; + + class ViewHolder { + TextView text; + ImageView icon; + AppCompatAutoCompleteTextView act; + } + + class Info { + String text; + Drawable icon; + AdapterView.OnItemClickListener onItemClickListener; + int selection; + + Info(final ApplicationInfo applicationInfo) { + text = getPackageManager().getApplicationLabel(applicationInfo).toString(); + icon = getPackageManager().getApplicationIcon(applicationInfo); + selection = preferences.getInt(applicationInfo.packageName, preferences.contains("allOff") ? 2 : 0); + + onItemClickListener = new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + if (position == 0 && !preferences.contains("allOff")) { + preferences.edit().remove(applicationInfo.packageName).apply(); + return; + } else if (position == 2 && preferences.contains("allOff")) + return; + preferences.edit().putInt(applicationInfo.packageName, position).apply(); + } + }; + } + } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setTheme(getSharedPreferences("MainActivity", MODE_PRIVATE).getInt("style", R.style.base_AppTheme_teal)); + setTheme(getSharedPreferences("MainActivity", MODE_PRIVATE).getInt("style", R.style.base_DayNight_AppTheme_teal)); setContentView(R.layout.activity_application); Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); - preferences = getPreferences(MODE_PRIVATE); listView = findViewById(R.id.listview); progressBar = findViewById(R.id.progressBar); - final PackageManager packageManager = getPackageManager(); - final List packageInfo = packageManager.getInstalledApplications(0); + preferences = getPreferences(MODE_PRIVATE); + + listView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + listView.setFitsSystemWindows(true); +// final ActionBar actionBar = getSupportActionBar(); +//// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +//// listView.setOnScrollChangeListener(new View.OnScrollChangeListener() { +//// boolean lastScrollinTop = true; +//// ValueAnimator animation = ValueAnimator.ofInt(0, 8); +//// +//// { +//// animation.setDuration(400); +//// animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { +//// @Override +//// public void onAnimationUpdate(ValueAnimator animation) { +//// actionBar.setElevation((int) animation.getAnimatedValue()); +//// } +//// }); +//// } +//// +//// @Override +//// public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { +//// if (!v.canScrollVertically(-1) && !lastScrollinTop) { +//// animation.reverse(); +//// lastScrollinTop = true; +//// } else if (lastScrollinTop) { +//// animation.start(); +//// lastScrollinTop = false; +//// } +//// } +//// }); +//// } else +//// actionBar.setElevation(8); + + final String[] priorityContent = getApplicationContext().getResources().getStringArray(R.array.priorityContent); + final ArrayAdapter actAdapter = new ArrayAdapter<>(getApplicationContext(), R.layout.dropdown, priorityContent); + packageManager = getPackageManager(); + packageInfo = packageManager.getInstalledApplications(0); + new Thread() { + @Override + public void run() { + Collections.sort(packageInfo, new ApplicationInfo.DisplayNameComparator(packageManager)); + super.run(); + } + }.start(); + displayInfo = new Info[packageInfo.size()]; + + ba = new BaseAdapter() { + private int lastPosition = -1; + + @Override + public int getCount() { + return displayItem.size(); + } + + @Override + public Object getItem(int position) { + return displayItem.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public void notifyDataSetChanged() { + displayInfo = new Info[packageInfo.size()]; + lastPosition = -1; + super.notifyDataSetChanged(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder; + Info info; + if (displayInfo[position] == null) + displayInfo[position] = (info = new Info(displayItem.get(position))); + else + info = displayInfo[position]; + if (convertView == null) { + convertView = LayoutInflater.from(getBaseContext()).inflate(R.layout.app_layout, listView, false); + holder = new ViewHolder(); + holder.text = convertView.findViewById(R.id.appName); + holder.icon = convertView.findViewById(R.id.imageView); + holder.act = convertView.findViewById(R.id.priority); + holder.act.setAdapter(actAdapter); + holder.act.setKeyListener(null); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + holder.text.setText(info.text); + holder.icon.setImageDrawable(info.icon); + holder.act.setOnItemClickListener(info.onItemClickListener); + holder.act.setText(priorityContent[info.selection], false); + convertView.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top)); + lastPosition = position; + return convertView; + } + }; + + refreshListData(new Runnable() { + @Override + public void run() { + listView.setAdapter(ba); + } + }); + } + + public void refreshListData(final Runnable update) { + progressBar.setVisibility(View.VISIBLE); - update = new Runnable() { + new Thread() { @Override public void run() { - final List packageView = new ArrayList<>(); - for (final ApplicationInfo applicationInfo : packageInfo) { - if (filterSystemApp && !((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)) - continue; - final String name = packageManager.getApplicationLabel(applicationInfo).toString(); - Spinner.OnItemSelectedListener onItemSelectedListener = new Spinner.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - if (position == 0) { - preferences.edit().remove(applicationInfo.packageName).apply(); - return; - } - preferences.edit().putInt(applicationInfo.packageName, position).apply(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - - } - }; - packageView.add(new info(name, packageManager.getApplicationIcon(applicationInfo), onItemSelectedListener, preferences.getInt(applicationInfo.packageName, 0))); + if (filterSystemApp || (searchText != null && !searchText.equals(""))) { + if (displayItem == packageInfo) + displayItem = tempItem; + displayItem.clear(); + for (ApplicationInfo applicationInfo : packageInfo) { + if (filterSystemApp && !((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)) + continue; + + // 判断search Text + if ((searchText != null && !searchText.equals("")) && !packageManager.getApplicationLabel(applicationInfo).toString().contains(searchText)) + continue; + + displayItem.add(applicationInfo); + } + } else if (displayItem != packageInfo) { + tempItem = displayItem; + displayItem = packageInfo; } - handler.post(new Runnable() { + runOnUiThread(new Runnable() { @Override public void run() { - listView.setAdapter(new BaseAdapter() { - @Override - public int getCount() { - return packageView.size(); - } - - @Override - public Object getItem(int position) { - return packageView.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - ViewHolder holder; - info info = packageView.get(position); - if (convertView == null) { - convertView = LayoutInflater.from(getBaseContext()).inflate(R.layout.app_layout, listView, false); - holder = new ViewHolder(); - holder.text = convertView.findViewById(R.id.appName); - holder.icon = convertView.findViewById(R.id.imageView); - holder.spinner = convertView.findViewById(R.id.spinner); - convertView.setTag(holder); - } else { - holder = (ViewHolder) convertView.getTag(); - } - holder.text.setText(info.text); - holder.icon.setImageDrawable(info.icon); - holder.spinner.setSelection(info.selection); - holder.spinner.setOnItemSelectedListener(info.onItemSelectedListener); - return convertView; - } - }); + update.run(); progressBar.setVisibility(View.GONE); } }); + super.run(); } + }.start(); + } - class ViewHolder { - TextView text; - ImageView icon; - Spinner spinner; + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.appmenu, menu); + + SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); + MenuItem searchMenu = menu.findItem(R.id.search); + searchMenu.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem menuItem) { + return true; } - class info { - String text; - Drawable icon; - Spinner.OnItemSelectedListener onItemSelectedListener; - int selection; - - info(String text, Drawable icon, Spinner.OnItemSelectedListener onItemSelectedListener, int selection) { - this.text = text; - this.icon = icon; - this.onItemSelectedListener = onItemSelectedListener; - this.selection = selection; + @Override + public boolean onMenuItemActionCollapse(MenuItem menuItem) { + if (searchText != null) { + searchText = null; + refreshListData(notifyDataSet); } + return true; } - }; - new Thread(update).start(); - } + }); + SearchView searchView = (SearchView) searchMenu.getActionView(); + searchView.setSearchableInfo(Objects.requireNonNull(searchManager).getSearchableInfo(getComponentName())); + searchView.setIconifiedByDefault(false); - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.appmenu, menu); + if (preferences.contains("allOff")) + menu.findItem(R.id.reverse).setTitle(getString(R.string.positive)); return true; } @@ -153,9 +279,28 @@ public boolean onOptionsItemSelected(MenuItem item) { break; case R.id.filter: filterSystemApp = !filterSystemApp; - new Thread(update).start(); + refreshListData(notifyDataSet); + break; + case R.id.reverse: + if (!preferences.contains("allOff")) { + preferences.edit().clear().putInt("allOff", 0).apply(); + item.setTitle(getString(R.string.positive)); + } else { + preferences.edit().remove("allOff").apply(); + item.setTitle(getString(R.string.reverse)); + } + refreshListData(notifyDataSet); break; } return true; } + + @Override + protected void onNewIntent(Intent intent) { + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + searchText = intent.getStringExtra(SearchManager.QUERY); + refreshListData(notifyDataSet); + } + super.onNewIntent(intent); + } } diff --git a/app/src/main/java/com/RichardLuo/notificationpush/FCMReceiver.java b/app/src/main/java/com/RichardLuo/notificationpush/FCMReceiver.java index 1008332..69fda18 100644 --- a/app/src/main/java/com/RichardLuo/notificationpush/FCMReceiver.java +++ b/app/src/main/java/com/RichardLuo/notificationpush/FCMReceiver.java @@ -45,10 +45,12 @@ public class FCMReceiver extends FirebaseMessagingService { static Map Package_Intent = new HashMap<>(); int color = 0; + Boolean ringForEach; NotificationManagerCompat notificationManagerCompat; @Override public void onCreate() { + ringForEach = getSharedPreferences("MainActivity", MODE_PRIVATE).getBoolean("ringForEach", false); notificationManagerCompat = NotificationManagerCompat.from(this); super.onCreate(); } @@ -166,7 +168,7 @@ public void onMessageReceived(RemoteMessage remoteMessage) { .setGroup(packageName) .setContentIntent(intent) .setAutoCancel(true) - .setOnlyAlertOnce(true) + .setOnlyAlertOnce(!ringForEach) .build(); notificationManagerCompat.notify(packageName, id, notification); } @@ -206,7 +208,7 @@ private boolean isAppInstalled(String packageName) { return false; } List applicationInfo = getPackageManager().getInstalledApplications(0); - if (applicationInfo == null || applicationInfo.isEmpty()) + if (applicationInfo.isEmpty()) return false; for (ApplicationInfo info : applicationInfo) { if (packageName.equals(info.packageName) && info.enabled) { @@ -220,12 +222,11 @@ public void setChannel(String AppName) { NotificationChannel mChannel; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !getSharedPreferences("Channels", MODE_PRIVATE).contains(AppName)) { mChannel = new NotificationChannel(AppName, AppName, IMPORTANCE_DEFAULT); - getSystemService(NotificationManager.class).createNotificationChannel(mChannel); + Objects.requireNonNull(getSystemService(NotificationManager.class)).createNotificationChannel(mChannel); getSharedPreferences("Channels", MODE_PRIVATE).edit().putBoolean(AppName, true).apply(); } } - @SuppressWarnings("ConstantConditions") private PendingIntent getIntent(String packageName) { PendingIntent intent = null; if (Package_Intent.containsKey(packageName)) { @@ -246,7 +247,7 @@ private PendingIntent getIntent(String packageName) { private Notification getCurrentNotification(String packageName, int id) { StatusBarNotification[] sbns; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) - sbns = getSystemService(NotificationManager.class).getActiveNotifications(); + sbns = Objects.requireNonNull(getSystemService(NotificationManager.class)).getActiveNotifications(); else return null; for (StatusBarNotification sbn : sbns) { @@ -305,7 +306,7 @@ private void MessagingStyle(String packageName, String AppName, String title, St notification.setGroup(packageName) .setContentIntent(intent) .setAutoCancel(true) - .setOnlyAlertOnce(true); + .setOnlyAlertOnce(!ringForEach); notificationManagerCompat.notify(packageName, ID, notification.build()); } } diff --git a/app/src/main/java/com/RichardLuo/notificationpush/GetNotification.java b/app/src/main/java/com/RichardLuo/notificationpush/GetNotification.java index f714c04..95195c3 100644 --- a/app/src/main/java/com/RichardLuo/notificationpush/GetNotification.java +++ b/app/src/main/java/com/RichardLuo/notificationpush/GetNotification.java @@ -1,6 +1,8 @@ package com.RichardLuo.notificationpush; import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.StrictMode; @@ -8,14 +10,18 @@ import android.service.notification.StatusBarNotification; import android.util.Log; +import androidx.core.app.NotificationCompat; + import org.json.JSONObject; import java.io.DataOutputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.preference.PreferenceManager.getDefaultSharedPreferences; public class GetNotification extends NotificationListenerService { @@ -29,6 +35,28 @@ public void onCreate() { inputID = getDefaultSharedPreferences(this).getString("input", ""); pm = getPackageManager(); StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build()); + if (getDefaultSharedPreferences(getApplicationContext()).getBoolean("startForeground", false)) { + NotificationChannel mChannel; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + mChannel = new NotificationChannel("Foreground", "前台服务", IMPORTANCE_DEFAULT); + Objects.requireNonNull(getSystemService(NotificationManager.class)).createNotificationChannel(mChannel); + } + Notification foregroundNotice = new NotificationCompat.Builder(this, "Foreground") + .setSmallIcon(R.drawable.ic_notification) + .setColor(getResources().getColor(getSharedPreferences("MainActivity", MODE_PRIVATE).getInt("color", R.color.teal))) + .setContentTitle("后台转发通知中") + .setContentText("转发中") + .build(); + startForeground(1, foregroundNotice); + } + } + + @Override + public void onDestroy() { + if (getDefaultSharedPreferences(getApplicationContext()).getBoolean("startForeground", false)) { + stopForeground(true); + } + super.onDestroy(); } @Override @@ -58,7 +86,8 @@ public void run() { if (getDefaultSharedPreferences(getApplicationContext()).getBoolean("hide_no_content", false) && title.equals("无标题") && body.equals("无内容")) return; - switch (getSharedPreferences("Application", MODE_PRIVATE).getInt(packageName, 0)) { + SharedPreferences appPreference = getSharedPreferences("Application", MODE_PRIVATE); + switch (appPreference.getInt(packageName, appPreference.contains("allOff") ? 2 : 0)) { case 0: priority = "normal"; break; @@ -85,16 +114,17 @@ public void run() { if (matcher.find()) { senderName = matcher.group(1); title = matcher.group(2); - body = matcher.group(4).trim(); + body = Objects.requireNonNull(matcher.group(4)).trim(); } else { String[] single = tickerText.split(":", 2); senderName = single[0]; title = single[0]; - body = single[1].trim(); + if (single.length > 1) + body = single[1].trim(); } - ID = StringToA(title); - } else - return; + if (title != null) + ID = StringToA(title); + } } } diff --git a/app/src/main/java/com/RichardLuo/notificationpush/MainActivity.java b/app/src/main/java/com/RichardLuo/notificationpush/MainActivity.java index dfeec1d..8a4511b 100644 --- a/app/src/main/java/com/RichardLuo/notificationpush/MainActivity.java +++ b/app/src/main/java/com/RichardLuo/notificationpush/MainActivity.java @@ -13,6 +13,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import java.util.List; public class MainActivity extends AppCompatActivity { @@ -24,7 +26,7 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); preferences = getPreferences(MODE_PRIVATE); - setTheme(preferences.getInt("style", R.style.base_AppTheme_teal)); + setTheme(preferences.getInt("style", R.style.base_DayNight_AppTheme_teal)); setContentView(R.layout.activity_main); getSupportFragmentManager().beginTransaction() .replace(R.id.preference, new Preferences()) @@ -57,38 +59,38 @@ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.color: final String[] items = {"水鸭青", "姨妈红", "哔哩粉", "基佬紫", "很深蓝", "非常黄", "真的灰"}; - AlertDialog.Builder listDialog = new AlertDialog.Builder(this); + AlertDialog.Builder listDialog = new MaterialAlertDialogBuilder(this); listDialog.setTitle("选择颜色"); listDialog.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int click) { switch (click) { case 0: - preferences.edit().putInt("style", R.style.base_AppTheme_teal).apply(); + preferences.edit().putInt("style", R.style.base_DayNight_AppTheme_teal).apply(); preferences.edit().putInt("color", R.color.teal).apply(); break; case 1: - preferences.edit().putInt("style", R.style.base_AppTheme_red).apply(); + preferences.edit().putInt("style", R.style.base_DayNight_AppTheme_red).apply(); preferences.edit().putInt("color", R.color.red).apply(); break; case 2: - preferences.edit().putInt("style", R.style.base_AppTheme_pink).apply(); + preferences.edit().putInt("style", R.style.base_DayNight_AppTheme_pink).apply(); preferences.edit().putInt("color", R.color.pink).apply(); break; case 3: - preferences.edit().putInt("style", R.style.base_AppTheme_purple).apply(); + preferences.edit().putInt("style", R.style.base_DayNight_AppTheme_purple).apply(); preferences.edit().putInt("color", R.color.purple).apply(); break; case 4: - preferences.edit().putInt("style", R.style.base_AppTheme_blue).apply(); + preferences.edit().putInt("style", R.style.base_DayNight_AppTheme_blue).apply(); preferences.edit().putInt("color", R.color.blue).apply(); break; case 5: - preferences.edit().putInt("style", R.style.base_AppTheme_yellow).apply(); + preferences.edit().putInt("style", R.style.base_DayNight_AppTheme_yellow).apply(); preferences.edit().putInt("color", R.color.yellow).apply(); break; case 6: - preferences.edit().putInt("style", R.style.base_AppTheme_grey).apply(); + preferences.edit().putInt("style", R.style.base_DayNight_AppTheme_grey).apply(); preferences.edit().putInt("color", R.color.grey).apply(); break; } @@ -98,7 +100,7 @@ public void onClick(DialogInterface dialog, int click) { listDialog.show(); break; case R.id.about: - final AlertDialog.Builder normalDialog = new AlertDialog.Builder(this); + final AlertDialog.Builder normalDialog = new MaterialAlertDialogBuilder(this); normalDialog.setTitle("关于"); normalDialog.setMessage(getResources().getString(R.string.HowToUse)); normalDialog.setPositiveButton("捐赠", new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/com/RichardLuo/notificationpush/Preferences.java b/app/src/main/java/com/RichardLuo/notificationpush/Preferences.java index 12c6d2e..824de38 100644 --- a/app/src/main/java/com/RichardLuo/notificationpush/Preferences.java +++ b/app/src/main/java/com/RichardLuo/notificationpush/Preferences.java @@ -1,5 +1,6 @@ package com.RichardLuo.notificationpush; +import android.animation.ValueAnimator; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.ProgressDialog; @@ -17,10 +18,17 @@ import android.text.Html; import android.text.TextUtils; import android.util.Log; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.CheckBoxPreference; import androidx.preference.EditTextPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; @@ -28,6 +36,7 @@ import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.InstanceIdResult; @@ -58,18 +67,6 @@ public class Preferences extends PreferenceFragmentCompat { public void onCreatePreferences(Bundle bundle, String s) { setPreferencesFromResource(R.xml.preference, null); preferences = getDefaultSharedPreferences(Objects.requireNonNull(getActivity())); - FirebaseInstanceId.getInstance().getInstanceId() - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - if (!task.isSuccessful()) { - token = "fail"; - Toast.makeText(getActivity(), "获取token失败", Toast.LENGTH_SHORT).show(); - return; - } - token = Objects.requireNonNull(task.getResult()).getToken(); - } - }); start = findPreference("start"); Objects.requireNonNull(start).setOnPreferenceClickListener(new SwitchPreference.OnPreferenceClickListener() { @@ -87,15 +84,25 @@ public boolean onPreferenceClick(Preference preference) { } }); + CheckBoxPreference startForeground = findPreference("startForeground"); + Objects.requireNonNull(startForeground).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (start.isChecked()) + Toast.makeText(getActivity(), "请重启通知监听", Toast.LENGTH_SHORT).show(); + return false; + } + }); + input = findPreference("input"); Preference logcat = findPreference("logcat"); Objects.requireNonNull(logcat).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - AlertDialog.Builder log = new AlertDialog.Builder(Objects.requireNonNull(getContext())); + AlertDialog.Builder log = new MaterialAlertDialogBuilder(Objects.requireNonNull(getContext())); log.setTitle("Log"); - ByteArrayOutputStream result = new ByteArrayOutputStream(); + final ByteArrayOutputStream result = new ByteArrayOutputStream(); try { InputStream is = Runtime.getRuntime().exec(new String[]{"logcat", "-d", "*:E"}).getInputStream(); byte[] buffer = new byte[1024]; @@ -114,7 +121,7 @@ public void run() { log.setPositiveButton("复制", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - ((ClipboardManager) Objects.requireNonNull(getActivity()).getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("token", token)); + ((ClipboardManager) Objects.requireNonNull(Objects.requireNonNull(getActivity()).getSystemService(Context.CLIPBOARD_SERVICE))).setPrimaryClip(ClipData.newPlainText("token", result.toString())); Toast.makeText(getActivity(), "复制成功", Toast.LENGTH_SHORT).show(); } }); @@ -139,13 +146,13 @@ public boolean onPreferenceClick(Preference preference) { Objects.requireNonNull(tokenPreference).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - final AlertDialog.Builder normalDialog = new AlertDialog.Builder(Objects.requireNonNull(getContext())); + final AlertDialog.Builder normalDialog = new MaterialAlertDialogBuilder(Objects.requireNonNull(getContext())); normalDialog.setTitle("Token"); normalDialog.setMessage(token); normalDialog.setPositiveButton("复制", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - ((ClipboardManager) Objects.requireNonNull(getActivity()).getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("token", token)); + ((ClipboardManager) Objects.requireNonNull(Objects.requireNonNull(getActivity()).getSystemService(Context.CLIPBOARD_SERVICE))).setPrimaryClip(ClipData.newPlainText("token", token)); Toast.makeText(getActivity(), "复制成功", Toast.LENGTH_SHORT).show(); } }); @@ -175,7 +182,7 @@ public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { final NotificationManager notificationManager = Objects.requireNonNull(getContext()).getSystemService(NotificationManager.class); - for (NotificationChannel channel : notificationManager.getNotificationChannels()) { + for (NotificationChannel channel : Objects.requireNonNull(notificationManager).getNotificationChannels()) { notificationManager.deleteNotificationChannel(channel.getId()); } } @@ -186,6 +193,57 @@ public boolean onPreferenceClick(Preference preference) { }); } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + FirebaseInstanceId.getInstance().getInstanceId() + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (!task.isSuccessful()) { + token = "fail"; + if (getActivity() != null) + Toast.makeText(getActivity(), "获取token失败", Toast.LENGTH_SHORT).show(); + return; + } + token = Objects.requireNonNull(task.getResult()).getToken(); + } + }); + + getListView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); + getListView().setFitsSystemWindows(true); +// +// final ActionBar actionBar = Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar()); +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// getListView().setOnScrollChangeListener(new View.OnScrollChangeListener() { +// boolean lastScrollinTop = true; +// ValueAnimator animation = ValueAnimator.ofInt(0, 8); +// +// { +// animation.setDuration(400); +// animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { +// @Override +// public void onAnimationUpdate(ValueAnimator animation) { +// actionBar.setElevation((int) animation.getAnimatedValue()); +// } +// }); +// } +// +// @Override +// public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { +// if (!v.canScrollVertically(-1) && !lastScrollinTop) { +// animation.reverse(); +// lastScrollinTop = true; +// } else if (lastScrollinTop) { +// animation.start(); +// lastScrollinTop = false; +// } +// } +// }); +// } else +// actionBar.setElevation(8); + } + @Override public void onStart() { super.onStart(); @@ -222,7 +280,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { final long bkn = GetBkn(skey); final SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(Objects.requireNonNull(getContext()).getDatabasePath("friends.db"), null); - AlertDialog.Builder listDialog = new AlertDialog.Builder(Objects.requireNonNull(getActivity())); + AlertDialog.Builder listDialog = new MaterialAlertDialogBuilder(Objects.requireNonNull(getActivity())); listDialog.setTitle("你需要同步"); listDialog.setItems(new String[]{"好友", "群组"}, new DialogInterface.OnClickListener() { @Override @@ -306,7 +364,7 @@ public void run() { getActivity().runOnUiThread(new Runnable() { public void run() { final ArrayList choices = new ArrayList<>(); - AlertDialog.Builder ChoiceDialog = new AlertDialog.Builder(getActivity()); + AlertDialog.Builder ChoiceDialog = new MaterialAlertDialogBuilder(getActivity()); ChoiceDialog.setTitle("选择要同步的群组"); ChoiceDialog.setMultiChoiceItems(groupNames, null, new DialogInterface.OnMultiChoiceClickListener() { @Override diff --git a/app/src/main/java/com/RichardLuo/notificationpush/QQLogin.java b/app/src/main/java/com/RichardLuo/notificationpush/QQLogin.java index 17d32a9..b65dd70 100644 --- a/app/src/main/java/com/RichardLuo/notificationpush/QQLogin.java +++ b/app/src/main/java/com/RichardLuo/notificationpush/QQLogin.java @@ -23,7 +23,7 @@ public class QQLogin extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setTheme(getSharedPreferences("MainActivity", MODE_PRIVATE).getInt("style", R.style.base_AppTheme_teal)); + setTheme(getSharedPreferences("MainActivity", MODE_PRIVATE).getInt("style", R.style.base_DayNight_AppTheme_teal)); setContentView(R.layout.qq_login); Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); diff --git a/app/src/main/res/anim/down_from_top.xml b/app/src/main/res/anim/down_from_top.xml new file mode 100644 index 0000000..8e7e395 --- /dev/null +++ b/app/src/main/res/anim/down_from_top.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/up_from_bottom.xml b/app/src/main/res/anim/up_from_bottom.xml new file mode 100644 index 0000000..c368b1f --- /dev/null +++ b/app/src/main/res/anim/up_from_bottom.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi/ic_reverse.xml b/app/src/main/res/drawable-anydpi/ic_reverse.xml new file mode 100644 index 0000000..0093037 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_reverse.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_search.xml b/app/src/main/res/drawable-anydpi/ic_search.xml new file mode 100644 index 0000000..be58917 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_search.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable-hdpi/ic_reverse.png b/app/src/main/res/drawable-hdpi/ic_reverse.png new file mode 100644 index 0000000..2c887aa Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_reverse.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_search.png b/app/src/main/res/drawable-hdpi/ic_search.png new file mode 100644 index 0000000..638a6c0 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_search.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_reverse.png b/app/src/main/res/drawable-mdpi/ic_reverse.png new file mode 100644 index 0000000..d229581 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_reverse.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_search.png b/app/src/main/res/drawable-mdpi/ic_search.png new file mode 100644 index 0000000..c1f36d3 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_search.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_reverse.png b/app/src/main/res/drawable-xhdpi/ic_reverse.png new file mode 100644 index 0000000..a2c556b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_reverse.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_search.png b/app/src/main/res/drawable-xhdpi/ic_search.png new file mode 100644 index 0000000..a722729 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_search.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_reverse.png b/app/src/main/res/drawable-xxhdpi/ic_reverse.png new file mode 100644 index 0000000..34cc8ea Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_reverse.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_search.png b/app/src/main/res/drawable-xxhdpi/ic_search.png new file mode 100644 index 0000000..9317672 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_search.png differ diff --git a/app/src/main/res/layout/activity_application.xml b/app/src/main/res/layout/activity_application.xml index b9b6ea6..741c10d 100644 --- a/app/src/main/res/layout/activity_application.xml +++ b/app/src/main/res/layout/activity_application.xml @@ -1,18 +1,19 @@ + + android:layout_height="match_parent"> + android:layout_height="match_parent" + android:clipToPadding="false" + android:divider="@null" /> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 804e1d2..f418223 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,6 @@ android:id="@+id/preference" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/colorPrimary" android:orientation="vertical" tools:context=".MainActivity"> diff --git a/app/src/main/res/layout/app_layout.xml b/app/src/main/res/layout/app_layout.xml index f362bc8..708811c 100644 --- a/app/src/main/res/layout/app_layout.xml +++ b/app/src/main/res/layout/app_layout.xml @@ -6,31 +6,45 @@ android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true" - android:orientation="horizontal" - android:paddingTop="20dp" - android:paddingBottom="20dp"> + android:orientation="horizontal"> + android:layout_width="36dp" + android:layout_height="36dp" + android:layout_margin="10dp" + tools:srcCompat="@tools:sample/avatars" + tools:ignore="ContentDescription" /> + android:textColor="@color/black" + android:textSize="14sp" + tools:ignore="InefficientWeight" /> - + android:layout_gravity="center" + android:layout_marginEnd="10dp"> + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dropdown.xml b/app/src/main/res/layout/dropdown.xml new file mode 100644 index 0000000..c52abad --- /dev/null +++ b/app/src/main/res/layout/dropdown.xml @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/app/src/main/res/menu/appmenu.xml b/app/src/main/res/menu/appmenu.xml index b8805b5..49974bd 100644 --- a/app/src/main/res/menu/appmenu.xml +++ b/app/src/main/res/menu/appmenu.xml @@ -1,10 +1,22 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu.xml b/app/src/main/res/menu/menu.xml index 1a70932..c7d8f77 100644 --- a/app/src/main/res/menu/menu.xml +++ b/app/src/main/res/menu/menu.xml @@ -1,9 +1,12 @@ - + \ No newline at end of file diff --git a/app/src/main/res/menu/webmenu.xml b/app/src/main/res/menu/webmenu.xml index c7412c3..d1bca6e 100644 --- a/app/src/main/res/menu/webmenu.xml +++ b/app/src/main/res/menu/webmenu.xml @@ -1,9 +1,12 @@ - + + android:title="@string/clear_cookies" + app:iconTint="@color/black" /> + android:title="@string/refresh" + app:iconTint="@color/black" /> \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 6aee6ee..03b2674 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -7,4 +7,9 @@ #7986cb #ffd54f #90a4ae + + #000000 + #ffffff + + #cc000000 \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 28e4e85..f851b8a 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -1,23 +1,29 @@ - --> + + + + + + + + - \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index b0a46df..c027c4f 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -39,4 +39,11 @@ 刷新 Logcat 过滤系统app + 以前台服务形式启动 + 增大服务存活率 + 关闭全部应用通知 + 开启全部提示音 + 每一条通知都将会有提示音 + 搜索 + 重置为正常优先级 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 6158a28..77865b5 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -10,4 +10,6 @@ #EAEAEA #000000 + + #ccffffff diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fb4972e..976469b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,4 +38,11 @@ Refresh Logcat exclude system app + Start Foreground service + To keep alive + close all Notification + Alert every time + Alert for every notice + search + reset to normal diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index bcfc6c6..66f76b4 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,60 +1,64 @@ - - - - - - - - - - diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml index bb5b820..cf9bf93 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference.xml @@ -5,6 +5,11 @@ + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index c28d30b..70b8926 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.1' - classpath 'com.google.gms:google-services:4.3.2' + classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.google.gms:google-services:4.3.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradlew b/gradlew old mode 100755 new mode 100644