当前位置: 首页 > 知识库问答 >
问题:

从Android intent打开离子(电容器)应用程序中的特定页面

王经赋
2023-03-14

我有一个Web/android应用程序,使用Ionic 4和电容器编写,我一直试图从Android服务(通过电容器插件激活)发出的通知中重新进入Ionic应用程序到特定页面,但没有成功。

以下是在服务中创建通知的代码:

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();
}

我认为我需要在新的意图(这个,MainActivity.class)中/周围添加一些东西,以使电容器/离子电池将应用程序初始化到正确的状态,但我无法确定应该是什么!

我浏览了电容器文档,到目前为止还没有找到解决方案,我怀疑我需要用某种URL向活动发送“视图”意图?

当前的行为是让它启动一个看似全新的应用程序实例(它会重新加载启动屏幕等),即使该应用程序仍然是手机上的前台任务。

更新

我最近的尝试是创建这样的意图:

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

(假设我在Ionic/Angular for/event/horse中设置了有效的路由,我会这样做)

虽然没有改变,但这仍然表示与上述相同的行为(重新进入启动屏幕)。

共有1个答案

沈宏朗
2023-03-14

为了实现这种行为,需要三个不同的部分。

首先,您的Angular/Ionic代码必须挂接电容器应用程序插件中的事件,并在使用打开的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端,这是获得一个PendingEvent来触发此行为所需的咒语:

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 for Mainactive(两者似乎都有效):

<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应用程序中合理地设置“后退”堆栈,因此回击不会自动向上导航。但这是另一个问题。。。

 类似资料:
  • 我在Ionic 6框架、Angular和Capacitor中为Android开发了一个应用程序 该应用程序从主页开始,当我单击登录按钮时,代码会在外部浏览器(例如Chrome或Firefox)中打开Microsoft链接。我进行登录,当成功时,它会将我发送回带有url的外部浏览器localhost:8100并且不会进一步。我想问是否有人可以帮助我在应用程序内部集成登录功能,而无需返回localho

  • 问题内容: 我的应用程序中有一个快捷方式,可以打开系统设置的存储部分(工作正常),但是如果设置应用程序已在运行,并且在显示设置的最后离开位置,则您不会直接进入存储设备设置,但按快捷键时显示设置。 有没有办法在尝试启动存储之前强制打开存储设置,或者说关闭(如果未关闭)设置应用程序? 我正打算开始活动。 问题答案: 尝试在您的意图上设置以下标志:

  • 我们有一个非常常见的用例与我们的(通过电容器)Android生成的应用程序:一旦它通过例如Websocket(或第三方应用程序,如OneSignal,Firebase等)接收到消息,我们希望将应用程序带到前台,以防用户当前与其他应用程序(如Skype,Whatsapp等)进行交互。原因是我们已经实现了“警报”场景,如果警报进入,应用程序应该出现在前面并显示正在发生的事情。简单的推送通知在这里无法完

  • 我最近将我的旧Cordova iOS/Android项目迁移到了Caperaction,到目前为止我对此非常满意。但是,在尝试使用电容器文档Capable-Community/AdMob中推荐的AdMob插件时遇到了困难,因为该插件的文档只显示了ionic与angular或ionic与React的示例。我没有使用任何一个框架,因为这个项目是在这个生态系统之外开始的,所以我在看这个Ionic/Rea

  • 我有一个电子应用程序,可以在单独的选项卡中编辑多个文件,比如Atom或VS代码。当通过对话框打开文件时,或者当应用程序未运行(通过解析argv)时,通过“打开方式”打开文件时,此功能可以正常工作。 然而,我不知道如何将通过“打开”打开的文件“添加”到已经运行的应用程序——默认情况下,会创建该应用程序的第二个新实例。我希望能够以某种方式将文件的路径传递给原始应用实例。 我浏览了文档,发现唯一有希望的

  • 我正在用电容器来构建Ionic应用程序。以下是在android Studio中打开android应用程序时运行的命令。 在Android Studio中,我运行了构建并单击Run,然后在我的设备中看到错误。我见过很多帖子都有相同的错误,但是那些帖子都是用build发布的。就我而言,我没有使用Cordova来准备android应用程序。 下面是我的Ionic应用程序的一些摘录。