알림 클릭에서 활동으로 매개 변수를 보내는 방법은 무엇입니까?


206

알림에서 내 활동에 매개 변수를 보내는 방법을 찾을 수 있습니다.

알림을 생성하는 서비스가 있습니다. 사용자가 알림을 클릭하면 몇 가지 특수 매개 변수로 주요 활동을 열고 싶습니다. 예를 들어 항목 ID이므로 내 활동이 특수 항목 세부 정보보기를로드하고 표시 할 수 있습니다. 더 구체적으로, 나는 파일을 다운로드하고 있으며, 파일을 다운로드 할 때 클릭 할 때 내 활동을 특수 모드로 여는 의도를 갖기를 원합니다. putExtra내 의도에 따라 사용하려고 시도했지만 추출 할 수 없으므로 잘못하고 있다고 생각합니다.

알림을 생성하는 서비스 코드 :

        // construct the Notification object.
     final Notification notif = new Notification(R.drawable.icon, tickerText, System.currentTimeMillis());


    final RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);
    contentView.setImageViewResource(R.id.image, R.drawable.icon);
    contentView.setTextViewText(R.id.text, tickerText);
    contentView.setProgressBar(R.id.progress,100,0, false);
    notif.contentView = contentView;        

    Intent notificationIntent = new Intent(context, Main.class);
    notificationIntent.putExtra("item_id", "1001"); // <-- HERE I PUT THE EXTRA VALUE
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
    notif.contentIntent = contentIntent;

    nm.notify(id, notif);

알림에서 추가 매개 변수를 가져 오는 내 활동의 코드 :

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);


    Bundle extras = getIntent().getExtras();
    if(extras != null){
        Log.i( "dd","Extra:" + extras.getString("item_id") );
    }

엑스트라는 항상 null이며 로그에 아무것도 넣지 않습니다.

Btw ... onCreate활동이 시작될 때만 실행됩니다. 활동이 이미 시작된 경우 추가 항목을 수집하고받은 item_id에 따라 활동을 제시하고 싶습니다.

어떤 아이디어?

답변:


241

이 안내서를 살펴보십시오 ( 알림 작성). ) ApiDemos "StatusBarNotifications"및 "NotificationDisplay"를 샘플링하십시오.

활동이 이미 실행 중인지 관리하기위한 두 가지 방법이 있습니다.

  1. 활동을 시작할 때 FLAG_ACTIVITY_SINGLE_TOP 플래그를 의도에 추가 한 다음 활동 클래스에서 onNewIntent (Intent intent) 이벤트 핸들러를 구현 하여 활동에 대해 호출 된 새 의도에 액세스 할 수 있습니다 (getIntent를 호출하는 것과 동일하지 않음) (), 항상 활동을 시작한 첫 번째 의도를 반환합니다.

  2. 1 번과 동일하지만 인 텐트에 플래그를 추가하는 대신 활동 AndroidManifest.xml에 "singleTop" 을 추가해야합니다 .

인 텐트 엑스트라를 사용하는 경우 remeber를 PendingIntent.getActivity()사용하여 플래그 를 호출 하십시오 PendingIntent.FLAG_UPDATE_CURRENT. 그렇지 않으면 모든 알림에 동일한 엑스트라가 재사용됩니다.


95
엑스트라에 대한 사용자의 질문에 대답하기 위해 : PendingIntent.getActivity()플래그 로 전화 해야합니다 PendingIntent.FLAG_UPDATE_CURRENT. 그렇지 않으면 모든 알림에 동일한 엑스트라가 재사용됩니다.
Matthias

2
U는 내 하루를 구했지만 왜 이렇게 간단한 데이터를 안드로이드에서 그렇게 복잡하게 전송 하는가
불법 인수

8
다른 알림이 있어야 하는 경우 및 에 PendingIntent.getActivity()설정을 설정 FLAG_ACTIVITY_SINGLE_TOP하는 것 외에도 전화 할 때 다른 요청 ID를 사용해야 합니다 . 참조 stackoverflow.com/questions/7370324/...IntentFLAG_UPDATE_CURRENTPendingIntent
schnatterer

101

내 응용 프로그램이 메시지 알림을 표시하는 것과 비슷한 문제가 있습니다. 여러 알림이 있고 각 알림을 클릭하면 해당 알림 세부 사항이 메시지보기 활동에 표시됩니다. 메시지 추가보기에서 동일한 추가 매개 변수가 수신되는 문제를 해결했습니다.

이것을 고친 코드는 다음과 같습니다. 알림 의도를 작성하기위한 코드입니다.

 Intent notificationIntent = new Intent(getApplicationContext(), viewmessage.class);
    notificationIntent.putExtra("NotificationMessage", notificationMessage);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingNotificationIntent = PendingIntent.getActivity(getApplicationContext(),notificationIndex,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notification.setLatestEventInfo(getApplicationContext(), notificationTitle, notificationMessage, pendingNotificationIntent);

메시지 활동을보기위한 코드입니다.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    onNewIntent(getIntent());
}

@Override
public void onNewIntent(Intent intent){
    Bundle extras = intent.getExtras();
    if(extras != null){
        if(extras.containsKey("NotificationMessage"))
        {
            setContentView(R.layout.viewmain);
            // extract the extra-data in the Notification
            String msg = extras.getString("NotificationMessage");
            txtView = (TextView) findViewById(R.id.txtMessage);
            txtView.setText(msg);
        }
    }


}

29

어쩌면 조금 늦었지만이 대신에 :

public void onNewIntent(Intent intent){
    Bundle extras = intent.getExtras();
    Log.i( "dbg","onNewIntent");

    if(extras != null){
        Log.i( "dbg", "Extra6 bool: "+ extras.containsKey("net.dbg.android.fjol"));
        Log.i( "dbg", "Extra6 val : "+ extras.getString("net.dbg.android.fjol"));

    }
    mTabsController.setActiveTab(TabsController.TAB_DOWNLOADS);
}

이것을 사용하십시오 :

Bundle extras = getIntent().getExtras();
if(extras !=null) {
    String value = extras.getString("keyName");
}

20
어쩌면 늦게 영업 이익,하지만 :) 인터넷에서 다른 사람을 위해 늦은 결코
espinchi

19

여기에서도 같은 문제가 발생합니다. PendingIntent를 만드는 동안 다른 요청 코드를 사용하여 해결하고 알림과 동일한 ID를 사용합니다. 그러나 이것이 왜 이루어져야 하는지를 여전히 모른다.

PendingIntent contentIntent = PendingIntent.getActivity(context, **id**, notificationIntent, 0);
notif.contentIntent = contentIntent;
nm.notify(**id**, notif);

14

일부 전자 메일 목록과 다른 포럼을 읽은 후 트릭이 의도에 som unique 데이터를 추가하는 것으로 나타났습니다.

이처럼 :

   Intent notificationIntent = new Intent(Main.this, Main.class);
   notificationIntent.putExtra("sport_id", "sport"+id);
   notificationIntent.putExtra("game_url", "gameURL"+id);

   notificationIntent.setData((Uri.parse("foobar://"+SystemClock.elapsedRealtime()))); 

나는 이것이 왜 이루어져야하는지 이해하지 못한다. 의도와 관련이있어 엑스트라로만 식별 할 수있다 ...


8
Anroid는 인 텐트를 재사용하고, 인 텐트 작업 및 요청 코드는이를 고유하게 만들지 만 추가 데이터는 아닙니다. 따라서 고유 한 요청 ID를 설정하거나 다른 의도 작업을 사용해야합니다.
Bachi

10

나는 모든 것을 시도했지만 아무것도 효과가 없었습니다.

결국 다음 해결책을 생각해 냈습니다.

1- 매니페스트 추가 활동 android : launchMode = "singleTop"

2-보류 의도를 만드는 동안 다음을 수행하면서 intent.putString () 또는 intent.putInt ()를 직접 사용하는 대신 번들을 사용하십시오.

                    Intent notificationIntent = new Intent(getApplicationContext(), CourseActivity.class);

                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXAM_ID,String.valueOf(lectureDownloadStatus.getExamId()));
                    bundle.putInt(Constants.COURSE_ID,(int)lectureDownloadStatus.getCourseId());
                    bundle.putString(Constants.IMAGE_URL,lectureDownloadStatus.getImageUrl());

                    notificationIntent.putExtras(bundle);

                    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                            Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
                            new Random().nextInt(), notificationIntent,
                            PendingIntent.FLAG_UPDATE_CURRENT); 

3
그것은 나를 위해 작동합니다. 다른 requestCode 값과 PendingIntent.FLAG_UPDATE_CURRENT 플래그를 사용해야합니다.
phuongle

4

AndroidManifest.xml

launchMode = "singleTop"포함

<activity android:name=".MessagesDetailsActivity"
        android:launchMode="singleTop"
        android:excludeFromRecents="true"
        />

SMSReceiver.java

Intent 및 PendingIntent에 대한 플래그를 설정하십시오.

Intent intent = new Intent(context, MessagesDetailsActivity.class);
    intent.putExtra("smsMsg", smsObject.getMsg());
    intent.putExtra("smsAddress", smsObject.getAddress());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    PendingIntent contentIntent = PendingIntent.getActivity(context, notification_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

MessageDetailsActivity.java

onResume ()-매번 호출되며 엑스트라를로드합니다.

Intent intent = getIntent();
    String extraAddress = intent.getStringExtra("smsAddress");
    String extraBody = intent.getStringExtra("smsMsg");

그것이 도움이되기를 바랍니다. 스택 오버 플로우에 대한 다른 답변을 기반으로했지만 이것이 가장 효과가있는 업데이트입니다.


3

쉽고, 이것은 객체를 사용하는 솔루션입니다!

내 POJO

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

방법 알림

  Person person = new Person();
  person.setName("david hackro");
  person.setAge(10);

    Intent notificationIntent = new Intent(this, Person.class);
    notificationIntent.putExtra("person",person);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.notification_icon)
                .setAutoCancel(true)
                .setColor(getResources().getColor(R.color.ColorTipografiaAdeudos))
                .setPriority(2)
                .setLargeIcon(bm)
                .setTicker(fotomulta.getTitle())
                .setContentText(fotomulta.getMessage())
                .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT))
                .setWhen(System.currentTimeMillis())
                .setContentTitle(fotomulta.getTicketText())
                .setDefaults(Notification.DEFAULT_ALL);

새로운 활동

 private Person person;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_notification_push);
    person = (Person) getIntent().getSerializableExtra("person");
}

행운을 빕니다!!


3

검색을 한 후 안드로이드 개발자 가이드에서 솔루션을 얻었습니다.

PendingIntent contentIntent ;
Intent intent = new Intent(this,TestActivity.class);
intent.putExtra("extra","Test");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);

stackBuilder.addParentStack(ArticleDetailedActivity.class);

contentIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);

Test Activity 클래스에서 인 텐트 추가 가치를 얻으려면 다음 코드를 작성해야합니다.

 Intent intent = getIntent();
 String extra = intent.getStringExtra("extra") ;

3
무엇입니까 stackBuilder?
AlexioVay

1

알림 구현에서 다음과 같은 코드를 사용하십시오.

NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
...
Intent intent = new Intent(this, ExampleActivity.class);
intent.putExtra("EXTRA_KEY", "value");

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
nBuilder.setContentIntent(pendingIntent);
...

ExampleActivity에서 추가 값을 얻으려면 다음 코드를 사용하십시오.

...
Intent intent = getIntent();
if(intent!=null) {
    String extraKey = intent.getStringExtra("EXTRA_KEY");
}
...

매우 중요 참고 : 의도 :: putExtra () 메소드는 오버로드입니다. 추가 키를 얻으려면 Intent :: get [Type] Extra () 를 사용해야합니다. 메서드 합니다.

참고 : NOTIFICATION_IDNOTIFICATION_CHANNEL_ID 는 ExampleActivity에 선언 된 상수입니다.


1

G'day, 나는이 게시물에 언급 된 모든 것을 시도했으며 다른 곳에서 몇 가지 더 시도했다고 말할 수 있습니다. 가장 큰 문제는 새로운 인 텐트에 항상 null 번들이 있다는 것입니다. 내 문제는 ".this 또는 .that을 포함 했는가"의 세부 사항에 너무 많은 초점을 맞추고있었습니다. 내 솔루션은 세부 사항에서 한 걸음 물러서서 알림의 전체 구조를 살펴 보았습니다. 그렇게 할 때 코드의 핵심 부분을 올바른 순서로 배치했습니다. 따라서 비슷한 문제가 발생하면 다음을 확인하십시오.

1. Intent notificationIntent = new Intent(MainActivity.this, NotificationActivity.class);

2a. Bundle bundle = new Bundle();

// 데이터 형식을 훨씬 잘 지정하는 것이 좋습니다. 예 : bundle.putInt

2b. notificationIntent.putExtras(bundle);
3. PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this, WIZARD_NOTIFICATION_ID, notificationIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
4. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
5.          NotificationCompat.Builder nBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.ic_notify)
                            .setContentTitle(title)
                            .setContentText(content)
                            .setContentIntent(contentIntent)
                            .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
                            .setAutoCancel(false)//false is standard. true == automatically removes the notification when the user taps it.
                            .setColor(getResources().getColor(R.color.colorPrimary))
                            .setCategory(Notification.CATEGORY_REMINDER)
                            .setPriority(Notification.PRIORITY_HIGH)
                            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
            notificationManager.notify(WIZARD_NOTIFICATION_ID, nBuilder.build());

순서 로 유효한 번들을 얻습니다.


0

당신이 사용하는 경우

android:taskAffinity="myApp.widget.notify.activity"
android:excludeFromRecents="true"

활동을 시작하려면 AndroidManifest.xml 파일에서 의도에 따라 다음을 사용해야합니다.

Intent notificationClick = new Intent(context, NotifyActivity.class);
    Bundle bdl = new Bundle();
    bdl.putSerializable(NotifyActivity.Bundle_myItem, myItem);
    notificationClick.putExtras(bdl);
    notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));
    notificationClick.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);  // schließt tasks der app und startet einen seperaten neuen

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(NotifyActivity.class);
    stackBuilder.addNextIntent(notificationClick);

    PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    mBuilder.setContentIntent(notificationPendingIntent);

다음과 같은 고유 ID를 사용하여 고유 데이터를 설정하는 것이 중요합니다.

notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));


0

해결되는 것보다 알림을 표시하는 동안 PendingIntent로 사용하십시오.

PendingIntent 의도 = PendingIntent.getActivity (this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

마지막 필드로 PendingIntent.FLAG_UPDATE_CURRENT를 추가하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.