Открыть определенную страницу в приложении Ionic (Capacitor) из Android намерения - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть веб-приложение / приложение для Android, написанное с использованием Ionic 4 и Capacitor, и я безуспешно пытаюсь повторно ввести приложение Ionic на определенную страницу из уведомления, полученного с Androidсервис (активируется через конденсаторный плагин).

Вот код, который создает уведомление в сервисе:

private Notification getNotification() {
    CharSequence contentTitle = "Fun App Background Mode Running";
    CharSequence contentText = "Fun App";
    long notificationTime = System.currentTimeMillis();

    if (_NFC == null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationChannel channel = new NotificationChannel("funapp", "FunApp", NotificationManager.IMPORTANCE_DEFAULT);
            channel.enableLights(false);
            channel.enableVibration(false);
            channel.setSound(null,null);
            channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
            channel.setShowBadge(true);
            manager.createNotificationChannel(channel);
        }

        Intent notificationIntent = new Intent(this, MainActivity.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addNextIntentWithParentStack(notificationIntent);
        PendingIntent pendingIntent =
            stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

        _NFC = new NotificationCompat.Builder(getApplicationContext(),"funapp")
                .setSmallIcon(R.drawable.ic_sheep_notif)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_foreground))
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .setCategory(NotificationCompat.CATEGORY_SERVICE)
                .setVisibility(NotificationCompat.VISIBILITY_SECRET) 
                .setContentTitle(contentTitle)
                .setContentText(contentText)
                .setStyle(new NotificationCompat.BigTextStyle().bigText(contentText).setBigContentTitle(contentTitle))
                .setContentIntent(pendingIntent)
                .setOngoing(true);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            _NFC.setPriority(NotificationCompat.PRIORITY_LOW);
        }
    }

    _NFC.setContentTitle(contentTitle);
    _NFC.setContentText(contentText);
    _NFC.setStyle(new NotificationCompat.BigTextStyle().bigText(contentText).setBigContentTitle(contentTitle));
    _NFC.setWhen(notificationTime);
    return _NFC.build();
}

Я считаю, что мне нужно поместить что-то в / около линии new Intent(this, MainActivity.class)чтобы заставить Capacitor / Ionic инициализировать приложение в нужном состоянии, но я не могу понять, что это должно быть!

Я изучил документацию Capacitor и не смог найти решение до сих пор, яесть подозрение, что мне нужно отправить намерение «просмотра» в действие с каким-то URL-адресом?

В настоящее время он запускает то, что кажется совершенно новым экземпляром приложения (- загружает заставку и т. д.), даже если приложение по-прежнему является приоритетной задачей на телефоне.

ОБНОВЛЕНИЕ

Моя последняя попытка - создатьнамерение, подобное этому:

Intent notificationIntent = new Intent(Intent.ACTION_VIEW,
    Uri.parse("http://localhost/event/horse"),
    this, MainActivity.class);

(при условии, что у меня есть действительный маршрут в Ionic / Angular для / event / horse, что я и делаю)

Без изменений, это все равно выражаеттакое же поведение, как описано выше (повторный вход в заставку).

1 Ответ

0 голосов
/ 02 марта 2019

Чтобы реализовать это поведение, необходимы три разные части.

Во-первых, ваш Angular / Ionic код должен подключаться к событиям из плагина Capacitor App и выполнять навигацию при вызове с открытым URL,например:

import { Plugins, AppUrlOpen } from '@capacitor/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  constructor(
    private platform: Platform,
    private router: Router
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      if (this.platform.is('capacitor')) {
        Plugins.SplashScreen.hide();

        // THIS WILL BE USED IF THE APP IS ALREADY OPEN:
        Plugins.App.addListener('appUrlOpen', (urlOpen: AppUrlOpen) => {
          console.log('App URL Open', urlOpen);
          this.navigate(urlOpen.url);
        });
      }

      // THIS WILL BE USED IF THE APP HAS BEEN KILLED AND RE-OPENED:
      this.getLaunchUrl();
    });
  }

  async getLaunchUrl() {
    const urlOpen = await Plugins.App.getLaunchUrl();
    if(!urlOpen || !urlOpen.url) return;
    console.log('Launch URL', urlOpen);
    this.navigate(urlOpen.url);
  }

  navigate(uri: string) {
    // THIS MUST EQUAL THE 'custom_url_scheme' from your Android intent:
    if (!uri.startsWith('net.exampleapp.app:/')) return;
    // Strip off the custom scheme:
    uri = uri.substring(19);
    this.router.navigateByUrl(uri);
  }
}

Затем, на стороне Android, это заклинание, необходимое для получения PendingIntent, чтобы вызвать это поведение:

Intent notificationIntent = getPackageManager()
        .getLaunchIntentForPackage(getPackageName())
        .setPackage(null)
        .setAction(Intent.ACTION_VIEW)
        .setData(Uri.parse(
            getResources().getString(R.string.custom_url_scheme) + 
            "://events/" + _EventId))
        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 1234,
        notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Наконец, в AndroidManifest.xml дляваше приложение, вы также должны указать режим запуска как SingleTask или SingleTop для MainActivity (либо кажутся работающими):

<activity
        android:name=".MainActivity"
        android:launchMode="singleTask"

  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
        android:label="@string/title_activity_main"
        android:theme="@style/AppTheme.NoActionBarLaunch">

При этой комбинации, если приложение все еще работает, соответствующая страница будет перемещена направильно, и если оно не запущено, приложение будет открыто, а затем страница перейдет к.

Обратите внимание, однако, что это не устанавливает «задний» стек внутри приложения Ionic в случае, когда приложение не было запущено, поэтому обратный удар не будет автоматически перемещаться вверх.Но это другая проблема ...

...