ionic-team / capacitor-plugins

Official plugins for Capacitor ⚡️
498 stars 574 forks source link

feat: capacitor localnotification image is not showing #430

Open armanhadifatah opened 4 years ago

armanhadifatah commented 4 years ago

Bug Report

Latest Dependencies:

@capacitor/cli: 1.4.0

@capacitor/core: 1.4.0

@capacitor/android: 1.4.0

@capacitor/ios: 1.4.0

Affected Platform(s)

I tested it on Android and web also

Current Behavior

when showing notification no image is shown in the notification

Expected Behavior

when adding url and id to attachments it should show image in notification

Sample Code or Sample Application Repo

 LocalNotifications.schedule({
      notifications: [
        {
          title: "aaaa",
          body: "Body",
          id: 1,
          actionTypeId: 'OPEN_PRODUCT',
          attachments: [
            { id: 'face', url: 'https://khanoo.com/wp-content/uploads/estate_images/house/77-1576179614/230174.jpg' }
          ],
          schedule: {
            every: "minute"
          },

          extra: null
        }
      ]
    });

Reproduction Steps

Just test my code which i provided to see if you can see image or not

Other Technical Details

npm --version output: 6.13.4

node --version output: v12.13.1

pod --version output (iOS issues only): 1.9.0.beta.2

jcesarmobile commented 4 years ago

http/https urls are not supported by iOS (native API limitation)

on Android and Web the attachments are not shown as images, should be implemented

malekian78 commented 2 years ago

i think attachments is not work for android.... for android you can use "largeIcon:" property to show your image first copy your image in res/drawable folder (not in 'res' only) and then write the name of your image in largeIcon........for example: i copy my 'manager.png' in 'android\app\src\main\res\drawable' then in my code: LocalNotifications.schedule({ notifications: [ { title: 'the title', body: 'msg body', id: 1, largeIcon:'manager', smallIcon:'manager' } ] }); it's look small but i think it much better than nothing.....

ivanov84 commented 2 years ago

If someone wants to show big image with notification then you need to add this code at line 185 in LocalNotificationManager.java:

if (localNotification.getAttachments() != null) {
  mBuilder.setStyle(
    new NotificationCompat.BigPictureStyle()
      .bigPicture(localNotification.getBigImage(context))
    );
}

And this code at line 386 in LocalNotifications.java:

import android.net.Uri;
...
public Bitmap getBigImage(Context context) {
  if (attachments != null && attachments.size() > 0) {
    try {
      LocalNotificationAttachment bp = attachments.get(0);
      String bpUrl = bp.getUrl();
      final AssetUtil assets = AssetUtil.getInstance(context);
      Uri uri = assets.parse(bpUrl);
      if (uri != Uri.EMPTY) {
        return assets.getIconFromUri(uri);
      }
    } catch (Exception e){
      e.printStackTrace();
    }
  }
  return null;
}

And also you need to fix a bug in a capacitor file node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/AssetUtil.java at line 328:

change from

String authority = context.getPackageName() + ".provider";

to

String authority = context.getPackageName() + ".fileprovider";

And at line 106:

change from

String resPath = path.replaceFirst("file:/", "www").replaceFirst("\\?.*$", "");

to

String resPath = path.replaceFirst("file:/", "public").replaceFirst("\\?.*$", "");

Then these links (url: 'file://assets/notifications/preview.jpg') will work in your javascript scheduling code:

{
    id: 666,
    largeIcon: bigIcon,
    schedule: { at: rem },
    title: title,
    body: text,
    largeBody: text,
    attachments: [{ id: 'my_preview', url: 'file://assets/notifications/preview.jpg' }]
}

Also that plugin architecture is too ill-considered and I see error !!! FAILED BINDER TRANSACTION !!! when load standard images that worked fine with katzer plugin.

In order to fix somehow, I added compression in capacitor file node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/plugin/util/AssetUtil.java at line 259:

InputStream stream = context.getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeStream(stream, null, options);

Instead of that:

InputStream input = context.getContentResolver().openInputStream(uri);
return BitmapFactory.decodeStream(input);

P.S.: But bigImage should be no more then 512x256 and largeIcon no more then 256x256

frederikheld commented 2 years ago

for android you can use "largeIcon:" property to show your image first copy your image in res/drawable folder (not in 'res' only) and then write the name of your image in largeIcon.

Is there any way to use a base64 encoded image from a variable instead? I'd like to display a profile picture as largeImage that was previously uploaded by the user and stored in Vuex as a bas64 encoded string.

ivanov84 commented 2 years ago

@frederikheld yes. Just edit the source code like I did for bigImage.

frederikheld commented 2 years ago

So I need to fork the repo and build my own version of the plugin you say? That's something I tried to avoid tbh because I'm not that much into Java. Would you care to submit your code as a PR to this repo in order to fix the issue / add this feature?

ivanov84 commented 2 years ago

@frederikheld I edited code directly in node_modules.

All you need - it's just pass base64 string via any property and convert it with java code:

byte[] decodedString = Base64.decode(base64ImageString, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return decodedByte;
frederikheld commented 2 years ago

Editing the code directly in node_modules is the worst advice you could give to anyone who tries to write software on a level that is above script kiddie 😖 How would you deal with updates? How would you make that portable? How would you make it reproducible? The whole point of packaging systems like npm is to only share a list of well defined dependencies which makes it easy to update, move around and reproduce. Fiddling around in node_modules breaks all of this...

frederikheld commented 2 years ago

But apart from that: your code only needs some if clause that checks what image format is incoming in order to make it compatible with the current source, then you could submit it as a pull request so it could go into the package in the regular way. I would appreciate that very much!

ivanov84 commented 2 years ago

@frederikheld I am entrepreneur and I need that things works. Then I look at revenue. I just said how to make things work. I really want to make PR but I have no time...

alexd2580-sf commented 1 year ago

Is there any sensible progress on this issue?

frederikheld commented 1 year ago

I am entrepreneur and I need that things works. Then I look at revenue. I just said how to make things work.

Doesn't look like a good strategy to generate long-term revenue tbh. Beware of the day when all of this falls on your feet and you're in full fire fighting mode :-P But you do you ...

@alexd2580-sf: I'm currently working on a different project, but if I get back to this one, I might submit the PR. But can't say how long until then, so if you need it, go ahead ;-)

Erudition commented 1 year ago

How would you deal with updates? How would you make that portable? How would you make it reproducible?

Actually, there's an easy way with e.g. pnpm, you have the patch command. So you can make changes to modules that get applied as a patch every time (reproducible) even with updates, yet are stored locally in your project (portable).

MarcelSchuermann commented 3 months ago

Any news here?