Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
e
os
BlissLauncher
Commits
8f67f67b
Commit
8f67f67b
authored
Mar 21, 2018
by
Amit Kumar
Browse files
Add notification badge feature
parent
4d6bc580
Changes
24
Expand all
Hide whitespace changes
Inline
Side-by-side
app/src/main/AndroidManifest.xml
View file @
8f67f67b
...
...
@@ -5,6 +5,25 @@
<uses-permission
android:name=
"android.permission.SET_WALLPAPER"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.READ_CONTACTS"
/>
<uses-permission
android:name=
"android.permission.READ_CALL_LOG"
/>
<uses-permission
android:name=
"android.permission.READ_SMS"
/>
<uses-permission
android:name=
"android.permission.GET_ACCOUNTS"
/>
<uses-permission
android:name=
"com.android.email.permission.ACCESS_PROVIDER"
/>
<uses-permission
android:name=
"com.google.android.gm.permission.READ_CONTENT_PROVIDER"
/>
<uses-permission
android:name=
"com.sec.android.provider.badge.permission.READ"
/>
<uses-permission
android:name=
"com.fsck.k9.permission.READ_MESSAGES"
/>
<uses-permission
android:name=
"com.kaitenmail.permission.READ_MESSAGES"
/>
<uses-permission
android:name=
"com.kaitenmail.adsupported.permission.READ_MESSAGES"
/>
<uses-permission
android:name=
"android.intent.action.BADGE_COUNT_UPDATE"
/>
<uses-permission
android:name=
"android.permission.RECEIVE_BOOT_COMPLETED"
/>
<uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
<uses-permission
android:name=
"android.permission.ACCESS_WIFI_STATE"
/>
<uses-permission
android:name=
"android.permission.READ_PHONE_STATE"
/>
<uses-permission
android:name=
"android.email.permission.READ_ATTACHMENT"
/>
<uses-permission
android:name=
"android.email.permission.ACCESS_PROVIDER"
/>
<uses-permission
android:name=
"android.permission.RECEIVE_SMS"
/>
<application
android:name=
".BlissLauncher"
android:allowBackup=
"true"
...
...
@@ -14,7 +33,7 @@
android:supportsRtl=
"true"
android:theme=
"@style/AppTheme"
>
<activity
android:name=
".ui.
Desktop
Activity"
android:name=
".ui.
Launcher
Activity"
android:clearTaskOnLaunch=
"true"
android:launchMode=
"singleTask"
android:screenOrientation=
"nosensor"
...
...
@@ -28,9 +47,20 @@
<category
android:name=
"android.intent.category.DEFAULT"
/>
</intent-filter>
</activity>
<service
android:name=
".notification.NotificationService"
android:permission=
"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
>
<intent-filter>
<action
android:name=
"android.service.notification.NotificationListenerService"
/>
</intent-filter>
</service>
<meta-data
android:name=
"io.fabric.ApiKey"
android:value=
"8fcf342f1b8ac74d6980872082b7216ef4682a29"
/>
</application>
</manifest>
app/src/main/java/org/indin/blisslaunchero/db/Storage.java
→
app/src/main/java/org/indin/blisslaunchero/
data/
db/Storage.java
View file @
8f67f67b
package
org.indin.blisslaunchero.db
;
package
org.indin.blisslaunchero.
data.
db
;
import
android.content.Context
;
import
android.content.SharedPreferences
;
...
...
@@ -7,7 +7,7 @@ import android.util.Log;
import
android.view.ViewGroup
;
import
android.widget.GridLayout
;
import
org.indin.blisslaunchero.model.AppItem
;
import
org.indin.blisslaunchero.
data.
model.AppItem
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
...
...
app/src/main/java/org/indin/blisslaunchero/model/AppItem.java
→
app/src/main/java/org/indin/blisslaunchero/
data/
model/AppItem.java
View file @
8f67f67b
package
org.indin.blisslaunchero.model
;
package
org.indin.blisslaunchero.
data.
model
;
import
android.content.Intent
;
import
android.graphics.drawable.Drawable
;
...
...
@@ -8,133 +8,134 @@ import java.util.List;
public
class
AppItem
{
private
CharSequence
label
;
private
String
packageName
;
private
Drawable
icon
;
private
Intent
intent
;
private
String
componentName
;
private
boolean
iconFromIconPack
;
private
boolean
isSystemApp
;
private
boolean
isClock
;
private
boolean
isCalendar
;
private
CharSequence
mLabel
;
private
String
mPackageName
;
private
Drawable
mIcon
;
private
Intent
mIntent
;
private
String
mComponentName
;
private
boolean
mIconFromIconPack
;
private
boolean
mIsSystemApp
;
private
boolean
mIsClock
;
private
boolean
mIsCalendar
;
private
boolean
isPinnedApp
;
// Folder specific
private
boolean
b
elongsToFolder
;
private
boolean
i
sFolder
;
private
String
f
olderID
;
private
List
<
AppItem
>
s
ubApps
;
private
boolean
mB
elongsToFolder
;
private
boolean
mI
sFolder
;
private
String
mF
olderID
;
private
List
<
AppItem
>
mS
ubApps
;
public
AppItem
(
CharSequence
label
,
String
packageName
,
Drawable
icon
,
Intent
intent
,
String
componentName
,
boolean
iconFromIconPack
,
boolean
isSystemApp
,
boolean
isClock
,
boolean
isCalendar
)
{
this
.
l
abel
=
label
;
this
.
p
ackageName
=
packageName
;
this
.
i
con
=
icon
;
this
.
i
ntent
=
intent
;
this
.
c
omponentName
=
componentName
;
this
.
i
conFromIconPack
=
iconFromIconPack
;
this
.
i
sSystemApp
=
isSystemApp
;
this
.
i
sClock
=
isClock
;
this
.
i
sCalendar
=
isCalendar
;
this
.
mL
abel
=
label
;
this
.
mP
ackageName
=
packageName
;
this
.
mI
con
=
icon
;
this
.
mI
ntent
=
intent
;
this
.
mC
omponentName
=
componentName
;
this
.
mI
conFromIconPack
=
iconFromIconPack
;
this
.
mI
sSystemApp
=
isSystemApp
;
this
.
mI
sClock
=
isClock
;
this
.
mI
sCalendar
=
isCalendar
;
}
public
CharSequence
getLabel
()
{
return
l
abel
;
return
mL
abel
;
}
public
void
setLabel
(
CharSequence
label
)
{
this
.
l
abel
=
label
;
this
.
mL
abel
=
label
;
}
public
String
getPackageName
()
{
return
p
ackageName
;
return
mP
ackageName
;
}
public
void
setPackageName
(
String
packageName
)
{
this
.
p
ackageName
=
packageName
;
this
.
mP
ackageName
=
packageName
;
}
public
Drawable
getIcon
()
{
return
i
con
;
return
mI
con
;
}
public
boolean
isSystemApp
()
{
return
i
sSystemApp
;
return
mI
sSystemApp
;
}
public
boolean
isClock
()
{
return
i
sClock
;
return
mI
sClock
;
}
public
boolean
isCalendar
()
{
return
i
sCalendar
;
return
mI
sCalendar
;
}
public
void
setSystemApp
(
boolean
isSystemApp
)
{
this
.
i
sSystemApp
=
isSystemApp
;
this
.
mI
sSystemApp
=
isSystemApp
;
}
public
void
setIcon
(
Drawable
icon
)
{
this
.
i
con
=
icon
;
this
.
mI
con
=
icon
;
}
public
Intent
getIntent
()
{
return
i
ntent
;
return
mI
ntent
;
}
public
void
setIntent
(
Intent
intent
)
{
this
.
i
ntent
=
intent
;
this
.
mI
ntent
=
intent
;
}
public
String
getComponentName
()
{
return
c
omponentName
;
return
mC
omponentName
;
}
public
void
setComponentName
(
String
componentName
)
{
this
.
c
omponentName
=
componentName
;
this
.
mC
omponentName
=
componentName
;
}
public
boolean
isIconFromIconPack
()
{
return
i
conFromIconPack
;
return
mI
conFromIconPack
;
}
public
void
setIconFromIconPack
(
boolean
iconFromIconPack
)
{
this
.
i
conFromIconPack
=
iconFromIconPack
;
this
.
mI
conFromIconPack
=
iconFromIconPack
;
}
public
boolean
isFolder
()
{
return
i
sFolder
;
return
mI
sFolder
;
}
public
void
setFolder
(
boolean
folder
)
{
i
sFolder
=
folder
;
mI
sFolder
=
folder
;
}
public
String
getFolderID
()
{
return
f
olderID
;
return
mF
olderID
;
}
public
void
setFolderID
(
String
folderID
)
{
this
.
f
olderID
=
folderID
;
this
.
mF
olderID
=
folderID
;
}
public
List
<
AppItem
>
getSubApps
()
{
if
(
s
ubApps
==
null
)
{
s
ubApps
=
new
ArrayList
<>();
if
(
mS
ubApps
==
null
)
{
mS
ubApps
=
new
ArrayList
<>();
}
return
s
ubApps
;
return
mS
ubApps
;
}
public
void
setSubApps
(
List
<
AppItem
>
subApps
)
{
this
.
s
ubApps
=
subApps
;
this
.
mS
ubApps
=
subApps
;
}
public
boolean
isBelongsToFolder
()
{
return
b
elongsToFolder
;
return
mB
elongsToFolder
;
}
public
void
setBelongsToFolder
(
boolean
belongsToFolder
)
{
this
.
b
elongsToFolder
=
belongsToFolder
;
this
.
mB
elongsToFolder
=
belongsToFolder
;
}
}
app/src/main/java/org/indin/blisslaunchero/data/model/CalendarIcon.java
0 → 100644
View file @
8f67f67b
package
org.indin.blisslaunchero.data.model
;
import
android.widget.TextView
;
/**
* Created by falcon on 17/3/18.
*/
public
class
CalendarIcon
{
public
TextView
monthTextView
;
public
TextView
dayTextView
;
public
CalendarIcon
(
TextView
monthTextView
,
TextView
dayTextView
)
{
this
.
monthTextView
=
monthTextView
;
this
.
dayTextView
=
dayTextView
;
}
}
app/src/main/java/org/indin/blisslaunchero/data/model/OtherInfo.java
0 → 100644
View file @
8f67f67b
package
org.indin.blisslaunchero.data.model
;
/**
* Created by falcon on 18/3/18.
*/
public
class
OtherInfo
{
public
int
count
;
public
String
packageName
;
}
app/src/main/java/org/indin/blisslaunchero/notification/DotRenderer.java
0 → 100644
View file @
8f67f67b
package
org.indin.blisslaunchero.notification
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Rect
;
import
android.util.Log
;
/**
* Created by falcon on 20/3/18.
*/
public
class
DotRenderer
{
private
static
final
String
TAG
=
"DotRenderer"
;
private
static
final
float
SIZE_PERCENTAGE
=
0.25f
;
private
final
int
mSize
;
private
final
Paint
mPaint
=
new
Paint
(
Paint
.
ANTI_ALIAS_FLAG
|
Paint
.
DITHER_FLAG
|
Paint
.
FILTER_BITMAP_FLAG
);
public
DotRenderer
(
int
iconSizePx
){
this
.
mSize
=
(
int
)
(
SIZE_PERCENTAGE
*
iconSizePx
);
}
public
void
drawDot
(
Canvas
canvas
,
Rect
iconBounds
){
Log
.
d
(
TAG
,
"drawDot() called with: canvas = ["
+
canvas
+
"], iconBounds = ["
+
iconBounds
+
"]"
);
int
badgeCenterX
=
(
int
)
(
iconBounds
.
left
+
mSize
*
0.25
);
int
badgeCenterY
=
(
int
)
(
iconBounds
.
top
+
mSize
*
0.25
);
mPaint
.
setColor
(
Color
.
parseColor
(
"#FF0800"
));
canvas
.
drawCircle
(
badgeCenterX
,
badgeCenterY
,
mSize
/
2
,
mPaint
);
}
}
app/src/main/java/org/indin/blisslaunchero/notification/NotificationRepository.java
0 → 100755
View file @
8f67f67b
package
org.indin.blisslaunchero.notification
;
import
android.service.notification.StatusBarNotification
;
import
android.util.Log
;
import
com.jakewharton.rxrelay2.BehaviorRelay
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
/**
* Created by Amit Kumar
* Email : mr.doc10jl96@gmail.com
*/
public
class
NotificationRepository
{
private
BehaviorRelay
<
Set
<
String
>>
notificationRelay
;
private
static
final
String
TAG
=
"NotificationRepository"
;
private
static
NotificationRepository
sInstance
;
private
NotificationRepository
()
{
notificationRelay
=
BehaviorRelay
.
createDefault
(
Collections
.
emptySet
());
}
public
static
NotificationRepository
getNotificationRepository
()
{
if
(
sInstance
==
null
)
{
sInstance
=
new
NotificationRepository
();
}
return
sInstance
;
}
public
void
updateNotification
(
List
<
StatusBarNotification
>
list
)
{
Log
.
d
(
TAG
,
"updateNotification() called with: list = ["
+
list
.
size
()
+
"]"
);
Set
<
String
>
notificationSet
=
new
HashSet
<>();
for
(
StatusBarNotification
statusBarNotification
:
list
)
{
notificationSet
.
add
(
statusBarNotification
.
getPackageName
());
}
this
.
notificationRelay
.
accept
(
notificationSet
);
}
public
BehaviorRelay
<
Set
<
String
>>
getNotifications
()
{
return
this
.
notificationRelay
;
}
}
app/src/main/java/org/indin/blisslaunchero/notification/NotificationService.java
0 → 100644
View file @
8f67f67b
package
org.indin.blisslaunchero.notification
;
import
android.content.Intent
;
import
android.service.notification.NotificationListenerService
;
import
android.service.notification.StatusBarNotification
;
import
android.util.Log
;
import
org.indin.blisslaunchero.utils.ListUtil
;
/**
* Created by falcon on 14/3/18.
*/
public
class
NotificationService
extends
NotificationListenerService
{
NotificationRepository
mNotificationRepository
;
private
static
final
String
TAG
=
"NotificationService"
;
@Override
public
void
onCreate
()
{
super
.
onCreate
();
mNotificationRepository
=
NotificationRepository
.
getNotificationRepository
();
}
@Override
public
void
onDestroy
()
{
super
.
onDestroy
();
}
@Override
public
void
onListenerConnected
()
{
Log
.
d
(
TAG
,
"onListenerConnected() called"
);
mNotificationRepository
.
updateNotification
(
ListUtil
.
asSafeList
(
getActiveNotifications
()));
}
@Override
public
void
onNotificationPosted
(
StatusBarNotification
sbn
)
{
Log
.
d
(
TAG
,
"onNotificationPosted() called with: sbn = ["
+
sbn
+
"]"
);
mNotificationRepository
.
updateNotification
(
ListUtil
.
asSafeList
(
getActiveNotifications
()));
}
@Override
public
void
onNotificationRemoved
(
StatusBarNotification
sbn
)
{
Log
.
d
(
TAG
,
"onNotificationRemoved() called with: sbn = ["
+
sbn
+
"]"
);
mNotificationRepository
.
updateNotification
(
ListUtil
.
asSafeList
(
getActiveNotifications
()));
}
}
app/src/main/java/org/indin/blisslaunchero/ui/
Desktop
Activity.java
→
app/src/main/java/org/indin/blisslaunchero/ui/
Launcher
Activity.java
View file @
8f67f67b
This diff is collapsed.
Click to expand it.
app/src/main/java/org/indin/blisslaunchero/ui/LauncherPresenter.java
0 → 100644
View file @
8f67f67b
package
org.indin.blisslaunchero.ui
;
import
android.content.Context
;
import
android.view.View
;
import
org.indin.blisslaunchero.utils.AppUtil
;
import
io.reactivex.Observable
;
import
io.reactivex.disposables.CompositeDisposable
;
import
io.reactivex.disposables.Disposable
;
/**
* Created by falcon on 18/3/18.
*/
public
class
LauncherPresenter
{
private
LauncherView
mLauncherView
;
private
Context
mContext
;
private
CompositeDisposable
mCompositeDisposable
;
private
LauncherPresenter
(
Context
context
)
{
this
.
mContext
=
context
;
this
.
mCompositeDisposable
=
new
CompositeDisposable
();
}
public
void
attachView
(
LauncherView
view
)
{
this
.
mLauncherView
=
view
;
}
public
void
detachView
()
{
mCompositeDisposable
.
dispose
();
mLauncherView
=
null
;
}
public
boolean
isViewAttached
()
{
return
mLauncherView
!=
null
;
}
public
void
loadApps
(){
}
}
app/src/main/java/org/indin/blisslaunchero/ui/LauncherView.java
0 → 100644
View file @
8f67f67b
package
org.indin.blisslaunchero.ui
;
import
org.indin.blisslaunchero.data.model.AppItem
;
import
java.util.List
;
import
java.util.Map
;
/**
* Created by falcon on 18/3/18.
*/
public
interface
LauncherView
{
void
showApps
(
List
<
AppItem
>
allAppItems
,
List
<
AppItem
>
pinnedAppItems
);
void
showNotificationBadges
(
Map
<
String
,
Integer
>
map
);
void
showLoading
();
void
hideLoading
();
}
app/src/main/java/org/indin/blisslaunchero/utils/AppUtil.java
View file @
8f67f67b
...
...
@@ -12,7 +12,7 @@ import android.os.Bundle;
import
android.provider.MediaStore
;
import
android.support.annotation.Nullable
;
import
org.indin.blisslaunchero.model.AppItem
;
import
org.indin.blisslaunchero.
data.
model.AppItem
;
import
org.indin.blisslaunchero.R
;
import
java.text.Collator
;
...
...
app/src/main/java/org/indin/blisslaunchero/utils/ConverterUtil.java
View file @
8f67f67b
...
...
@@ -2,6 +2,7 @@ package org.indin.blisslaunchero.utils;
import
android.content.Context
;
import
android.util.DisplayMetrics
;
import
android.util.TypedValue
;
import
java.util.Calendar
;
...
...
@@ -21,6 +22,10 @@ public class ConverterUtil {
return
px
/
metrics
.
scaledDensity
;
}
public
static
int
spToPx
(
float
sp
,
Context
context
)
{
return
(
int
)
TypedValue
.
applyDimension
(
TypedValue
.
COMPLEX_UNIT_SP
,
sp
,
context
.
getResources
().
getDisplayMetrics
());
}
public
static
String
convertMonthToString
(
int
month
)
{
switch
(
month
)
{
case
Calendar
.
JANUARY
:
...
...
app/src/main/java/org/indin/blisslaunchero/utils/GraphicsUtil.java
View file @
8f67f67b
...
...
@@ -15,7 +15,7 @@ import android.renderscript.ScriptIntrinsicBlur;
import
android.support.v4.content.ContextCompat
;
import
android.util.Log
;
import
org.indin.blisslaunchero.model.AppItem
;
import
org.indin.blisslaunchero.
data.
model.AppItem
;
import
org.indin.blisslaunchero.R
;
public
class
GraphicsUtil
{
...
...
app/src/main/java/org/indin/blisslaunchero/utils/ListUtil.java
0 → 100755
View file @
8f67f67b
package
org.indin.blisslaunchero.utils
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* Created by Amit Kumar
* Email : mr.doc10jl96@gmail.com
*/
public
class
ListUtil
{
@SafeVarargs
public
static
<
T
>
List
<
T
>
asSafeList
(
T
...
tArr
)
{
return
(
tArr
==
null
||
tArr
.
length
==
0
)
?
new
ArrayList
()
:
Arrays
.
asList
(
tArr
);
}
}
app/src/main/java/org/indin/blisslaunchero/widgets/BlissFrameLayout.java
0 → 100644
View file @
8f67f67b
package
org.indin.blisslaunchero.widgets
;
import
android.animation.ObjectAnimator
;
import
android.content.Context
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
import
android.graphics.Rect
;
import
android.graphics.Typeface
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.util.AttributeSet
;
import
android.util.Log
;
import
android.util.Property
;
import
android.widget.FrameLayout
;
import
org.indin.blisslaunchero.notification.DotRenderer
;
import
org.indin.blisslaunchero.ui.LauncherActivity
;
import
org.indin.blisslaunchero.utils.ConverterUtil
;
/**
* Created by falcon on 20/3/18.
*/
public
class
BlissFrameLayout
extends
FrameLayout
{
private
static
final
String
TAG
=
"BlissFrameLayout"
;
private
final
Context
mContext
;
private
boolean
hasBadge
=
false
;
private
Rect
mTempIconBounds
=
new
Rect
();
private
float
mBadgeScale
;
private
static
final
Property
<
BlissFrameLayout
,
Float
>
BADGE_SCALE_PROPERTY
=
new
Property
<
BlissFrameLayout
,
Float
>(
Float
.
TYPE
,
"badgeScale"
)
{
@Override
public
Float
get
(
BlissFrameLayout
bubbleTextView
)
{
return
bubbleTextView
.
mBadgeScale
;
}
@Override
public
void
set
(
BlissFrameLayout
bubbleTextView
,
Float
value
)
{