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

时间:2018-05-23 10:22:28

标签: android delphi

我的应用程序启动后台服务并添加通知 - 所有工作正常,但我无法弄清楚当用户点击通知时如何启动我的应用程序...
(我需要一个正确的JPendingIntent ...)

这是我在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;

3 个答案:

答案 0 :(得分:1)

创建前台通知并添加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()
}

内容意图代码

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

答案 1 :(得分:0)

我要在这里粘贴我的代码。详细讨论它太多了。希望您能够看到自己遗失的内容,或者您​​可能需要在自己的代码中进行更改的内容,以便我不必为您做到这一点。

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;

答案 2 :(得分:0)

您可以使用以下代码获取主类:

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

并在该类中使用该未决意图:

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

最后在此使用待定意图

.setContentIntent

您的通知。