Làm cách nào để gửi tham số từ nhấp chuột thông báo đến một hoạt động?


206

Tôi có thể tìm cách gửi tham số cho hoạt động của mình từ thông báo của mình.

Tôi có một dịch vụ tạo ra một thông báo. Khi người dùng nhấp vào thông báo, tôi muốn mở hoạt động chính của mình với một số thông số đặc biệt. Ví dụ: id mục, vì vậy hoạt động của tôi có thể tải và hiển thị chế độ xem chi tiết mục đặc biệt. Cụ thể hơn, tôi đang tải xuống một tệp và khi tệp được tải xuống, tôi muốn thông báo có ý định rằng khi nhấp vào, nó sẽ mở hoạt động của tôi ở chế độ đặc biệt. Tôi đã cố gắng sử dụng putExtravào mục đích của mình, nhưng dường như không thể trích xuất nó, vì vậy tôi nghĩ rằng tôi đang làm sai.

Mã từ dịch vụ của tôi tạo Thông báo:

        // 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);

Mã từ Hoạt động của tôi cố gắng tìm nạp tham số bổ sung từ thông báo:

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

Các tính năng bổ sung luôn là null và tôi không bao giờ nhận được bất cứ điều gì vào nhật ký của mình.

Btw ... onCreatechỉ được chạy khi hoạt động của tôi bắt đầu, nếu hoạt động của tôi đã bắt đầu, tôi cũng muốn thu thập các tính năng bổ sung và trình bày hoạt động của mình theo mục_id tôi nhận được.

Có ý kiến ​​gì không?

Câu trả lời:


241

Hãy xem hướng dẫn này ( tạo thông báo ) và lấy mẫu ApiDemos "StatusBarNotifying" và "NotificationDisplay".

Để quản lý nếu hoạt động đã chạy, bạn có hai cách:

  1. Thêm cờ FLAG_ACTIVITY_SINGLE_TOP vào Ý định khi khởi chạy hoạt động và sau đó trong lớp hoạt động triển khai trình xử lý sự kiện trên NewIntent (Ý định ý định) , theo cách đó bạn có thể truy cập mục đích mới được gọi cho hoạt động (không giống như chỉ gọi getIntent (), điều này sẽ luôn trả về Ý định đầu tiên khởi chạy hoạt động của bạn.

  2. Tương tự như số một, nhưng thay vì thêm một cờ vào Mục đích, bạn phải thêm "singleTop" trong hoạt động của mình AndroidManifest.xml.

Nếu bạn sử dụng tính năng bổ sung có ý định, người nhớ để gọi PendingIntent.getActivity()bằng cờ PendingIntent.FLAG_UPDATE_CURRENT, nếu không, các tính năng bổ sung tương tự sẽ được sử dụng lại cho mỗi thông báo.


95
và để trả lời câu hỏi của người dùng về các tính năng bổ sung là null: Bạn phải gọi PendingIntent.getActivity()bằng cờ PendingIntent.FLAG_UPDATE_CURRENT, nếu không các tính năng bổ sung tương tự sẽ được sử dụng lại cho mỗi thông báo.
Matthias

2
u đã lưu ngày của tôi nhưng tại sao việc truyền dữ liệu đơn giản như thế này lại phức tạp như vậy trong Android
Đối số bất hợp pháp

8
Nếu bạn cần có các thông báo khác nhau, hãy đảm bảo sử dụng các ID yêu cầu khác nhau khi gọi PendingIntent.getActivity()ngoài cài đặt FLAG_ACTIVITY_SINGLE_TOPtrên IntentFLAG_UPDATE_CURRENTtrên PendingIntent. Xem stackoverflow.com/questions/7370324/
Mạnh

101

Tôi gặp vấn đề tương tự ứng dụng của tôi hiển thị thông báo tin nhắn. Khi có nhiều thông báo và nhấp vào từng thông báo, nó sẽ hiển thị chi tiết thông báo đó trong một hoạt động xem tin nhắn. Tôi đã giải quyết vấn đề của các tham số bổ sung tương tự đang được nhận trong mục đích xem tin nhắn.

Đây là đoạn mã đã sửa lỗi này. Mã để tạo ý định thông báo.

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

Mã để xem Hoạt động tin nhắn.

@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

Có thể hơi muộn, nhưng: thay vì điều này:

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

Dùng cái này:

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

20
Có thể muộn cho OP, nhưng nó không bao giờ muộn đối với những người khác trên Internet :)
đặc biệt là

19

Gặp vấn đề tương tự ở đây. Tôi giải quyết nó bằng cách sử dụng mã yêu cầu khác nhau, sử dụng cùng một id làm thông báo, trong khi tạo PendingIntent. nhưng vẫn không biết tại sao điều này nên được thực hiện.

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

14

Sau khi đọc một số danh sách email và các diễn đàn khác, tôi thấy rằng thủ thuật này dường như thêm một số dữ liệu duy nhất vào mục đích.

như thế này:

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

Tôi không hiểu tại sao điều này cần phải được thực hiện. Nó có một cái gì đó để làm với mục đích không thể được xác định chỉ bằng các tính năng bổ sung của nó ...


8
Anroid sử dụng lại ý định, hành động có ý định và mã yêu cầu làm cho nó trở nên độc đáo, nhưng không phải là dữ liệu bổ sung. Vì vậy, bạn cần đặt id yêu cầu duy nhất hoặc sử dụng các hành động có mục đích khác nhau.
Bachi

10

Tôi đã thử mọi cách nhưng không có gì hiệu quả.

cuối cùng đã đưa ra giải pháp sau đây.

1- trong tệp kê khai thêm cho hoạt động android: launchMode = "singleTop"

2- trong khi thực hiện ý định đang chờ thực hiện, hãy sử dụng gói thay vì sử dụng trực tiếp aim.putString () hoặc aim.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
Nó làm việc cho tôi. Phải sử dụng giá trị requestCode khác nhau và cờ PendingIntent.FLAG_UPDATE_CURRENT.
phuongle

4

AndroidManifest.xml

Bao gồm launchMode = "singleTop"

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

SMSReceiver.java

Đặt cờ cho Ý định và 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 () - được gọi mọi lúc, tải các tính năng bổ sung.

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

Hy vọng nó có ích, nó dựa trên các câu trả lời khác ở đây trên stackoverflow, nhưng đây là bản cập nhật nhất phù hợp với tôi.


3

Thật dễ dàng, đây là giải pháp của tôi bằng cách sử dụng các đối tượng!

POJO của tôi

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Thông báo phương pháp

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

Hoạt động mới

 private Person person;

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

Chúc may mắn!!


3

Sau khi thực hiện một số tìm kiếm, tôi đã nhận được giải pháp từ hướng dẫn dành cho nhà phát triển Android

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

Để có được giá trị bổ sung ý định trong lớp Hoạt động kiểm tra, bạn cần viết mã sau đây:

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

3
Để làm gì stackBuilder?
AlexioVay

1

Trong triển khai thông báo của bạn, hãy sử dụng một mã như thế này:

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);
...

Để có được các giá trị bổ sung có ý định trong exampleActivity, hãy sử dụng đoạn mã sau:

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

LƯU Ý RẤT QUAN TRỌNG: phương thức Intent :: putExtra () là một phương thức Quá tải. Để lấy khóa bổ sung, bạn cần sử dụng phương thức Intent :: get [Type] Extra () .

Lưu ý: NOTIFICATION_IDNOTIFICATION_CHANNEL_ID là các hằng số được khai báo trong exampleActivity


1

G'day, tôi cũng có thể nói rằng tôi đã thử mọi thứ được đề cập trong các bài đăng này và một vài thứ khác từ nơi khác. Vấn đề số 1 đối với tôi là Intent mới luôn có một gói null. Vấn đề của tôi là tập trung quá nhiều vào các chi tiết của "tôi đã bao gồm. Điều này hay .that". Giải pháp của tôi là lùi một bước từ chi tiết và xem xét cấu trúc tổng thể của thông báo. Khi tôi làm điều đó, tôi đã quản lý để đặt các phần chính của mã theo đúng trình tự. Vì vậy, nếu bạn gặp vấn đề tương tự, hãy kiểm tra:

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

2a. Bundle bundle = new Bundle();

// Tôi thích chỉ định kiểu dữ liệu tốt hơn nhiều. ví dụ: 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());

Với trình tự này, tôi nhận được một gói hợp lệ.


0

Nếu bạn dùng

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

trong tệp AndroidManifest.xml của bạn để Hoạt động khởi chạy, bạn phải sử dụng các mục sau đây trong ý định của mình:

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

Quan trọng là đặt dữ liệu duy nhất, ví dụ: sử dụng một id duy nhất như:

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

0

cho Dịch vụ sử dụng PendingIntent.FLAG_UPDATE_CURRENT

cho tôi làm việc


0

Vui lòng sử dụng như PendingIntent trong khi hiển thị thông báo hơn nó sẽ được giải quyết.

PendingIntent aim = PendingIntent.getActivity (this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Thêm PendingIntent.FLAG_UPDATE_CURRENT làm trường cuối cùng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.