Skip to content

Commit

Permalink
Merge pull request #1182 from Neamar/notification-dot
Browse files Browse the repository at this point in the history
Add notification dot
  • Loading branch information
Neamar authored May 18, 2019
2 parents c2966cd + 082aa85 commit 773c6cf
Show file tree
Hide file tree
Showing 20 changed files with 461 additions and 75 deletions.
8 changes: 8 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@
<service android:name=".dataprovider.ContactsProvider" />
<service android:name=".dataprovider.SettingsProvider" />
<service android:name=".dataprovider.ShortcutsProvider" />

<service android:name=".notification.NotificationListener"
android:enabled="@bool/notification_service_enabled"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
</application>

</manifest>
18 changes: 13 additions & 5 deletions app/src/main/java/fr/neamar/kiss/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

import androidx.annotation.NonNull;

import java.util.ArrayList;

import androidx.annotation.NonNull;
import fr.neamar.kiss.adapter.RecordAdapter;
import fr.neamar.kiss.broadcast.IncomingCallHandler;
import fr.neamar.kiss.forwarder.ForwarderManager;
Expand Down Expand Up @@ -114,7 +115,7 @@ public class MainActivity extends Activity implements QueryInterface, KeyboardSc
* Favorites bar. Can be either the favorites within the KISS bar,
* or the external favorites bar (default)
*/
public View favoritesBar;
public ViewGroup favoritesBar;
/**
* Progress bar displayed when loading
*/
Expand Down Expand Up @@ -414,10 +415,11 @@ protected void onResume() {
super.onResume();
}


@Override
protected void onDestroy() {
super.onDestroy();
this.unregisterReceiver(this.mReceiver);
protected void onPause() {
super.onPause();
forwarderManager.onPause();
}

@Override
Expand All @@ -426,6 +428,12 @@ protected void onStop() {
forwarderManager.onStop();
}

@Override
protected void onDestroy() {
super.onDestroy();
this.unregisterReceiver(this.mReceiver);
}

@Override
protected void onNewIntent(Intent intent) {
// This is called when the user press Home again while already browsing MainActivity
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/java/fr/neamar/kiss/SettingsActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
Expand Down Expand Up @@ -106,6 +105,9 @@ protected void onCreate(Bundle savedInstanceState) {
removePreference("history-hide-section", "pref-hide-navbar");
removePreference("history-hide-section", "pref-hide-statusbar");
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
removePreference("advanced", "enable-notifications");
}

addHiddenTagsTogglesInformation(prefs);
}
Expand Down Expand Up @@ -170,7 +172,7 @@ public void onClick(View v) {
}

private void removePreference(String parent, String category) {
PreferenceCategory p = (PreferenceCategory) findPreference(parent);
PreferenceGroup p = (PreferenceGroup) findPreference(parent);
Preference c = findPreference(category);
p.removePreference(c);
}
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/fr/neamar/kiss/UIColors.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;

public class UIColors {
public static final int COLOR_DEFAULT = 0xFF4caf50;
// Source: https://material.io/guidelines/style/color.html#color-color-palette
Expand Down Expand Up @@ -71,7 +73,7 @@ public static int getPrimaryColor(Context context) {
return primaryColor;
}

public static void clearPrimaryColorCache(Context context) {
static void clearPrimaryColorCache(Context context) {
primaryColor = -1;
}
}
3 changes: 2 additions & 1 deletion app/src/main/java/fr/neamar/kiss/adapter/RecordAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
import android.widget.BaseAdapter;
import android.widget.SectionIndexer;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import androidx.annotation.NonNull;
import fr.neamar.kiss.KissApplication;
import fr.neamar.kiss.normalizer.StringNormalizer;
import fr.neamar.kiss.result.AppResult;
Expand Down
98 changes: 66 additions & 32 deletions app/src/main/java/fr/neamar/kiss/forwarder/Favorites.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.DragEvent;
Expand All @@ -19,13 +22,18 @@
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.NonNull;

import java.util.ArrayList;

import fr.neamar.kiss.KissApplication;
import fr.neamar.kiss.MainActivity;
import fr.neamar.kiss.R;
import fr.neamar.kiss.UIColors;
import fr.neamar.kiss.db.DBHelper;
import fr.neamar.kiss.notification.NotificationListener;
import fr.neamar.kiss.pojo.Pojo;
import fr.neamar.kiss.result.AppResult;
import fr.neamar.kiss.result.ContactsResult;
import fr.neamar.kiss.result.Result;
import fr.neamar.kiss.ui.ListPopup;
Expand All @@ -40,7 +48,7 @@ public class Favorites extends Forwarder implements View.OnClickListener, View.O
/**
* IDs for the favorites buttons
*/
private ArrayList<ImageView> favoritesViews = new ArrayList<>();
private ArrayList<View> favoritesViews = new ArrayList<>();

/**
* Currently displayed favorites
Expand All @@ -66,6 +74,8 @@ public class Favorites extends Forwarder implements View.OnClickListener, View.O
private boolean contextMenuShown = false;
private int favCount = -1;

private SharedPreferences notificationPrefs = null;

Favorites(MainActivity mainActivity) {
super(mainActivity);
}
Expand All @@ -89,6 +99,11 @@ void onCreate() {
// set flag to false
prefs.edit().putBoolean("firstRun", false).apply();
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
notificationPrefs = mainActivity.getSharedPreferences(NotificationListener.NOTIFICATION_PREFERENCES_NAME, Context.MODE_PRIVATE);
}

}

private static Bitmap drawableToBitmap(Drawable drawable) {
Expand Down Expand Up @@ -120,43 +135,67 @@ void onFavoriteChange() {
favCount = favoritesPojo.size();
LayoutInflater layoutInflater = null;

int dotColor;
if (isExternalFavoriteBarEnabled()) {
dotColor = UIColors.getPrimaryColor(mainActivity);
}
else {
dotColor = Color.WHITE;
}

// Don't look for items after favIds length, we won't be able to display them
for (int i = 0; i < favoritesPojo.size(); i++) {
Pojo pojo = favoritesPojo.get(i);

ImageView image;
View favoriteView;

if (favoritesViews.size() <= i) {
if (layoutInflater == null) {
layoutInflater = (LayoutInflater) mainActivity.favoritesBar.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
assert layoutInflater != null;
image = (ImageView) layoutInflater.inflate(R.layout.favorite_item, (ViewGroup) mainActivity.favoritesBar, false);
image.setTag(i);
image.setOnDragListener(this);
image.setOnTouchListener(this);
((ViewGroup) mainActivity.favoritesBar).addView(image);
favoritesViews.add(image);
favoriteView = layoutInflater.inflate(R.layout.favorite_item, (ViewGroup) mainActivity.favoritesBar, false);
favoriteView.setTag(i);
favoriteView.setOnDragListener(this);
favoriteView.setOnTouchListener(this);
mainActivity.favoritesBar.addView(favoriteView);
favoritesViews.add(favoriteView);
} else {
image = (ImageView) favoritesViews.get(i);
favoriteView = favoritesViews.get(i);
}

Pojo pojo = favoritesPojo.get(i);
Result result = Result.fromPojo(mainActivity, pojo);
Drawable drawable = result.getDrawable(mainActivity);
ImageView favoriteImage = favoriteView.findViewById(R.id.favorite);
if (drawable != null) {
if (result instanceof ContactsResult) {
Bitmap iconBitmap = drawableToBitmap(drawable);
drawable = new RoundedQuickContactBadge.RoundedDrawable(iconBitmap);
}
image.setImageDrawable(drawable);
favoriteImage.setImageDrawable(drawable);
} else {
// Use a placeholder if no drawable found
image.setImageResource(R.drawable.ic_launcher_white);
favoriteImage.setImageResource(R.drawable.ic_launcher_white);
}

image.setVisibility(View.VISIBLE);
image.setContentDescription(pojo.getName());
if (notificationPrefs != null) {
ImageView notificationDot = favoriteView.findViewById(R.id.item_notification_dot);
notificationDot.setColorFilter(dotColor);

if (result instanceof AppResult) {
String packageName = ((AppResult) result).getPackageName();
notificationDot.setTag(packageName);
notificationDot.setVisibility(notificationPrefs.contains(packageName) ? View.VISIBLE : View.GONE);
} else {
// Ensure view is clean (might have been recycled after a drag and drop)
notificationDot.setTag(null);
notificationDot.setVisibility(View.GONE);
}

}

favoriteView.setVisibility(View.VISIBLE);
favoriteView.setContentDescription(pojo.getName());
}

// Hide empty favorites (not enough favorites yet)
Expand All @@ -177,7 +216,7 @@ void updateSearchRecords(String query) {

void onDataSetChanged() {
// Do not display the external bar when viewing all apps
if(mainActivity.isViewingAllApps() && isExternalFavoriteBarEnabled()) {
if (mainActivity.isViewingAllApps() && isExternalFavoriteBarEnabled()) {
mainActivity.favoritesBar.setVisibility(View.GONE);
}
}
Expand All @@ -187,7 +226,7 @@ void onDataSetChanged() {
*/
private void addDefaultAppsToFavs() {
{
//Default phone call app
// Default phone call app
Intent phoneIntent = new Intent(Intent.ACTION_DIAL);
phoneIntent.setData(Uri.parse("tel:0000"));
ResolveInfo resolveInfo = mainActivity.getPackageManager().resolveActivity(phoneIntent, PackageManager.MATCH_DEFAULT_ONLY);
Expand All @@ -197,7 +236,7 @@ private void addDefaultAppsToFavs() {

if (resolveInfo.activityInfo.name != null && !resolveInfo.activityInfo.name.equals(DEFAULT_RESOLVER)) {
String activityName = resolveInfo.activityInfo.name;
if(packageName.equals("com.google.android.dialer")) {
if (packageName.equals("com.google.android.dialer")) {
// Default dialer has two different activities, one when calling a phone number and one when opening the app from the launcher.
// (com.google.android.apps.dialer.extensions.GoogleDialtactsActivity vs. com.google.android.dialer.extensions.GoogleDialtactsActivity)
// (notice the .apps. in the middle)
Expand All @@ -212,7 +251,7 @@ private void addDefaultAppsToFavs() {
}
}
{
//Default contacts app
// Default contacts app
Intent contactsIntent = new Intent(Intent.ACTION_DEFAULT, ContactsContract.Contacts.CONTENT_URI);
ResolveInfo resolveInfo = mainActivity.getPackageManager().resolveActivity(contactsIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfo != null) {
Expand All @@ -225,7 +264,7 @@ private void addDefaultAppsToFavs() {

}
{
//Default browser
// Default browser
Intent browserIntent = new Intent("android.intent.action.VIEW", Uri.parse("http://"));
ResolveInfo resolveInfo = mainActivity.getPackageManager().resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfo != null) {
Expand All @@ -234,7 +273,7 @@ private void addDefaultAppsToFavs() {

if (resolveInfo.activityInfo.name != null && !resolveInfo.activityInfo.name.equals(DEFAULT_RESOLVER)) {
String activityName = resolveInfo.activityInfo.name;
if(packageName.equalsIgnoreCase("com.android.chrome")) {
if (packageName.equalsIgnoreCase("com.android.chrome")) {
// Chrome has two different activities, one for Launcher and one when opening an URL.
// The browserIntent above resolve to the latter, which isn't exposed as a Launcher activity and thus can't be displayed
// This hack uses the correct resolver when the application is Chrome.
Expand All @@ -248,13 +287,8 @@ private void addDefaultAppsToFavs() {
}
}

@NonNull
private Result getFavResult(int favNumber) {
if (favNumber >= favoritesPojo.size()) {
// Clicking on a favorite before everything is loaded.
Log.i(TAG, "Clicking on an uninitialized favorite.");
return null;
}

// Favorites handling
Pojo pojo = favoritesPojo.get(favNumber);
return Result.fromPojo(mainActivity, pojo);
Expand Down Expand Up @@ -292,7 +326,7 @@ public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
// No need to do the extra work
if(isDragging) {
if (isDragging) {
return true;
}

Expand All @@ -302,7 +336,7 @@ public boolean onTouch(View view, MotionEvent motionEvent) {
this.onClick(view);
return true;
}
if(!contextMenuShown && holdTime > LONG_PRESS_DELAY) {
if (!contextMenuShown && holdTime > LONG_PRESS_DELAY) {
contextMenuShown = true;
this.onLongClick(view);
return true;
Expand Down Expand Up @@ -352,7 +386,7 @@ public boolean onDrag(View v, final DragEvent event) {

case DragEvent.ACTION_DRAG_ENDED:
// Only need to handle this action once.
if(!isDragging) {
if (!isDragging) {
return true;
}
isDragging = false;
Expand Down Expand Up @@ -386,8 +420,8 @@ public void run() {

final int pos = KissApplication.getApplication(mainActivity).getDataHandler().getFavoritePosition(mainActivity, overApp.id);
draggedView.post(new Runnable() {
@Override
public void run() {
@Override
public void run() {
// Signals to a View that the drag and drop operation has concluded.
// If event result is set, this means the dragged view was dropped in target
if (event.getResult()) {
Expand Down
Loading

0 comments on commit 773c6cf

Please sign in to comment.