简体   繁体   English

如何从(前台服务)通知启动主应用程序?

[英]How to start Main App from (Foreground Service) Notification?

My App starts an background Service and adds a Notification - all working fine except that i can't figure out how to launch my App when the user clicks the Notification...我的应用程序启动后台服务并添加一个通知 - 一切正常,除了当用户单击通知时我无法弄清楚如何启动我的应用程序......
(i need a correct JPendingIntent...) (我需要一个正确的 JPendingIntent...)

Here is my Source for SetForground Procedure, called in OnStartCommand:这是我在 OnStartCommand 中调用的 SetForground 过程的来源:

Procedure TDatasnapServiceModule.SetForeground(aTitle, aText: String; aNr: Integer);
    var service            : JService;
        serviceObjectId    : Pointer;
        ntf                : JNotification;
        intent             : JIntent;
        PendingIntent      : JPendingIntent;
    begin
      serviceObjectId := (JavaService as ILocalObject).GetObjectID;
      service         := TJService.Wrap(serviceObjectId);
      ntf             := TJNotification.Create;
      ntf.icon        := service.getApplicationInfo.icon;
      if aNr > 0 then
        ntf.Number    := aNr;
    // empty intent, works but App is not started/activated (of course...)
      intent  := TJIntent.Create;

    // what to put into this intent so my App launches when user clicks?

      PendingIntent := TJPendingIntent.JavaClass.getActivity(service.getApplicationContext, ServiceID, intent, 0);
      ntf.setLatestEventInfo(service.getApplicationContext, StrToJCharSequence(aTitle), StrToJCharSequence(aText), PendingIntent);
      service.startForeground(NotifyID, ntf);
    end;

Create foreground notification and add pendingIntent创建前台通知并添加pendingIntent

  fun createForegroundNotification(account: Account): Notification {
    val notification = NotificationCompat.Builder(mContext, ID)
            .setOngoing(true)
            .setAutoCancel(false)
            .setContentIntent(createMainActivityIntent())
            .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(),
                    R.mipmap.ic_launcher))
            .setContentTitle(mContext.getResources().getString(R.string.app_name))
            .setCategory(Notification.CATEGORY_SERVICE)
            .setVisibility(Notification.VISIBILITY_PRIVATE)
            .setWhen(0)
            .setColor(mContext.getResources().getColor(R.color.colorPrimary))
    return notification.build()
}

Content intent code内容意图代码

   private fun createMainActivityIntent(): PendingIntent {
    val intent = Intent(mContext, MainActivity::class.java)
    return PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}

You can use this code for get main class:您可以使用此代码获取主类:

private static Class getMainActivityClass(Context context) {
    String packageName = context.getPackageName();
    Intent launchIntent = 
         context.getPackageManager().getLaunchIntentForPackage(packageName);
    String className = launchIntent.getComponent().getClassName();
    try {
        return Class.forName(className);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return null;
    }
}

And use this class in for this pendingIntent :并将这个类用于这个 pendingIntent :

int yourRequestCode  = 66 ;
Intent resultIntent = new Intent(this, getMainActivityClass(this));
        PendingIntent pendingIntent = 
            PendingIntent.getActivity(this,yourRequestCode, 
                 resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

And finally use this pending intent in最后使用这个待定的意图

.setContentIntent .setContentIntent

of your notification.您的通知。

I'm just going to paste my code here.我只是要在这里粘贴我的代码。 There's too much to discuss it in detail.有太多要详细讨论的。 Hopefully you'll just see the bit you have been missing, or what you might need to change in your own code, so that I don't have to do that for you.希望您能看到您遗漏的部分,或者您可能需要在自己的代码中更改哪些内容,这样我就不必为您做这些了。

function TMainService.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
var
  ExtraData: String;
{$ifdef FOREGROUND}
  NewIntent: JIntent;
  ncb: JNotificationCompat_Builder;
  ntf: JNotification;
  PendingIntent: JPendingIntent;
{$endif}
begin

  // called EVERY TIME the service starts or automatically restarts
  LogMe('Startservice called');

  // Using NOT STICKY so the service gets automatically closed when the host closes
  // not need to try stopservice anymore :-)
  Result := TJService.JavaClass.START_NOT_STICKY;

  {$ifdef FOREGROUND}
    {$ifdef ORDINARY_NOTIFICATION}
    // unclickable
    PendingIntent := TJPendingIntent.JavaClass.getActivity(
      JavaService.getApplicationContext, 0, Intent, 0
      );
    ntf := TJNotification.Create;
    ntf.icon := JavaService.getApplicationInfo.icon;
    ntf.setLatestEventInfo(
      JavaService.getApplicationContext,
      StrToJCharSequence('Tracker Service'),
      StrToJCharSequence('Communications Service'), PendingIntent);
    {$else}
    // ALL THIS code is to make the host come to foreground when the user taps
    // the permanent notification
    // thanks to:
    // https://forums.embarcadero.com/message.jspa?messageID=847227
    // https://gist.github.com/kristopherjohnson/6211176

    NewIntent:= TAndroidHelper.Context.getPackageManager().getLaunchIntentForPackage(
      TAndroidHelper.Context.getPackageName());
    NewIntent.setAction(TJIntent.JavaClass.ACTION_MAIN);
    NewIntent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
    NewIntent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent := TJPendingIntent.JavaClass.getActivity(
      TAndroidHelper.Context, 0, NewIntent,
      TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK
      );

    ncb := TJNotificationCompat_Builder.JavaClass.init(TAndroidHelper.Context);
    ncb.setContentTitle(StrToJCharSequence('GroupTracker Service'));
    ncb.setTicker(StrToJCharSequence('Communications Service'));
    ncb.setSmallIcon(JavaService.getApplicationInfo.icon);
    ncb.setContentIntent(PendingIntent);
    ncb.setOngoing(True);
    ntf := ncb.build;
    {$endif}
    LogMe('Start foreground called');
    JavaService.startForeground(StartId, ntf);
  {$endif}

  {$ifdef STOPSELF}
  LogMe('stopSelf');
  // this actually queues the stop request until the host stops running
  // almost like START_NOT_STICKY really
  JavaService.stopSelf(StartId);
  // using unbind and stop instead, thanks
  {$endif}

  if Intent <> nil then
  begin
    ExtraData := TAndroidHelper.JStringToString(
      Intent.getStringExtra(TAndroidHelper.StringToJString('ExtraData')));
    LogMe('ExtraData=' + Extradata);
  end;

end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM