Badge on app icon for Android doesn't show eve

2019-05-30 01:09发布

问题:

I will really appreciate if anyone can help me with this issue that has been bugging me for days.

I have a hybrid app created using the Ionic framework, which I have implemented push notifications on (via phonegap-plugin-push). The push notifications work fine, but what I want is for the push notification (i.e. GCM payload) to send a badge count/number over to the application, and the application will take that count/number and displays it as a badge beside the app icon. My code works perfectly for iOS devices given that badges are already inbuilt, but I have difficulties with implementing the same idea (badges) on the Android platform.

I am aware that due to badges not being inbuilt into the Android platform, some devices might not be supported, but at least I want it to work for some devices (i.e. Samsung, Sony). I have done a lot of research, most prominently:

  1. cordova-plugin-badge (https://github.com/katzer/cordova-plugin-badge) which stated in the documentation is supposed to work for both iOS and certain Android devices, but it doesn't work on any Android devices at all for me. Note that the Android devices I have been testing on are emulators from Genymotion, which I have set up Google Play Services on and are able to receive push notifications and function almost like a real device, will that be an issue?

  2. ShortcutBadger (https://github.com/leolin310148/ShortcutBadger) which only has documentation for native Android implementation and supposedly utilised by cordova-plugin-badge as stated above to extend the support to hybrid Android apps, but this has been unable to help me at all.

My index.html:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="css/style.css" rel="stylesheet">

    <script src="lib/ionic/js/ionic.bundle.js"></script>
    <script src="lib/ionic-platform-web-client/dist/ionic.io.bundle.min.js"></script>

    <script src="js/ng-cordova.js"></script>
    <script src="cordova.js"></script>

    <script src="js/app.js"></script>

  </head>
  <body ng-app="starter">
    <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Trade Deals</h1>
      </ion-header-bar>
      <ion-content ng-controller="badgeController">
        <div>Number of deals pending now: </div>
        <div class="deals"></div>
        <button class="button" ng-click="setBadge(10)">Set badge 10</button>
        <button class="button" ng-click="hasPermission()">Show permission</button>
        <button class="button" ng-click="get()">Get badge count</button>
        <button class="button" ng-click="clear()">Clear badge count</button>
        <button class="button" ng-click="increase()">Increase by 1</button>
        <button class="button" ng-click="decrease()">Decrease by 1</button>
      </ion-content>
    </ion-pane>
  </body>
</html>

My app.js:

angular.module('starter', ['ionic', 'ngCordova'])

/*
 * do a ionic.push register() every time the app launches for the first time
 * so that it is guaranteed that there is always a valid device token for GCM/APNS
 */
.run(function($ionicPlatform, $cordovaBadge) {
  $ionicPlatform.ready(function() {
    console.log("Device platform is "+device.platform);
    var push = new Ionic.Push({
      "debug": true,
      "onNotification": function(notification) {
        console.log("notification received!!!");
        var payload = notification.payload;
        var payloadStr = JSON.stringify(payload, null, 4);
        var notiStr = JSON.stringify(notification, null, 4);
        console.log("notification: "+notiStr);

        var countIndex = notiStr.indexOf("count");  // extracting badge count from the GCM payload
        var badgeIndex = countIndex + 9;
        var badgeNo;
        if (!isNaN(notiStr[badgeIndex+1])) {
          badgeNo = notiStr.substr(badgeIndex,badgeIndex+2);
        }
        else {
          badgeNo = notiStr[badgeIndex];
        }

        if (device.platform == "Android") {
          $cordovaBadge.set(badgeNo);
        }
      },
      "onRegister": function(data) {
        console.log(data.token);
      },
      "pluginConfig": {
        "android": {
          "sound": "true",
          "badge": "true",
          "icon": "icon",
          "iconColor": "lime"
        },
        "ios": {
          "alert": "true",
          "badge": "true",
          "sound": "true"
        },
      }
    });

    push.register(function(token) {
      console.log("My Device token:",token.token);
      //window.alert("The token is "+token.token);
      push.saveToken(token);  // persist the token in the Ionic Platform so that it doesn't change on multiple launches
    });

    $cordovaBadge.get().then(function(badge) {
      document.querySelector(".deals").innerHTML = badge;
    });
  });
})

.controller("badgeController", function($scope, $ionicPlatform, $cordovaBadge) {
    console.log("inside badgeController");

    $ionicPlatform.ready(function() {
        $ionicPlatform.on('resume', function() {
          $cordovaBadge.get().then(function(badge) {
            document.querySelector(".deals").innerHTML = badge;
          });
        });
        //$cordovaBadge.configure({autoClear: true});  // configure to clear all notifications whenever user opens the app
        $scope.setBadge = function(value) {
          console.log("inside setBadge");
          $cordovaBadge.hasPermission().then(function(result) {
              $cordovaBadge.set(value);
              window.alert("Badge count is "+value);
          }, function(error) {
              console.log(JSON.stringify(error));   // display error message
          });
        }

        $scope.hasPermission = function() {
          console.log("inside hasPermission");
          $cordovaBadge.hasPermission().then(function(result) {
              window.alert("User has permission: "+result);
              console.log("device has permission");
          }, function(error) {
              console.log(JSON.stringify(error));   // display error message
          });
        }

        $scope.get = function() {
          console.log("inside get");
          $cordovaBadge.hasPermission().then(function(result) {
              $cordovaBadge.get().then(function(badge) {
                if (badge>=0) {
                  document.querySelector(".deals").innerHTML = badge;
                }
              })
          }, function(error) {
              console.log(JSON.stringify(error));   // display error message
          });
        }

        $scope.clear = function() {
          console.log("inside clear");
          $cordovaBadge.hasPermission().then(function(result) {
              $cordovaBadge.clear();
              window.alert("Cleared badge count");
          }, function(error) {
              console.log(JSON.stringify(error));   // display error message
          });
        }

        $scope.increase = function() {
          console.log("inside increase");
          $cordovaBadge.hasPermission().then(function(result) {
              $cordovaBadge.increase();
              window.alert("Increased badge count");
          }, function(error) {
              console.log(JSON.stringify(error));   // display error message
          });
        }

        $scope.decrease = function() {
          console.log("inside decrease");
          $cordovaBadge.hasPermission().then(function(result) {
              $cordovaBadge.decrease();
              window.alert("Good job!");
              //window.alert("Decreased badge count");
          }, function(error) {
              console.log(JSON.stringify(error));   // display error message
          });
        }
    });
});

Also, is the issue that the app icon has to be converted to a widget in order for the badges to work? I am not sure how the cordova-plugin-badge is implemented and the instructions didn't say anything about widgets being needed for Android.

Thank you and any help/tips is appreciated :) I have been troubleshooting this for days and it's rather frustrating.

回答1:

Stock Android does not offer this functionality at the moment on the standard launcher.

Certain manufacturers (e.g. Samsung notably) have included this functionality into their customised Android launchers. Also some 3rd-party launchers (e.g. Nova Launcher) have included an API to accomplish this.

You may want to check following links for further explaination:

  1. How does Facebook add badge numbers on app icon in Android?
  2. Does Samsung modifies it's Android ROMs to have badges on email and SMS icons?
  3. How to make application badge on android?

Regards