【问题标题】:Android notification with RemoteViews - having activity associated with RemoteViews layout带有 RemoteViews 的 Android 通知 - 具有与 RemoteViews 布局关联的活动
【发布时间】:2014-03-23 00:56:42
【问题描述】:

我一直在研究如何使用RemoteView 创建自定义布局通知。

到目前为止,我能够创建一个通知,其中 contentViewbigContentView 指向带有自定义布局 xml 的 RemoteView。但是,不会发生的情况是在创建此 RemoteView 时启动 Activity(与自定义布局相关联)。

我已经仔细检查并在我的布局 xml 中,它似乎有正确的 Activity 类名:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="0dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    tools:context=".LLMNotificationActivity" >

..... the rest are standard layout items: images, buttons and text

</RelativeLayout>

在清单文件中,在主应用程序主活动之后,还添加了通知活动:

<activity
    android:name=".LLMNotificationActivity"
    android:label="@string/app_name">
    <intent-filter>
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

我希望当通知使用RemoteView 作为其内容时,此RemoteView 将启动附加到其布局定义的活动。然而它似乎没有。

这是我在主应用程序Activity 中创建通知的方法:

protected void startNoti() {
    if( noti!=null ) return;

    Context context = getApplicationContext();  

    RemoteViews contentView = new RemoteViews(context.getPackageName(),R.layout.activity_noti1);

    Notification.Builder notibuilder = new Notification.Builder(context);
    notibuilder.setContentTitle(" ");
    notibuilder.setContentText(" ");
    notibuilder.setSmallIcon(R.drawable.ic_launcher);
    notibuilder.setOngoing(true);

    manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    noti = notibuilder.build();

    noti.contentView = contentView;

    manager.notify(NOTIFICATION_ID, noti);  
}

LLMNotificationActivity活动类照常定义:

public class LLMNotificationActivity extends Activity {
    .... etc.... constructor, some button on-click handlers, nothing spectacular...
}

谁能指出我缺少什么或者我误解了RemoteView 可以做什么?我的理解是RemoteView 应该在创建后调用与其布局关联的活动。或者 - 是否有一些我错过的 API 可以明确设置 RemoteView 的意图?

到目前为止,我发现的只是设置内容Intent,它基本上只是在用户触摸通知时启动Activity。我正在寻找的是在自定义布局通知中处理对某些 UI 元素的触摸,而不是在用户单击通知表面的哪个位置时启动 Activity

例如,如果我在通知使用的RemoteView 中有 3 个图标(即ImageView),我希望能够处理每个图标的触摸。我无法想象这是不可能的,如果不是,那么在通知中添加RemoteView 有什么意义?

【问题讨论】:

  • tools Manifest 中的 XML 属性仅影响工具(即,根据声明的 tools:context 在 IDE 中查看布局预览时提供正确的主题)。它们在运行时没有影响。
  • 感谢您的指出。 XML 是由我的 IDE 自动生成的。

标签: java android notifications android-activity remoteview


【解决方案1】:

您必须关联活动想法setOnClickPendingIntent 才能从远程视图启动活动,如下所示...您可以在RemoteView 中设置任何布局ID 以单击。

 Intent intent = new Intent(context, YourActivity.class);
 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,   PendingIntent.FLAG_UPDATE_CURRENT);
 RemoteViews removeWidget = new RemoteViews(context.getPackageName(), R.layout.your_layout);
 removeWidget.setOnClickPendingIntent(R.id.layout_id, pendingIntent);

为您使用的RelativeLayout 提供+id/layout_id

如果你必须在用户点击通知时启动活动,那么你必须使用PendingIntent as....

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setContentTitle("title")
                    .setContent(mRemoteControl);
    Intent notificationIntent = new Intent(this, YourActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(
            this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    mBuilder.setContentIntent(contentIntent);
    mNM.notify(1000,mBuilder.build());

对于 3 个按钮,您必须使用创建自定义 RemoteView 并使用 PendingIntent。下面的一些东西......

这是我用于我的媒体播放器应用程序之一的自定义远程视图。它有三个按钮来处理点击。

public class RemoveControlWidget extends RemoteViews
{
private final Context mContext;

public static final String ACTION_PLAY = "com.mediabook.app.ACTION_PLAY";

public static final String ACTION_PREVIOUS = "com.mediabook.app.ACTION_PREVIOUS";

public static final String ACTION_NEXT = "com.mediabook.app.ACTION_NEXT";

public RemoveControlWidget(Context context , String packageName, int layoutId)
{
    super(packageName, layoutId);
    mContext = context;
    Intent intent = new Intent(ACTION_PLAY);
    PendingIntent pendingIntent = PendingIntent.getService(mContext.getApplicationContext(),100,
            intent,PendingIntent.FLAG_UPDATE_CURRENT);
    setOnClickPendingIntent(R.id.play_control,pendingIntent);
    setOnClickPendingIntent(R.id.pause_control,pendingIntent);
    intent = new Intent(ACTION_PREVIOUS);
    pendingIntent = PendingIntent.getService(mContext.getApplicationContext(),101,
            intent,PendingIntent.FLAG_UPDATE_CURRENT);
    setOnClickPendingIntent(R.id.previous_control,pendingIntent);
    intent = new Intent(ACTION_NEXT);
    pendingIntent = PendingIntent.getService(mContext.getApplicationContext(),102,
            intent,PendingIntent.FLAG_UPDATE_CURRENT);
    setOnClickPendingIntent(R.id.next_control,pendingIntent);
}
}

【讨论】:

  • 这是否意味着不可能有与用于 RemoteViews 的布局相关联的活动?
  • 检查我更新的答案。希望这就是你的样子
  • 谢谢,但正如我所解释的,我不想在点击通知时启动活动。我正在看你的第二部分,会尽快回复评论。
  • 检查我更新的答案。使用第一部分。您可以将活动与远程视图相关联。希望这是您的要求。
  • 我已经接受了你的回答,准确地说是最后一部分 - 使用自定义 RemoteViews 类。然而,我添加了一个广播而不是服务,并使我的扩展 RemoteViews 类来监听特定的广播消息 - 所以我可以将所有 UI 应用程序逻辑保留在一个对象实例中,而不是运行/访问服务。这也是因为当用户单击某些选项时,我需要对 UI 进行更改。基本上我的通知现在像一个小活动一样运行 :-) 感谢您的宝贵意见!
【解决方案2】:

您只需将setContentIntent 添加到您的 Notification.Builder 中,如下所示:

Intent i = new Intent(context, YourLaunchedActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, 0);
Notification.Builder notibuilder = new Notification.Builder(context);
notibuilder.setContentIntent(pendingIntent);

现在,当您点击通知时,YourLanchedActivity 将启动。

【讨论】:

    【解决方案3】:

    *您可以通过执行以下操作来实现单击远程视图的挂起意图 还要注意 如果您尝试从远程视图获取活动,则 getAcitvity 用于挂起的意图 喜欢 *

    //i will create a simple method//
           //use return getActivity cause getting the bottom Activity
    private static PendingIntent getActivityBottom(Context context) {
        clearNotification(context);
    
        Intent intentStartActivity = new Intent(context, BotomNavViewActivity.class);
        intentStartActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //intentStartActivity.addFlags(/*Intent.FLAG_ACTIVITY_CLEAR_TASK |*/ Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        return PendingIntent.getActivity(
                context,
                2,
                intentStartActivity,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }
    
    public static void clearNotification(Context context) {
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(NOTIFICATION_ID);
    }
     
    

    现在,如果您想获取服务类,请在待处理意图中使用 getService

    private static PendingIntent stopPlayer(Context context){
        Intent serviceIntent = new Intent(context, MusicService.class);
        
               serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
               context.stopService(serviceIntent);
               mContentView.setImageViewResource(R.id.notif_play, R.drawable.ic_play);
            
    
        return PendingIntent.getService(
                context,
                2,
                serviceIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }
    

    像这样使用上面的方法

      //perfoam action on notification to go to activity
        mContentView.setOnClickPendingIntent(R.id.notif_small,getActivityBottom(context));
    
        //for service
        mContentView.setOnClickPendingIntent(R.id.notif_play,stopPlayer(context));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 2014-02-05
      • 2023-03-26
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多