Repository: leolin310148/ShortcutBadger
Branch: master
Commit: 6d4ce808b0a1
Files: 48
Total size: 91.1 KB
Directory structure:
gitextract_akhmgbpy/
├── .gitignore
├── LICENSE
├── README.md
├── SampleApp/
│ ├── .gitignore
│ ├── build.gradle
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── me/
│ │ └── leolin/
│ │ └── shortcutbadger/
│ │ └── example/
│ │ └── ApplicationTest.java
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── me/
│ │ └── leolin/
│ │ └── shortcutbadger/
│ │ └── example/
│ │ ├── BadgeIntentService.java
│ │ └── MainActivity.java
│ └── res/
│ ├── layout/
│ │ └── activity_main.xml
│ ├── values/
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── values-w820dp/
│ └── dimens.xml
├── ShortcutBadger/
│ ├── .gitignore
│ ├── build.gradle
│ ├── mvn-push.gradle
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ └── java/
│ └── me/
│ └── leolin/
│ └── shortcutbadger/
│ ├── Badger.java
│ ├── ShortcutBadgeException.java
│ ├── ShortcutBadger.java
│ ├── impl/
│ │ ├── AdwHomeBadger.java
│ │ ├── ApexHomeBadger.java
│ │ ├── AsusHomeBadger.java
│ │ ├── DefaultBadger.java
│ │ ├── EverythingMeHomeBadger.java
│ │ ├── HuaweiHomeBadger.java
│ │ ├── IntentConstants.java
│ │ ├── LGHomeBadger.java
│ │ ├── NewHtcHomeBadger.java
│ │ ├── NovaHomeBadger.java
│ │ ├── OPPOHomeBader.java
│ │ ├── SamsungHomeBadger.java
│ │ ├── SonyHomeBadger.java
│ │ ├── VivoHomeBadger.java
│ │ ├── XiaomiHomeBadger.java
│ │ ├── YandexLauncherBadger.java
│ │ ├── ZTEHomeBadger.java
│ │ └── ZukHomeBadger.java
│ └── util/
│ ├── BroadcastHelper.java
│ └── CloseHelper.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.idea/*
*.iml
build
.gradle
local.properties
**/gradle.properties
================================================
FILE: LICENSE
================================================
Copyright 2014 Leo Lin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
ShortcutBadger: [](https://maven-badges.herokuapp.com/maven-central/me.leolin/ShortcutBadger)
===================================
The ShortcutBadger makes your Android App show the count of unread messages as a badge on your App shortcut!
# Supported launchers:
Sony
Samsung
LG
HTC
Xiaomi
ASUS
ADW
APEX
NOVA
Huawei
(Not Fully Support)
(1.1.7+)
ZUK
(1.1.10+)
OPPO
(Not Fully Support)
(1.1.10+)
EverythingMe
ZTE
(1.1.17+)
KISS
(1.1.18+)
LaunchTime
Yandex Launcher
(1.1.23+)
* Nova launcher with TeslaUnread, Apex launcher, ADW Launcher provided by [notz](https://github.com/notz)
* Solid launcher provided by [MajeurAndroid](https://github.com/MajeurAndroid)
* KISS Launcher provided by [alexander255](https://github.com/alexander255)
## About Xiaomi devices
Xiaomi devices require extra setup with notifications, please read [wiki](https://github.com/leolin310148/ShortcutBadger/wiki/Xiaomi-Device-Support).
## IsBadgeWorking?
A tool for displaying your device, launcher & android version and testing whether ShortcutBadger
works or not may be downloaded from
* Google Play [https://play.google.com/store/apps/details?id=me.leolin.isbadgeworking](https://play.google.com/store/apps/details?id=me.leolin.isbadgeworking)
* The GitHub repository [https://github.com/leolin310148/IsBadgeWorking.Android/releases](https://github.com/leolin310148/IsBadgeWorking.Android/releases)
USAGE
===================================
1. Add mavenCentral to your build script.
repositories {
mavenCentral()
}
2. Add dependencies for ShortcutBadger, it's available from maven now.
dependencies {
implementation "me.leolin:ShortcutBadger:1.1.22@aar"
}
3. Add the codes below:
int badgeCount = 1;
ShortcutBadger.applyCount(context, badgeCount); //for 1.1.4+
ShortcutBadger.with(getApplicationContext()).count(badgeCount); //for 1.1.3
4. If you want to remove the badge
ShortcutBadger.removeCount(context); //for 1.1.4+
ShortcutBadger.with(getApplicationContext()).remove(); //for 1.1.3
or
ShortcutBadger.applyCount(context, 0); //for 1.1.4+
ShortcutBadger.with(getApplicationContext()).count(0); //for 1.1.3
DEVELOP BY
===================================
[Leo Lin](https://github.com/leolin310148) - leolin310148@gmail.com
ABOUT Google Play Developer Term Violations
===================================
If you receive a message from Google containing something like this:
REASON FOR WARNING: Violation of section 4.4 of the Developer Distribution Agreement.
please use version 1.1.0+!
CHANGE LOG
==========
1.1.23:
* Added Yandex Launcher support. Fixed issue with incorrect default launcher resolve
1.1.22:
* Improve Oreo support (Thanks to [AlexStarc](https://github.com/AlexStarc))
1.1.20:
* Renamed default broadcast action; added Android Oreo support.
1.1.19:
* Fix multiple home package resolve issue.
1.1.18:
* Add Kill Launcher Support
1.1.17:
* Add ZTE Support
1.1.16:
* Improve Sony Launcher support.
1.1.15:
* Add EverythingLauncher Support.
1.1.14:
* Fix for specific class of Samsung devices: with android 5, but without support of DefaultBadger
* Remove Xiaomi from Badger and add Notification Support for Xiaomi devices.
1.1.13:
* Fix XiaomiBadger (tested with RedMi Note4)
1.1.12:
* Handling Samsung badger for old devices and new devices.
* Try to support newer Xiaomi (Not tested.)
* Try to support Vivo (Not tested.)
1.1.11:
* Add OPPO Launcher Support
1.1.10:
* Add ZUK Launcher Support
1.1.9:
* Add SamsungBadger back for more Samsung devices support.
1.1.8:
* Remove SolidBadger, now solid launcher will use default badger.
1.1.7:
* Add Huawei launcher support.
1.1.6:
* Add support for new Sony Launchers.
1.1.5:
* `applyCount` will return if the Broadcast has been sent successfully.
1.1.4:
* Changed `ShortcutBadger.setBadge(context, badgeCount)` to `ShortcutBadger.applyCount(context, badgeCount);`
1.1.3:
* Deprecate SamsungBadger and LGBadger, those devices can use DefaultBadger.
1.1.2:
* Add support for `com.miui.mihome2`
1.1.1:
* Add DefaultBadger because some launchers use android.intent.action.BADGE_COUNT_UPDATE to update count.
* Since the ShortcutBadgerException is helpless. So change api to set badge and never have to handle the exception again.
1.1.0:
* Remove Android Launcher support due to Google Play Developer Term Violation since 4.4.
1.0.10:
* Add Asus launcher support.
1.0.9:
* Add Xiaomi launcher support.
LICENSE
===================================
Copyright 2014 Leo Lin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: SampleApp/.gitignore
================================================
/build
================================================
FILE: SampleApp/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "me.leolin.shortcutbadger.example"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
lintOptions {
abortOnError false
}
}
dependencies {
// implementation 'me.leolin:ShortcutBadger:1.0.+@aar'
implementation project(':ShortcutBadger')
}
================================================
FILE: SampleApp/src/androidTest/java/me/leolin/shortcutbadger/example/ApplicationTest.java
================================================
package me.leolin.shortcutbadger.example;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* Testing Fundamentals
*/
public class ApplicationTest extends ApplicationTestCase {
public ApplicationTest() {
super(Application.class);
}
}
================================================
FILE: SampleApp/src/main/AndroidManifest.xml
================================================
================================================
FILE: SampleApp/src/main/java/me/leolin/shortcutbadger/example/BadgeIntentService.java
================================================
package me.leolin.shortcutbadger.example;
import android.annotation.TargetApi;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import me.leolin.shortcutbadger.ShortcutBadger;
public class BadgeIntentService extends IntentService {
private static final String NOTIFICATION_CHANNEL = "me.leolin.shortcutbadger.example";
private int notificationId = 0;
public BadgeIntentService() {
super("BadgeIntentService");
}
private NotificationManager mNotificationManager;
@Override
public void onCreate() {
super.onCreate();
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
int badgeCount = intent.getIntExtra("badgeCount", 0);
mNotificationManager.cancel(notificationId);
notificationId++;
Notification.Builder builder = new Notification.Builder(getApplicationContext())
.setContentTitle("")
.setContentText("")
.setSmallIcon(R.drawable.ic_launcher);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setupNotificationChannel();
builder.setChannelId(NOTIFICATION_CHANNEL);
}
Notification notification = builder.build();
ShortcutBadger.applyNotification(getApplicationContext(), notification, badgeCount);
mNotificationManager.notify(notificationId, notification);
}
}
@TargetApi(Build.VERSION_CODES.O)
private void setupNotificationChannel() {
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL, "ShortcutBadger Sample",
NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
}
}
================================================
FILE: SampleApp/src/main/java/me/leolin/shortcutbadger/example/MainActivity.java
================================================
package me.leolin.shortcutbadger.example;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import me.leolin.shortcutbadger.ShortcutBadger;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText numInput = findViewById(R.id.numInput);
Button button = findViewById(R.id.btnSetBadge);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int badgeCount = 0;
try {
badgeCount = Integer.parseInt(numInput.getText().toString());
} catch (NumberFormatException e) {
Toast.makeText(getApplicationContext(), "Error input", Toast.LENGTH_SHORT).show();
}
boolean success = ShortcutBadger.applyCount(MainActivity.this, badgeCount);
Toast.makeText(getApplicationContext(), "Set count=" + badgeCount + ", success=" + success, Toast.LENGTH_SHORT).show();
}
});
Button launchNotification = findViewById(R.id.btnSetBadgeByNotification);
launchNotification.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int badgeCount = 0;
try {
badgeCount = Integer.parseInt(numInput.getText().toString());
} catch (NumberFormatException e) {
Toast.makeText(getApplicationContext(), "Error input", Toast.LENGTH_SHORT).show();
}
finish();
startService(
new Intent(MainActivity.this, BadgeIntentService.class).putExtra("badgeCount", badgeCount)
);
}
});
Button removeBadgeBtn = findViewById(R.id.btnRemoveBadge);
removeBadgeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean success = ShortcutBadger.removeCount(MainActivity.this);
Toast.makeText(getApplicationContext(), "success=" + success, Toast.LENGTH_SHORT).show();
}
});
//find the home launcher Package
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
String currentHomePackage = "none";
ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
// in case of duplicate apps (Xiaomi), calling resolveActivity from one will return null
if (resolveInfo != null) {
currentHomePackage = resolveInfo.activityInfo.packageName;
}
TextView textViewHomePackage = findViewById(R.id.textViewHomePackage);
textViewHomePackage.setText("launcher:" + currentHomePackage);
}
}
================================================
FILE: SampleApp/src/main/res/layout/activity_main.xml
================================================
================================================
FILE: SampleApp/src/main/res/values/dimens.xml
================================================
16dp16dp
================================================
FILE: SampleApp/src/main/res/values/strings.xml
================================================
ShortcutBadger
================================================
FILE: SampleApp/src/main/res/values/styles.xml
================================================
================================================
FILE: SampleApp/src/main/res/values-w820dp/dimens.xml
================================================
64dp
================================================
FILE: ShortcutBadger/.gitignore
================================================
.idea/*
*.iml
build
.gradle
================================================
FILE: ShortcutBadger/build.gradle
================================================
apply plugin: 'com.android.library'
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
minSdkVersion 14
targetSdkVersion 27
versionCode 1
versionName "1.0"
consumerProguardFiles 'proguard-rules.pro'
}
lintOptions {
abortOnError false
}
}
//apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'
apply from: './mvn-push.gradle'
================================================
FILE: ShortcutBadger/mvn-push.gradle
================================================
/*
* Copyright 2013 Chris Banes
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
apply plugin: 'maven'
apply plugin: 'signing'
def isReleaseBuild() {
return VERSION_NAME.contains("SNAPSHOT") == false
}
def getReleaseRepositoryUrl() {
return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
: "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
}
def getSnapshotRepositoryUrl() {
return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
: "https://oss.sonatype.org/content/repositories/snapshots/"
}
def getRepositoryUsername() {
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
}
def getRepositoryPassword() {
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
}
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
pom.groupId = GROUP
pom.artifactId = POM_ARTIFACT_ID
pom.version = VERSION_NAME
repository(url: getReleaseRepositoryUrl()) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
snapshotRepository(url: getSnapshotRepositoryUrl()) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
pom.project {
name POM_NAME
packaging POM_PACKAGING
description POM_DESCRIPTION
url POM_URL
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEV_CONNECTION
}
licenses {
license {
name POM_LICENCE_NAME
url POM_LICENCE_URL
distribution POM_LICENCE_DIST
}
}
developers {
developer {
id POM_DEVELOPER_ID
name POM_DEVELOPER_NAME
}
}
}
}
}
}
signing {
required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
sign configurations.archives
}
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
}
================================================
FILE: ShortcutBadger/proguard-rules.pro
================================================
#https://github.com/leolin310148/ShortcutBadger/issues/46
-keep class me.leolin.shortcutbadger.impl.** { (...); }
================================================
FILE: ShortcutBadger/src/main/AndroidManifest.xml
================================================
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/Badger.java
================================================
package me.leolin.shortcutbadger;
import android.content.ComponentName;
import android.content.Context;
import java.util.List;
public interface Badger {
/**
* Called when user attempts to update notification count
* @param context Caller context
* @param componentName Component containing package and class name of calling application's
* launcher activity
* @param badgeCount Desired notification count
* @throws ShortcutBadgeException
*/
void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException;
/**
* Called to let {@link ShortcutBadger} knows which launchers are supported by this badger. It should return a
* @return List containing supported launchers package names
*/
List getSupportLaunchers();
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/ShortcutBadgeException.java
================================================
package me.leolin.shortcutbadger;
public class ShortcutBadgeException extends Exception {
public ShortcutBadgeException(String message) {
super(message);
}
public ShortcutBadgeException(String message, Exception e) {
super(message, e);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/ShortcutBadger.java
================================================
package me.leolin.shortcutbadger;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import me.leolin.shortcutbadger.impl.AdwHomeBadger;
import me.leolin.shortcutbadger.impl.ApexHomeBadger;
import me.leolin.shortcutbadger.impl.AsusHomeBadger;
import me.leolin.shortcutbadger.impl.DefaultBadger;
import me.leolin.shortcutbadger.impl.EverythingMeHomeBadger;
import me.leolin.shortcutbadger.impl.HuaweiHomeBadger;
import me.leolin.shortcutbadger.impl.NewHtcHomeBadger;
import me.leolin.shortcutbadger.impl.NovaHomeBadger;
import me.leolin.shortcutbadger.impl.OPPOHomeBader;
import me.leolin.shortcutbadger.impl.SamsungHomeBadger;
import me.leolin.shortcutbadger.impl.SonyHomeBadger;
import me.leolin.shortcutbadger.impl.VivoHomeBadger;
import me.leolin.shortcutbadger.impl.YandexLauncherBadger;
import me.leolin.shortcutbadger.impl.ZTEHomeBadger;
import me.leolin.shortcutbadger.impl.ZukHomeBadger;
/**
* @author Leo Lin
*/
public final class ShortcutBadger {
private static final String LOG_TAG = "ShortcutBadger";
private static final int SUPPORTED_CHECK_ATTEMPTS = 3;
private static final List> BADGERS = new LinkedList>();
private volatile static Boolean sIsBadgeCounterSupported;
private final static Object sCounterSupportedLock = new Object();
static {
BADGERS.add(AdwHomeBadger.class);
BADGERS.add(ApexHomeBadger.class);
BADGERS.add(DefaultBadger.class);
BADGERS.add(NewHtcHomeBadger.class);
BADGERS.add(NovaHomeBadger.class);
BADGERS.add(SonyHomeBadger.class);
BADGERS.add(AsusHomeBadger.class);
BADGERS.add(HuaweiHomeBadger.class);
BADGERS.add(OPPOHomeBader.class);
BADGERS.add(SamsungHomeBadger.class);
BADGERS.add(ZukHomeBadger.class);
BADGERS.add(VivoHomeBadger.class);
BADGERS.add(ZTEHomeBadger.class);
BADGERS.add(EverythingMeHomeBadger.class);
BADGERS.add(YandexLauncherBadger.class);
}
private static Badger sShortcutBadger;
private static ComponentName sComponentName;
/**
* Tries to update the notification count
*
* @param context Caller context
* @param badgeCount Desired badge count
* @return true in case of success, false otherwise
*/
public static boolean applyCount(Context context, int badgeCount) {
try {
applyCountOrThrow(context, badgeCount);
return true;
} catch (ShortcutBadgeException e) {
if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
Log.d(LOG_TAG, "Unable to execute badge", e);
}
return false;
}
}
/**
* Tries to update the notification count, throw a {@link ShortcutBadgeException} if it fails
*
* @param context Caller context
* @param badgeCount Desired badge count
*/
public static void applyCountOrThrow(Context context, int badgeCount) throws ShortcutBadgeException {
if (sShortcutBadger == null) {
boolean launcherReady = initBadger(context);
if (!launcherReady)
throw new ShortcutBadgeException("No default launcher available");
}
try {
sShortcutBadger.executeBadge(context, sComponentName, badgeCount);
} catch (Exception e) {
throw new ShortcutBadgeException("Unable to execute badge", e);
}
}
/**
* Tries to remove the notification count
*
* @param context Caller context
* @return true in case of success, false otherwise
*/
public static boolean removeCount(Context context) {
return applyCount(context, 0);
}
/**
* Tries to remove the notification count, throw a {@link ShortcutBadgeException} if it fails
*
* @param context Caller context
*/
public static void removeCountOrThrow(Context context) throws ShortcutBadgeException {
applyCountOrThrow(context, 0);
}
/**
* Whether this platform launcher supports shortcut badges. Doing this check causes the side
* effect of resetting the counter if it's supported, so this method should be followed by
* a call that actually sets the counter to the desired value, if the counter is supported.
*/
public static boolean isBadgeCounterSupported(Context context) {
// Checking outside synchronized block to avoid synchronization in the common case (flag
// already set), and improve perf.
if (sIsBadgeCounterSupported == null) {
synchronized (sCounterSupportedLock) {
// Checking again inside synch block to avoid setting the flag twice.
if (sIsBadgeCounterSupported == null) {
String lastErrorMessage = null;
for (int i = 0; i < SUPPORTED_CHECK_ATTEMPTS; i++) {
try {
Log.i(LOG_TAG, "Checking if platform supports badge counters, attempt "
+ String.format("%d/%d.", i + 1, SUPPORTED_CHECK_ATTEMPTS));
if (initBadger(context)) {
sShortcutBadger.executeBadge(context, sComponentName, 0);
sIsBadgeCounterSupported = true;
Log.i(LOG_TAG, "Badge counter is supported in this platform.");
break;
} else {
lastErrorMessage = "Failed to initialize the badge counter.";
}
} catch (Exception e) {
// Keep retrying as long as we can. No need to dump the stack trace here
// because this error will be the norm, not exception, for unsupported
// platforms. So we just save the last error message to display later.
lastErrorMessage = e.getMessage();
}
}
if (sIsBadgeCounterSupported == null) {
Log.w(LOG_TAG, "Badge counter seems not supported for this platform: "
+ lastErrorMessage);
sIsBadgeCounterSupported = false;
}
}
}
}
return sIsBadgeCounterSupported;
}
/**
* @param context Caller context
* @param notification
* @param badgeCount
*/
public static void applyNotification(Context context, Notification notification, int badgeCount) {
if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
try {
Field field = notification.getClass().getDeclaredField("extraNotification");
Object extraNotification = field.get(notification);
Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
method.invoke(extraNotification, badgeCount);
} catch (Exception e) {
if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
Log.d(LOG_TAG, "Unable to execute badge", e);
}
}
}
}
// Initialize Badger if a launcher is availalble (eg. set as default on the device)
// Returns true if a launcher is available, in this case, the Badger will be set and sShortcutBadger will be non null.
private static boolean initBadger(Context context) {
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
if (launchIntent == null) {
Log.e(LOG_TAG, "Unable to find launch intent for package " + context.getPackageName());
return false;
}
sComponentName = launchIntent.getComponent();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
//Turns out framework does not guarantee to put DEFAULT Activity on top of the list.
ResolveInfo resolveInfoDefault = context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
validateInfoList(resolveInfoDefault, resolveInfos);
for (ResolveInfo resolveInfo : resolveInfos) {
String currentHomePackage = resolveInfo.activityInfo.packageName;
for (Class extends Badger> badger : BADGERS) {
Badger shortcutBadger = null;
try {
shortcutBadger = badger.newInstance();
} catch (Exception ignored) {
}
if (shortcutBadger != null && shortcutBadger.getSupportLaunchers().contains(currentHomePackage)) {
if (isLauncherVersionSupported(context, currentHomePackage)) {
sShortcutBadger = shortcutBadger;
}
break;
}
}
if (sShortcutBadger != null) {
break;
}
}
if (sShortcutBadger == null) {
if (Build.MANUFACTURER.equalsIgnoreCase("ZUK"))
sShortcutBadger = new ZukHomeBadger();
else if (Build.MANUFACTURER.equalsIgnoreCase("OPPO"))
sShortcutBadger = new OPPOHomeBader();
else if (Build.MANUFACTURER.equalsIgnoreCase("VIVO"))
sShortcutBadger = new VivoHomeBadger();
else if (Build.MANUFACTURER.equalsIgnoreCase("ZTE"))
sShortcutBadger = new ZTEHomeBadger();
else
sShortcutBadger = new DefaultBadger();
}
return true;
}
/**
* Making sure that launcher version that yet doesn't support badges mechanism
* is NOT used by sShortcutBadger.
*/
private static boolean isLauncherVersionSupported(Context context, String currentHomePackage) {
if (!YandexLauncherBadger.PACKAGE_NAME.equals(currentHomePackage)) {
return true;
}
return YandexLauncherBadger.isVersionSupported(context);
}
/**
* Making sure the default Home activity is on top of the returned list
* @param defaultActivity default Home activity
* @param resolveInfos list of all Home activities in the system
*/
private static void validateInfoList(ResolveInfo defaultActivity, List resolveInfos) {
int indexToSwapWith = 0;
for (int i = 0, resolveInfosSize = resolveInfos.size(); i < resolveInfosSize; i++) {
ResolveInfo resolveInfo = resolveInfos.get(i);
String currentActivityName = resolveInfo.activityInfo.packageName;
if (currentActivityName.equals(defaultActivity.activityInfo.packageName)) {
indexToSwapWith = i;
}
}
Collections.swap(resolveInfos, 0, indexToSwapWith);
}
// Avoid anybody to instantiate this class
private ShortcutBadger() {
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/AdwHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* @author Gernot Pansy
*/
public class AdwHomeBadger implements Badger {
public static final String INTENT_UPDATE_COUNTER = "org.adw.launcher.counter.SEND";
public static final String PACKAGENAME = "PNAME";
public static final String CLASSNAME = "CNAME";
public static final String COUNT = "COUNT";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Intent intent = new Intent(INTENT_UPDATE_COUNTER);
intent.putExtra(PACKAGENAME, componentName.getPackageName());
intent.putExtra(CLASSNAME, componentName.getClassName());
intent.putExtra(COUNT, badgeCount);
BroadcastHelper.sendIntentExplicitly(context, intent);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList(
"org.adw.launcher",
"org.adwfreak.launcher"
);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/ApexHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* @author Gernot Pansy
*/
public class ApexHomeBadger implements Badger {
private static final String INTENT_UPDATE_COUNTER = "com.anddoes.launcher.COUNTER_CHANGED";
private static final String PACKAGENAME = "package";
private static final String COUNT = "count";
private static final String CLASS = "class";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Intent intent = new Intent(INTENT_UPDATE_COUNTER);
intent.putExtra(PACKAGENAME, componentName.getPackageName());
intent.putExtra(COUNT, badgeCount);
intent.putExtra(CLASS, componentName.getClassName());
BroadcastHelper.sendIntentExplicitly(context, intent);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList("com.anddoes.launcher");
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/AsusHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.annotation.TargetApi;
import android.content.AsyncQueryHandler;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* @author leolin
*/
public class AsusHomeBadger implements Badger {
private static final String INTENT_ACTION = IntentConstants.DEFAULT_INTENT_ACTION;
private static final String INTENT_EXTRA_BADGE_COUNT = "badge_count";
private static final String INTENT_EXTRA_PACKAGENAME = "badge_count_package_name";
private static final String INTENT_EXTRA_ACTIVITY_NAME = "badge_count_class_name";
private static final String PROVIDER_CONTENT_URI = "content://com.android.badge/"; // FIXME
private static final String PROVIDER_COLUMNS_BADGE_COUNT = "badge_count"; // FIXME
private static final String PROVIDER_COLUMNS_PACKAGE_NAME = "package_name"; // FIXME
private static final String PROVIDER_COLUMNS_ACTIVITY_NAME = "activity_name"; // FIXME
private static final String ASUS_LAUNCHER_PROVIDER_NAME = "com.android.badge";
private final Uri BADGE_CONTENT_URI = Uri.parse(PROVIDER_CONTENT_URI);
private AsyncQueryHandler mQueryHandler;
// It seems that Asus handle Sony like badges better than old implementation...
private static final String SONY_INTENT_ACTION = "com.sonyericsson.home.action.UPDATE_BADGE";
private static final String SONY_INTENT_EXTRA_PACKAGE_NAME = "com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME";
private static final String SONY_INTENT_EXTRA_ACTIVITY_NAME = "com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME";
private static final String SONY_INTENT_EXTRA_MESSAGE = "com.sonyericsson.home.intent.extra.badge.MESSAGE";
private static final String SONY_INTENT_EXTRA_SHOW_MESSAGE = "com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// FIXME: It seems that ZenUI (com.asus.launcher) declares a content provider for badges but without documentation it is hard to guess how to add badges with it. Current draft implementation gives "No yet implemented" exception.
// if (asusBadgeContentProviderExists(context)) {
// executeBadgeByContentProvider(context, componentName, badgeCount);
// } else {
executeBadgeByBroadcast(context, componentName, badgeCount);
// }
} else {
Intent intent = new Intent(INTENT_ACTION);
intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount);
intent.putExtra(INTENT_EXTRA_PACKAGENAME, componentName.getPackageName());
intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName());
intent.putExtra("badge_vip_count", 0);
BroadcastHelper.sendDefaultIntentExplicitly(context, intent);
}
}
private void executeBadgeByBroadcast(Context context, ComponentName componentName, int badgeCount) {
Intent intent = new Intent(SONY_INTENT_ACTION);
intent.putExtra(SONY_INTENT_EXTRA_PACKAGE_NAME, componentName.getPackageName());
intent.putExtra(SONY_INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName());
intent.putExtra(SONY_INTENT_EXTRA_MESSAGE, String.valueOf(badgeCount));
intent.putExtra(SONY_INTENT_EXTRA_SHOW_MESSAGE, badgeCount > 0);
// FIXME: BroadcastHelper fail to resolve broadcast and then don't broadcast intent while it works.
// BroadcastHelper.sendDefaultIntentExplicitly(context, intent);
context.sendBroadcast(intent);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList("com.asus.launcher");
}
/**
* Send request to Asus badge content provider to set badge in Sony home launcher.
*
* @param context the context to use
* @param componentName the componentName to use
* @param badgeCount the badge count
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void executeBadgeByContentProvider(Context context, ComponentName componentName,
int badgeCount) {
if (badgeCount < 0) {
return;
}
final ContentValues contentValues = createContentValues(badgeCount, componentName);
if (Looper.myLooper() == Looper.getMainLooper()) {
// We're in the main thread. Let's ensure the badge update happens in a background
// thread by using an AsyncQueryHandler and an async update.
if (mQueryHandler == null) {
mQueryHandler = new AsyncQueryHandler(
context.getApplicationContext().getContentResolver()) {
};
}
insertBadgeAsync(contentValues);
} else {
// Already in a background thread. Let's update the badge synchronously. Otherwise,
// if we use the AsyncQueryHandler, this thread may already be dead by the time the
// async execution finishes, which will lead to an IllegalStateException.
insertBadgeSync(context, contentValues);
}
}
/**
* Asynchronously inserts the badge counter.
*
* @param contentValues Content values containing the badge count, package and activity names
*/
private void insertBadgeAsync(final ContentValues contentValues) {
mQueryHandler.startInsert(0, null, BADGE_CONTENT_URI, contentValues);
}
/**
* Synchronously inserts the badge counter.
*
* @param context Caller context
* @param contentValues Content values containing the badge count, package and activity names
*/
private void insertBadgeSync(final Context context, final ContentValues contentValues) {
context.getApplicationContext().getContentResolver()
.insert(BADGE_CONTENT_URI, contentValues);
}
/**
* Creates a ContentValues object to be used in the badge counter update. The package and
* activity names must correspond to an activity that holds an intent filter with action
* "android.intent.action.MAIN" and category android.intent.category.LAUNCHER" in the manifest.
* Also, it is not allowed to publish badges on behalf of another client, so the package and
* activity names must belong to the process from which the insert is made.
* To be able to insert badges, the app must have the PROVIDER_INSERT_BADGE
* permission in the manifest file. In case these conditions are not
* fulfilled, or any content values are missing, there will be an unhandled
* exception on the background thread.
*
* @param badgeCount the badge count
* @param componentName the component name from which package and class name will be extracted
*/
private ContentValues createContentValues(final int badgeCount,
final ComponentName componentName) {
final ContentValues contentValues = new ContentValues();
contentValues.put(PROVIDER_COLUMNS_BADGE_COUNT, badgeCount);
contentValues.put(PROVIDER_COLUMNS_PACKAGE_NAME, componentName.getPackageName());
contentValues.put(PROVIDER_COLUMNS_ACTIVITY_NAME, componentName.getClassName());
return contentValues;
}
/**
* Check if the latest Asus badge content provider exists.
*
* @param context the context to use
* @return true if Asus badge content provider exists, otherwise false.
*/
private static boolean asusBadgeContentProviderExists(Context context) {
boolean exists = false;
ProviderInfo info = context.getPackageManager().resolveContentProvider(ASUS_LAUNCHER_PROVIDER_NAME, 0);
if (info != null) {
exists = true;
}
return exists;
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/DefaultBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* @author leolin
*/
public class DefaultBadger implements Badger {
private static final String INTENT_ACTION = IntentConstants.DEFAULT_INTENT_ACTION;
private static final String INTENT_EXTRA_BADGE_COUNT = "badge_count";
private static final String INTENT_EXTRA_PACKAGENAME = "badge_count_package_name";
private static final String INTENT_EXTRA_ACTIVITY_NAME = "badge_count_class_name";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Intent intent = new Intent(INTENT_ACTION);
intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount);
intent.putExtra(INTENT_EXTRA_PACKAGENAME, componentName.getPackageName());
intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName());
BroadcastHelper.sendDefaultIntentExplicitly(context, intent);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList(
"fr.neamar.kiss",
"com.quaap.launchtime",
"com.quaap.launchtime_official"
);
}
boolean isSupported(Context context) {
Intent intent = new Intent(INTENT_ACTION);
return BroadcastHelper.resolveBroadcast(context, intent).size() > 0
|| (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& BroadcastHelper.resolveBroadcast(context, new Intent(IntentConstants.DEFAULT_OREO_INTENT_ACTION)).size() > 0);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/EverythingMeHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
/**
* @author Radko Roman
* @since 13.04.17.
*/
public class EverythingMeHomeBadger implements Badger {
private static final String CONTENT_URI = "content://me.everything.badger/apps";
private static final String COLUMN_PACKAGE_NAME = "package_name";
private static final String COLUMN_ACTIVITY_NAME = "activity_name";
private static final String COLUMN_COUNT = "count";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_PACKAGE_NAME, componentName.getPackageName());
contentValues.put(COLUMN_ACTIVITY_NAME, componentName.getClassName());
contentValues.put(COLUMN_COUNT, badgeCount);
context.getContentResolver().insert(Uri.parse(CONTENT_URI), contentValues);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList("me.everything.launcher");
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/HuaweiHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
/**
* @author Jason Ling
*/
public class HuaweiHomeBadger implements Badger {
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Bundle localBundle = new Bundle();
localBundle.putString("package", context.getPackageName());
localBundle.putString("class", componentName.getClassName());
localBundle.putInt("badgenumber", badgeCount);
context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, localBundle);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList(
"com.huawei.android.launcher"
);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/IntentConstants.java
================================================
package me.leolin.shortcutbadger.impl;
public interface IntentConstants {
String DEFAULT_INTENT_ACTION = "android.intent.action.BADGE_COUNT_UPDATE";
String DEFAULT_OREO_INTENT_ACTION = "me.leolin.shortcutbadger.BADGE_COUNT_UPDATE";
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/LGHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* @author Leo Lin
* Deprecated, LG devices will use DefaultBadger
*/
@Deprecated
public class LGHomeBadger implements Badger {
private static final String INTENT_ACTION = IntentConstants.DEFAULT_INTENT_ACTION;
private static final String INTENT_EXTRA_BADGE_COUNT = "badge_count";
private static final String INTENT_EXTRA_PACKAGENAME = "badge_count_package_name";
private static final String INTENT_EXTRA_ACTIVITY_NAME = "badge_count_class_name";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Intent intent = new Intent(INTENT_ACTION);
intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount);
intent.putExtra(INTENT_EXTRA_PACKAGENAME, componentName.getPackageName());
intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName());
BroadcastHelper.sendDefaultIntentExplicitly(context, intent);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList(
"com.lge.launcher",
"com.lge.launcher2"
);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/NewHtcHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import java.util.Collections;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* @author Leo Lin
*/
public class NewHtcHomeBadger implements Badger {
public static final String INTENT_UPDATE_SHORTCUT = "com.htc.launcher.action.UPDATE_SHORTCUT";
public static final String INTENT_SET_NOTIFICATION = "com.htc.launcher.action.SET_NOTIFICATION";
public static final String PACKAGENAME = "packagename";
public static final String COUNT = "count";
public static final String EXTRA_COMPONENT = "com.htc.launcher.extra.COMPONENT";
public static final String EXTRA_COUNT = "com.htc.launcher.extra.COUNT";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Intent intent1 = new Intent(INTENT_SET_NOTIFICATION);
boolean intent1Success;
intent1.putExtra(EXTRA_COMPONENT, componentName.flattenToShortString());
intent1.putExtra(EXTRA_COUNT, badgeCount);
Intent intent = new Intent(INTENT_UPDATE_SHORTCUT);
boolean intentSuccess;
intent.putExtra(PACKAGENAME, componentName.getPackageName());
intent.putExtra(COUNT, badgeCount);
try {
BroadcastHelper.sendIntentExplicitly(context, intent1);
intent1Success = true;
} catch (ShortcutBadgeException e) {
intent1Success = false;
}
try {
BroadcastHelper.sendIntentExplicitly(context, intent);
intentSuccess = true;
} catch (ShortcutBadgeException e) {
intentSuccess = false;
}
if (!intent1Success && !intentSuccess) {
throw new ShortcutBadgeException("unable to resolve intent: " + intent.toString());
}
}
@Override
public List getSupportLaunchers() {
return Collections.singletonList("com.htc.launcher");
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/NovaHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
/**
* Shortcut Badger support for Nova Launcher.
* TeslaUnread must be installed.
* User: Gernot Pansy
* Date: 2014/11/03
* Time: 7:15
*/
public class NovaHomeBadger implements Badger {
private static final String CONTENT_URI = "content://com.teslacoilsw.notifier/unread_count";
private static final String COUNT = "count";
private static final String TAG = "tag";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
ContentValues contentValues = new ContentValues();
contentValues.put(TAG, componentName.getPackageName() + "/" + componentName.getClassName());
contentValues.put(COUNT, badgeCount);
context.getContentResolver().insert(Uri.parse(CONTENT_URI), contentValues);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList("com.teslacoilsw.launcher");
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/OPPOHomeBader.java
================================================
package me.leolin.shortcutbadger.impl;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import java.util.Collections;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* Created by NingSo on 2016/10/14.上午10:09
*
* @author: NingSo
* Email: ningso.ping@gmail.com
*/
public class OPPOHomeBader implements Badger {
private static final String PROVIDER_CONTENT_URI = "content://com.android.badge/badge";
private static final String INTENT_ACTION = "com.oppo.unsettledevent";
private static final String INTENT_EXTRA_PACKAGENAME = "pakeageName";
private static final String INTENT_EXTRA_BADGE_COUNT = "number";
private static final String INTENT_EXTRA_BADGE_UPGRADENUMBER = "upgradeNumber";
private static final String INTENT_EXTRA_BADGEUPGRADE_COUNT = "app_badge_count";
private int mCurrentTotalCount = -1;
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
if (mCurrentTotalCount == badgeCount) {
return;
}
mCurrentTotalCount = badgeCount;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
executeBadgeByContentProvider(context, badgeCount);
} else {
executeBadgeByBroadcast(context, componentName, badgeCount);
}
}
@Override
public List getSupportLaunchers() {
return Collections.singletonList("com.oppo.launcher");
}
private void executeBadgeByBroadcast(Context context, ComponentName componentName,
int badgeCount) throws ShortcutBadgeException {
if (badgeCount == 0) {
badgeCount = -1;
}
Intent intent = new Intent(INTENT_ACTION);
intent.putExtra(INTENT_EXTRA_PACKAGENAME, componentName.getPackageName());
intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount);
intent.putExtra(INTENT_EXTRA_BADGE_UPGRADENUMBER, badgeCount);
BroadcastHelper.sendIntentExplicitly(context, intent);
}
/**
* Send request to OPPO badge content provider to set badge in OPPO home launcher.
*
* @param context the context to use
* @param badgeCount the badge count
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void executeBadgeByContentProvider(Context context, int badgeCount) throws ShortcutBadgeException {
try {
Bundle extras = new Bundle();
extras.putInt(INTENT_EXTRA_BADGEUPGRADE_COUNT, badgeCount);
context.getContentResolver().call(Uri.parse(PROVIDER_CONTENT_URI), "setAppBadgeCount", null, extras);
} catch (Throwable ignored) {
throw new ShortcutBadgeException("Unable to execute Badge By Content Provider");
}
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/SamsungHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.CloseHelper;
/**
* @author Leo Lin
*/
public class SamsungHomeBadger implements Badger {
private static final String CONTENT_URI = "content://com.sec.badge/apps?notify=true";
private static final String[] CONTENT_PROJECTION = new String[]{"_id", "class"};
private DefaultBadger defaultBadger;
public SamsungHomeBadger() {
if (Build.VERSION.SDK_INT >= 21) {
defaultBadger = new DefaultBadger();
}
}
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
if (defaultBadger != null && defaultBadger.isSupported(context)) {
defaultBadger.executeBadge(context, componentName, badgeCount);
} else {
Uri mUri = Uri.parse(CONTENT_URI);
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = null;
try {
cursor = contentResolver.query(mUri, CONTENT_PROJECTION, "package=?", new String[]{componentName.getPackageName()}, null);
if (cursor != null) {
String entryActivityName = componentName.getClassName();
boolean entryActivityExist = false;
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
ContentValues contentValues = getContentValues(componentName, badgeCount, false);
contentResolver.update(mUri, contentValues, "_id=?", new String[]{String.valueOf(id)});
if (entryActivityName.equals(cursor.getString(cursor.getColumnIndex("class")))) {
entryActivityExist = true;
}
}
if (!entryActivityExist) {
ContentValues contentValues = getContentValues(componentName, badgeCount, true);
contentResolver.insert(mUri, contentValues);
}
}
} finally {
CloseHelper.close(cursor);
}
}
}
private ContentValues getContentValues(ComponentName componentName, int badgeCount, boolean isInsert) {
ContentValues contentValues = new ContentValues();
if (isInsert) {
contentValues.put("package", componentName.getPackageName());
contentValues.put("class", componentName.getClassName());
}
contentValues.put("badgecount", badgeCount);
return contentValues;
}
@Override
public List getSupportLaunchers() {
return Arrays.asList(
"com.sec.android.app.launcher",
"com.sec.android.app.twlauncher"
);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/SonyHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.AsyncQueryHandler;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Looper;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
/**
* @author Leo Lin
*/
public class SonyHomeBadger implements Badger {
private static final String INTENT_ACTION = "com.sonyericsson.home.action.UPDATE_BADGE";
private static final String INTENT_EXTRA_PACKAGE_NAME = "com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME";
private static final String INTENT_EXTRA_ACTIVITY_NAME = "com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME";
private static final String INTENT_EXTRA_MESSAGE = "com.sonyericsson.home.intent.extra.badge.MESSAGE";
private static final String INTENT_EXTRA_SHOW_MESSAGE = "com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE";
private static final String PROVIDER_CONTENT_URI = "content://com.sonymobile.home.resourceprovider/badge";
private static final String PROVIDER_COLUMNS_BADGE_COUNT = "badge_count";
private static final String PROVIDER_COLUMNS_PACKAGE_NAME = "package_name";
private static final String PROVIDER_COLUMNS_ACTIVITY_NAME = "activity_name";
private static final String SONY_HOME_PROVIDER_NAME = "com.sonymobile.home.resourceprovider";
private final Uri BADGE_CONTENT_URI = Uri.parse(PROVIDER_CONTENT_URI);
private AsyncQueryHandler mQueryHandler;
@Override
public void executeBadge(Context context, ComponentName componentName,
int badgeCount) throws ShortcutBadgeException {
if (sonyBadgeContentProviderExists(context)) {
executeBadgeByContentProvider(context, componentName, badgeCount);
} else {
executeBadgeByBroadcast(context, componentName, badgeCount);
}
}
@Override
public List getSupportLaunchers() {
return Arrays.asList("com.sonyericsson.home", "com.sonymobile.home");
}
private static void executeBadgeByBroadcast(Context context, ComponentName componentName,
int badgeCount) {
Intent intent = new Intent(INTENT_ACTION);
intent.putExtra(INTENT_EXTRA_PACKAGE_NAME, componentName.getPackageName());
intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName());
intent.putExtra(INTENT_EXTRA_MESSAGE, String.valueOf(badgeCount));
intent.putExtra(INTENT_EXTRA_SHOW_MESSAGE, badgeCount > 0);
context.sendBroadcast(intent);
}
/**
* Send request to Sony badge content provider to set badge in Sony home launcher.
*
* @param context the context to use
* @param componentName the componentName to use
* @param badgeCount the badge count
*/
private void executeBadgeByContentProvider(Context context, ComponentName componentName,
int badgeCount) {
if (badgeCount < 0) {
return;
}
final ContentValues contentValues = createContentValues(badgeCount, componentName);
if (Looper.myLooper() == Looper.getMainLooper()) {
// We're in the main thread. Let's ensure the badge update happens in a background
// thread by using an AsyncQueryHandler and an async update.
if (mQueryHandler == null) {
mQueryHandler = new AsyncQueryHandler(
context.getApplicationContext().getContentResolver()) {
};
}
insertBadgeAsync(contentValues);
} else {
// Already in a background thread. Let's update the badge synchronously. Otherwise,
// if we use the AsyncQueryHandler, this thread may already be dead by the time the
// async execution finishes, which will lead to an IllegalStateException.
insertBadgeSync(context, contentValues);
}
}
/**
* Asynchronously inserts the badge counter.
*
* @param contentValues Content values containing the badge count, package and activity names
*/
private void insertBadgeAsync(final ContentValues contentValues) {
mQueryHandler.startInsert(0, null, BADGE_CONTENT_URI, contentValues);
}
/**
* Synchronously inserts the badge counter.
*
* @param context Caller context
* @param contentValues Content values containing the badge count, package and activity names
*/
private void insertBadgeSync(final Context context, final ContentValues contentValues) {
context.getApplicationContext().getContentResolver()
.insert(BADGE_CONTENT_URI, contentValues);
}
/**
* Creates a ContentValues object to be used in the badge counter update. The package and
* activity names must correspond to an activity that holds an intent filter with action
* "android.intent.action.MAIN" and category android.intent.category.LAUNCHER" in the manifest.
* Also, it is not allowed to publish badges on behalf of another client, so the package and
* activity names must belong to the process from which the insert is made.
* To be able to insert badges, the app must have the PROVIDER_INSERT_BADGE
* permission in the manifest file. In case these conditions are not
* fulfilled, or any content values are missing, there will be an unhandled
* exception on the background thread.
*
* @param badgeCount the badge count
* @param componentName the component name from which package and class name will be extracted
*
*/
private ContentValues createContentValues(final int badgeCount,
final ComponentName componentName) {
final ContentValues contentValues = new ContentValues();
contentValues.put(PROVIDER_COLUMNS_BADGE_COUNT, badgeCount);
contentValues.put(PROVIDER_COLUMNS_PACKAGE_NAME, componentName.getPackageName());
contentValues.put(PROVIDER_COLUMNS_ACTIVITY_NAME, componentName.getClassName());
return contentValues;
}
/**
* Check if the latest Sony badge content provider exists .
*
* @param context the context to use
* @return true if Sony badge content provider exists, otherwise false.
*/
private static boolean sonyBadgeContentProviderExists(Context context) {
boolean exists = false;
ProviderInfo info = context.getPackageManager().resolveContentProvider(SONY_HOME_PROVIDER_NAME, 0);
if (info != null) {
exists = true;
}
return exists;
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/VivoHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
/**
* @author leolin
*/
public class VivoHomeBadger implements Badger {
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
intent.putExtra("packageName", context.getPackageName());
intent.putExtra("className", componentName.getClassName());
intent.putExtra("notificationNum", badgeCount);
context.sendBroadcast(intent);
}
@Override
public List getSupportLaunchers() {
return Arrays.asList("com.vivo.launcher");
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/XiaomiHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.util.BroadcastHelper;
/**
* @author leolin
*/
@Deprecated
public class XiaomiHomeBadger implements Badger {
public static final String INTENT_ACTION = "android.intent.action.APPLICATION_MESSAGE_UPDATE";
public static final String EXTRA_UPDATE_APP_COMPONENT_NAME = "android.intent.extra.update_application_component_name";
public static final String EXTRA_UPDATE_APP_MSG_TEXT = "android.intent.extra.update_application_message_text";
private ResolveInfo resolveInfo;
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
try {
Class miuiNotificationClass = Class.forName("android.app.MiuiNotification");
Object miuiNotification = miuiNotificationClass.newInstance();
Field field = miuiNotification.getClass().getDeclaredField("messageCount");
field.setAccessible(true);
try {
field.set(miuiNotification, String.valueOf(badgeCount == 0 ? "" : badgeCount));
} catch (Exception e) {
field.set(miuiNotification, badgeCount);
}
} catch (Exception e) {
Intent localIntent = new Intent(
INTENT_ACTION);
localIntent.putExtra(EXTRA_UPDATE_APP_COMPONENT_NAME, componentName.getPackageName() + "/" + componentName.getClassName());
localIntent.putExtra(EXTRA_UPDATE_APP_MSG_TEXT, String.valueOf(badgeCount == 0 ? "" : badgeCount));
try {
BroadcastHelper.sendIntentExplicitly(context, localIntent);
} catch (ShortcutBadgeException ignored) {}
}
if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
tryNewMiuiBadge(context, badgeCount);
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void tryNewMiuiBadge(Context context, int badgeCount) throws ShortcutBadgeException {
if (resolveInfo == null) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
resolveInfo = context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
}
if (resolveInfo != null) {
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context)
.setContentTitle("")
.setContentText("")
.setSmallIcon(resolveInfo.getIconResource());
Notification notification = builder.build();
try {
Field field = notification.getClass().getDeclaredField("extraNotification");
Object extraNotification = field.get(notification);
Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
method.invoke(extraNotification, badgeCount);
mNotificationManager.notify(0, notification);
} catch (Exception e) {
throw new ShortcutBadgeException("not able to set badge", e);
}
}
}
@Override
public List getSupportLaunchers() {
return Arrays.asList(
"com.miui.miuilite",
"com.miui.home",
"com.miui.miuihome",
"com.miui.miuihome2",
"com.miui.mihome",
"com.miui.mihome2",
"com.i.miui.launcher"
);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/YandexLauncherBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import java.util.Collections;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
/**
* @author Nikolay Pakhomov
* created 16/04/2018
*/
public class YandexLauncherBadger implements Badger {
public static final String PACKAGE_NAME = "com.yandex.launcher";
private static final String AUTHORITY = "com.yandex.launcher.badges_external";
private static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
private static final String METHOD_TO_CALL = "setBadgeNumber";
private static final String COLUMN_CLASS = "class";
private static final String COLUMN_PACKAGE = "package";
private static final String COLUMN_BADGES_COUNT = "badges_count";
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Bundle extras = new Bundle();
extras.putString(COLUMN_CLASS, componentName.getClassName());
extras.putString(COLUMN_PACKAGE, componentName.getPackageName());
extras.putString(COLUMN_BADGES_COUNT, String.valueOf(badgeCount));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
context.getContentResolver().call(CONTENT_URI, METHOD_TO_CALL, null, extras);
}
}
public static boolean isVersionSupported(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
try {
context.getContentResolver().call(CONTENT_URI, "", null, null);
return true;
} catch (IllegalArgumentException e) {
return false;
}
}
return false;
}
@Override
public List getSupportLaunchers() {
return Collections.singletonList(PACKAGE_NAME);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/ZTEHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
public class ZTEHomeBadger implements Badger {
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount)
throws ShortcutBadgeException {
Bundle extra = new Bundle();
extra.putInt("app_badge_count", badgeCount);
extra.putString("app_badge_component_name", componentName.flattenToString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
context.getContentResolver().call(
Uri.parse("content://com.android.launcher3.cornermark.unreadbadge"),
"setAppUnreadCount", null, extra);
}
}
@Override
public List getSupportLaunchers() {
return new ArrayList(0);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/ZukHomeBadger.java
================================================
package me.leolin.shortcutbadger.impl;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import java.util.Collections;
import java.util.List;
import me.leolin.shortcutbadger.Badger;
import me.leolin.shortcutbadger.ShortcutBadgeException;
/**
* Created by wuxuejian on 2016/10/9.
* 需在设置 -- 通知和状态栏 -- 应用角标管理 中开启应用
*/
public class ZukHomeBadger implements Badger {
private final Uri CONTENT_URI = Uri.parse("content://com.android.badge/badge");
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException {
Bundle extra = new Bundle();
extra.putInt("app_badge_count", badgeCount);
context.getContentResolver().call(CONTENT_URI, "setAppBadgeCount", null, extra);
}
@Override
public List getSupportLaunchers() {
return Collections.singletonList("com.zui.launcher");
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/util/BroadcastHelper.java
================================================
package me.leolin.shortcutbadger.util;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import java.util.Collections;
import java.util.List;
import me.leolin.shortcutbadger.ShortcutBadgeException;
import me.leolin.shortcutbadger.impl.IntentConstants;
/**
* Created by mahijazi on 17/05/16.
*/
public class BroadcastHelper {
public static List resolveBroadcast(Context context, Intent intent) {
PackageManager packageManager = context.getPackageManager();
List receivers = packageManager.queryBroadcastReceivers(intent, 0);
return receivers != null ? receivers : Collections.emptyList();
}
public static void sendIntentExplicitly(Context context, Intent intent) throws ShortcutBadgeException {
List resolveInfos = resolveBroadcast(context, intent);
if (resolveInfos.size() == 0) {
throw new ShortcutBadgeException("unable to resolve intent: " + intent.toString());
}
for (ResolveInfo info : resolveInfos) {
Intent actualIntent = new Intent(intent);
if (info != null) {
actualIntent.setPackage(info.resolvePackageName);
context.sendBroadcast(actualIntent);
}
}
}
public static void sendDefaultIntentExplicitly(Context context, Intent intent) throws ShortcutBadgeException {
boolean oreoIntentSuccess = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent oreoIntent = new Intent(intent);
oreoIntent.setAction(IntentConstants.DEFAULT_OREO_INTENT_ACTION);
try {
sendIntentExplicitly(context, oreoIntent);
oreoIntentSuccess = true;
} catch (ShortcutBadgeException e) {
oreoIntentSuccess = false;
}
}
if (oreoIntentSuccess) {
return;
}
// try pre-Oreo default intent
sendIntentExplicitly(context, intent);
}
}
================================================
FILE: ShortcutBadger/src/main/java/me/leolin/shortcutbadger/util/CloseHelper.java
================================================
package me.leolin.shortcutbadger.util;
import android.database.Cursor;
import java.io.Closeable;
import java.io.IOException;
/**
* @author leolin
*/
public class CloseHelper {
public static void close(Cursor cursor) {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException var2) {
}
}
}
================================================
FILE: build.gradle
================================================
buildscript {
repositories {
jcenter()
mavenCentral()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.0'
}
ext {
POM_NAME = 'ShortcutBadger'
POM_DESCRIPTION = 'The ShortcutBadger makes your Android App show the count of unread messages as a badge on your App shortcut!'
POM_URL = 'https://github.com/leolin310148/ShortcutBadger'
POM_SCM_URL = 'https://github.com/leolin310148/ShortcutBadger'
POM_SCM_CONNECTION = 'https://github.com/leolin310148/ShortcutBadger.git'
POM_SCM_DEV_CONNECTION = 'https://github.com/leolin310148/ShortcutBadger.git'
POM_LICENCE_NAME = 'The Apache Software License, Version 2.0'
POM_LICENCE_URL = 'http://www.apache.org/licenses/LICENSE-2.0'
POM_LICENCE_DIST = 'repo'
POM_DEVELOPER_ID = 'leolin310148'
POM_DEVELOPER_NAME = 'Leo Lin'
POM_PACKAGING = 'aar'
POM_ARTIFACT_ID = 'ShortcutBadger'
VERSION_NAME = '1.1.8'
VERSION_CODE = 1
GROUP = 'me.leolin'
}
}
subprojects {
buildscript {
repositories {
jcenter()
mavenCentral()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
}
}
repositories {
jcenter()
mavenCentral()
google()
}
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Sun Apr 01 16:48:39 MSK 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-all.zip
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
include ':ShortcutBadger'
include ':SampleApp'