Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 55

6
votes
answers
13 views
+10

Bundle.putExtra problem with android

I am currently developing an android app where I create a notification Intent which adds parameters to the bundle of the intent. When the notification is clicked it calls an activity and gets the data from the bundle. However, the first time the app is used it works fine, but when you click on a different item its supposed to pass different data onto the notification activity but for some reason its not replacing the old data with the new.

I have tried to call bundle.removeExtra("companyPassword") before I use the putExtra but it doesn't seem to make any difference. Below is the code for the notification

private void notification(String companyName, String companyURL, String companyUsername, String loginPassword)
{
    String ns = Context.NOTIFICATION_SERVICE;
    NotificationManager mNotificationManager = (NotificationManager)getSystemService(ns);

    int icon = R.drawable.icon;
    CharSequence tickerText = "Click notification to copy password";
    long when = System.currentTimeMillis();

    Notification notification = new Notification(icon, tickerText, when);

    Context context = getApplicationContext();
    CharSequence contentTitle = "PM - Login Management";
    CharSequence contentText = "Click here to copy password";
    Intent notificationIntent = new Intent(ShowLogins.this, DataManagement.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    notificationIntent.removeExtra("companyName");
    notificationIntent.removeExtra("companyURL");
    notificationIntent.removeExtra("companyUsername");
    notificationIntent.removeExtra("companyPassword");
    notificationIntent.putExtra("companyName", companyName);
    notificationIntent.putExtra("companyURL", companyURL);
    notificationIntent.putExtra("companyUsername", companyUsername);
    notificationIntent.putExtra("companyPassword", loginPassword);

    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

    final int NOTIFICATION_ID = 1;

    notification.defaults |= Notification.DEFAULT_SOUND;
    //notification.defaults |= Notification.DEFAULT_VIBRATE;
    notification.defaults |= Notification.DEFAULT_SOUND;
    notification.defaults |= Notification.FLAG_AUTO_CANCEL;

    mNotificationManager.notify(NOTIFICATION_ID, notification);
    finish();

And below is the code for the Notification activty where it retrieves the data that is passed into the bundle

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            // setContentView(R.layout.data_mangement);

            Bundle bundle = this.getIntent().getExtras();

            company = bundle.getString("companyName");
            companyURL = bundle.getString("companyURL");
            username = bundle.getString("companyUsername");
            password = bundle.getString("companyPassword");
            bundle.clear();

            ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
            Encryption encryption = new Encryption();
            String decryptedPassword = encryption.decrypt(password);
            clipboard.setText(decryptedPassword);
            toastNotification("Password Successfully Copied

Paste into password field");
            bundle.clear();
            finish();
            moveTaskToBack(true);

        } catch (Exception ex) {
            Log.d("DataManagement Error", ex.toString());
        }
    }

For some reason when the activity for the notification is called it is only returning the data that was first sent when an item was first selected instead of retrieving the new data.

Thanks for any help you can provide.

沙发
+60
+50

However, the first time the app is used it works fine, but when you click on a different item its supposed to pass different data onto the notification activity but for some reason its not replacing the old data with the new.

That is because you are not sufficiently changing your Intent and you are not using FLAG_UPDATE_CURRENT in your PendingIntent. Try the latter and see if it helps.

你的意思是沒有充分改變意圖。我已經完成了你的建議創建一個PendingIntent添加標誌,但似乎沒有傳遞任何關於它剛剛出現NullPointerException - Boardy 2011年2月19日在19:55

@Boardy:如果你在PendingIntent上為一個Intent調用getActivity(),那麼稍後在PendingIntent上為另一個等效的Intent(相同的Intent動作,數據,類別和組件)調用getActivity(),你會得到相同的PendingIntent。沒有FLAG_UPDATE_CURRENT,這意味著你從第一個Intent而不是第二個Intent獲得額外的東西。關於您的異常,請在創建PendingIntent之前先配置整個Intent。 - CommonsWare 2011年2月19日20:01

非常感謝您的幫助。再次感謝 - Boardy 2011年2月19日20:21

這有一個工作解決方案stackoverflow.com/questions/3168484 / ...在Intent上設置一些虛擬動作,否則會刪除額外的動作。例如,intent.setAction(“foo”) - Sam於2012年1月23日在10:24

0
votes
answers
42 views
+10

在哪個線程中通過Notification啓動的IntentService運行?

0

我裹着的PendingIntent的IntentService,我想,當用戶點擊一個特定的通知操作這樣的啓動:在哪個線程中通過Notification啓動的IntentService運行?

Intent actionIntentService = new Intent(context, ActionIntentService.class); 
PendingIntent actionPendingIntent = PendingIntent.getService(app, getNotificationId(), actionIntentService, PendingIntent.FLAG_CANCEL_CURRENT); 

然後我一定要與這個懸而未決的意圖我通知創建添加動作經由NotificationCompat.Builder:

notificationBuilder.addAction(R.drawable.ic_notif_action, actionTitle, actionPendingIntent); 

我的問題是,當m的

onHandleIntent(Intent intent) 

方法y IntentService被調用,它在哪個線程上運行?

我調試了我的代碼,它讓我覺得這個方法調用在主線程上運行。如果是這種情況,爲了使它在後臺線程上運行,我需要做些什麼?

編輯:

我ActionIntentService確實擴展了IntentService

class ActionIntentService extends IntentService 
+0

IntentService運行OFF主UI線程(即點) – Booger 2014-11-06 00:21:19

沙发
0
1

請參考文檔,你所描述的方法不存在。您應該延伸IntentService和實施onHandleIntent(Intent)

文件說:

該方法被調用的工作者線程與處理請求。

+0

那麼什麼是問題?我想答案已經提供。 – 2014-11-06 00:23:32

+0

我的問題是爲什麼onHandleIntent()在通過點擊通知中的Action調用時在主線程上運行。 – murki 2014-11-06 01:22:11

+0

它沒有。你怎麼知道?你如何檢查? – 2014-11-06 01:30:42

0
votes
answers
17 views
+10

android - 將烤麪包從一項活動傳遞給另一項活動

0

不確定這是否有效,但我正嘗試從CustomerCall活動向Toledo活動發送Toast消息。android - 將烤麪包從一項活動傳遞給另一項活動

一旦司機選擇取消。敬酒需要發送到RiderHome活動,說「司機取消了請求」

這可以做到嗎?

CustomerCall

btnCancel = (Button)findViewById(R.id.btnDecline); 
    btnCancel.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

       cancelBooking(); 
     } 
    }); 

} 

private void cancelBooking() { 

    Intent intent = new Intent(getBaseContext(), RiderHome.class); 
    String cancel = "cancel" 
    intent.putExtra("cancel", cancel); 
    startActivity(intent); 

    Toast.makeText(CustomerCall.this, "The Driver has cancelled 
    the request", Toast.LENGTH_LONG).show(); 
} 

RiderHome

public class RiderHome extends AppCompatActivity 
    implements NavigationView.OnNavigationItemSelectedListener, OnMapReadyCallback, 
    GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener, 
    LocationListener { 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_home); 

    } 

} 
+0

如何瀏覽RiderHome活動?你可以使用intent包含你的代碼片段嗎? –

+0

爲什麼不只是在CustomerCall活動上敬酒?如果你只是要烤麪包,你爲什麼還需要將其他活動的吐司/消息傳遞給另一個活動? –

+0

@ TentenPonce驅動程序取消請求後,需要將msg發送給騎手,請求被取消 – LizG

沙发
0
1

你可以做到這一點way-:

private void cancelBooking() { 

    Intent intent = new Intent(getBaseContext(), RiderHome.class); 
    String cancel = "cancel" 
    intent.putExtra("user_cancelled",cancel); 
    startActivity(intent); 

    Toast.makeText(CustomerCall.this, "The Driver has cancelled 
    the request", Toast.LENGTH_LONG).show(); 
} 

在此傳遞一個字符串值,指示駕駛員取消請求

和RiderHome活動,你可以,如果你檢查正在通過以下方式獲取該值:

Intent intent=getIntent(); 
intent.getExtras(); 

if(intent.hasExtra("user_cancelled")) 
{ 

    You can print your toast here. 

} 
+0

感謝您的輸入,但沒有工作:/。它與不同用戶的應用程序,所以也許這就是爲什麼它不工作。我想如果我只是傳遞一個字符串,如果字符串通過,我可以然後打印吐司。沒有運氣, – LizG

+0

你能轉移到騎手活動嗎? –

+0

從CustomerCall活動到意圖? – LizG

板凳
0
-1

,而不是(烤麪包與活動 - 吐司的生命是死的,當活動結束)

Toast.makeText(CustomerCall.this, "The Driver has cancelled 
the request", Toast.LENGTH_LONG).show(); 

到(使用背景!它會生存)

Toast.makeText(getBaseContext(), "The Driver has cancelled 
the request", Toast.LENGTH_LONG).show(); 
4
votes
answers
32 views
+10

How to pass non parcelable objects to from activity to another activity?

I have two objects instantiated from two different class and both classes do not implement parcelable nor serializable. and I want to pass those objects to another activity, so I wrote the below code:

*code:

 //send object
 Intent intConnect = new Intent(mCtx.getApplicationContext(), ActConnect.class);
            Bundle bndConnect = new Bundle();
            bndConnect.putParcelable("HeaderModel", (Parcelable) mHeaderModel);
            bndConnect.putParcelable("DetailsModel", (Parcelable) mDetailsModel);
            intConnect.putExtras(bndConnect);
            intConnect.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mCtx.startActivity(intConnect);

//receive objects in the receiving activity
 Bundle extras = getIntent().getExtras();
    Header headerModel = (Header) extras.get("HeaderModel");
    Details detailsModel = (Details) extras.get("DetailsModel");

but at run time, I receive the below logcat:

logcat:

10-08 11:55:44.225  13138-13138/com.example.com.bt_11 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.com.bt_11, PID: 13138
java.lang.ClassCastException: com.example.com.adapter.Header cannot be cast to android.os.Parcelable
        at com.example.com.adapter.MyExpandableList$1.onClick(MyExpandableList.java:152)
        at android.view.View.performClick(View.java:5184)
        at android.view.View$PerformClick.run(View.java:20893)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)

how can I pass non parcelable objects to from activity to another activity?

沙发
0
+50

You can do this way:

Your Model class will looks like below:

public class ModelClass implements Serializable{

  // Other stuff

}

How to pass:

Intent mIntent = new Intent(mContext, NextActivity.class);
mIntent.putExtra("HeaderModel", mHeaderModel);
startActivity(mIntent);

How to get:

Header headerModel = (Header) getIntent.getSerializableExtra("HeaderModel");

Hope this will help you.

你讀過OP問題嗎?這兩個類都沒有實現parcelable或serializable - Rustam 2015年10月8日10:13

OP請問什麼? - LetsamrIt 2015年10月8日10:15

OP是那個問這個問題的人,你。@LetsamrIt - Manza 2016年7月20日13:11

@LetsamrIt“OP”的意思是“原創海報”,就是你。 - RCB '18年12月3日20:49

+30

If your class doesn't implement parcelable nor serializable, and you cannot modify them (code not under your control perhaps), then you have no way to directly send the data between the two activities.

However, you can pass the data indirectly between the two activities. You could store them in a singleton class (however singletons are hard to test etc.), you could save and retrieve them off your application class, or you could persist them into sharedpreferences, a file or a database to be loaded by the second activity.

+10

The best way to pass object without parcelable or serializable is to use Gson Lib

And use this extensions:

fun Intent.putObject(name: String, value: Any) {
    val jsonValue = Gson().toJson(value)
    this.putExtra(name, jsonValue)
}

inline fun <reified T : Any> Intent.getObjectExtra(name: String): T? {
    val json = this.getStringExtra(name)

    val obj = Gson().fromJson<T>(json, T::class.java)
    return (obj as T)
}

inline fun <reified T : Any> Bundle.getObject(name: String): T? {
    val json = this.getString(name)

    val obj = Gson().fromJson<T>(json, T::class.java)
    return (obj as T)
}

Using:

val intent = Intent(this,YourActivity::class.java)
intent.putObject(name = "myKey", value = MyObject)

//To get the object in the other activity
val product = intent.extras?.getObject<MyObject>(name = "myKey")
// or
val product = intent.getObjectExtra<MyObject>(name = "myKey")
0

try like this:

     Bundle bundle=getIntent().getExtras();

    Header headerModel =(Header)) bundle.getParcelable("HeaderModel");

我收到了完全相同的錯誤 - LetsamrIt 2015年10月8日10:43

0
votes
answers
36 views
+10

如何從WakefulBroadcastReceiver啓動一個IntentService

6

我有一個應用程序,您應該能夠使用我將在此問題中發佈的代碼完全且非常輕鬆地重新創建。這裏的清單文件:如何從WakefulBroadcastReceiver啓動一個IntentService

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.broadcasttest" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="19" 
     android:targetSdkVersion="21" /> 

    <uses-permission android:name="android.permission.WAKE_LOCK"/> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 

     <activity 
      android:name="com.example.broadcasttest.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <receiver 
      android:name="com.example.broadcasttest.TestReceiver" 
      android:label="@string/app_name" 
      android:enabled="true" > 
     </receiver> 

     <intentservice 
      android:name="com.example.broadcasttest.MonitorService" 
      android:enabled="true" > 
      <intent-filter> 
       <action android:name="com.example.broadcasttest.MonitorService" /> 
      </intent-filter> 
     </intentservice> 
    </application> 

</manifest> 

正如你所看到的,包含一個活動,一個(清醒)廣播接收器和intentservice,都在同一個包。該活動得到啓動的啓動,這裏的代碼:

package com.example.broadcasttest; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 


public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     sendBroadcast(new Intent(this, TestReceiver.class)); 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 

這成功地觸發TestReceiveronReceive功能。

package com.example.broadcasttest; 

import android.content.Context; 
import android.content.Intent; 
import android.support.v4.content.WakefulBroadcastReceiver; 

public class TestReceiver extends WakefulBroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     //Intent service = new Intent("com.example.broadcasttest.MonitorService"); 
     Intent service = new Intent(context, MonitorService.class); 
     startWakefulService(context, service); 
    } 

} 

這是不如意的事情,雖然,我把一個斷點在onReceive功能,它肯定會被調用。然而,MonitorService類永遠不會達到。我在onHandleEvent函數中放置了一個斷點,但似乎它從來沒有那麼遠。下面是這個類的代碼:

package com.example.broadcasttest; 

import android.app.IntentService; 
import android.content.Intent; 

public class MonitorService extends IntentService { 

    public MonitorService(String name) { 
     super(name); 
    } 

    public MonitorService() 
    { 
     super("MonitorService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } finally { 
      TestReceiver.completeWakefulIntent(intent); 
     } 

    } 

} 

正如你可以從TestReceiver類的註釋行告訴,我使用隱含的意圖,而不是一個明確的一個嘗試。我也讀了this question並嘗試了那裏提到的一切。我在這裏錯過了什麼嗎?我在模擬器上運行(Nexus7 API L)。

有什麼我在這裏失蹤?

+0

對不起,究竟是這些代碼的目的是什麼?它有什麼作用? – 2015-05-30 12:05:18

沙发
0
9

Application Manifest中沒有標籤<intentservice>IntentServiceService的子類,因此您需要將其聲明爲清單中的服務。


變化

<intentservice 
    android:name="com.example.broadcasttest.MonitorService" 
    android:enabled="true" > 
     <intent-filter> 
      <action android:name="com.example.broadcasttest.MonitorService" /> 
     </intent-filter> 
</intentservice> 

<service 
    android:name="com.example.broadcasttest.MonitorService" 
    android:enabled="true" > 
     <intent-filter> 
      <action android:name="com.example.broadcasttest.MonitorService" /> 
     </intent-filter> 
</service> 
+0

謝謝,如果我只知道那很簡單。 我想知道爲什麼我沒有得到任何形式的錯誤。 – overactor 2014-09-01 08:56:27

+0

@overactor最受歡迎:) – 2014-09-01 08:58:40

0
votes
answers
8 views
+10

應用程序中的衆多活動

-3

我剛剛開始學習Android應用程序開發,並對此感到好奇; 假設我想創建一個包含大量活動(頁面)的應用程序,例如聖經應用程序,大約有1189個章節,每章都有不同的活動。這是否意味着我將創建約1189個不同的活動,或者有更簡單的方法來創建這種類型的應用程序?應用程序中的衆多活動

+0

你不會被創建爲每個頁面的活動,因爲這將是矯枉過正。大部分數據(文本,頁碼)都會從數據庫,文本文件或其他來源加載。在每個章節的測驗或某種遊戲方面取決於你想要達到的目標以及邏輯能夠重複使用多少。閱讀面向對象的編程和片段。 – f78xd23

+0

一項活動就夠了。除非你還需要一個閃屏。其餘的都在碎片中完成。和動態內容。 –

沙发
0
0

你可以使用很多設計模式。你可以把你想要在課堂上顯示的信息。然後你可以跨越1189個對象。你可以創建一個活動,並獲得1189個不同的對象的信息。最後顯示在活動中。

這樣https://github.com/newcaoguo/booksource/tree/master/chapter3/RecyclerViewTest

0
votes
answers
35 views
+10

從另一個活動請參考活動佈局

0

我已經開發了幾年的網絡應用程序,並且決定使用本書開始我的android開發之路:開始wrox的Android應用程序開發。從另一個活動請參考活動佈局

在某些時候,本書解釋瞭如何從意圖獲得結果(標題爲「從意向返回結果」)。

這些步驟如下:

  1. 本書介紹瞭如何通過添加一些新的控件更改的main.xml佈局文件。
  2. 書中介紹如何改變,這將是第二個(活性2)活動,它說,這個活動應該是指不同的活動的佈局通過調用 ?Button btn = (Button) findViewById(R.id.btn_OK); 因爲btn_OK在的佈局定義主要活動(而不是Activity2中的一個,它在main.xml中)該方法返回null。

的正式文檔描述:

public View findViewById (int id) 
Since: API Level 1 

查找所有的鑑定通過從在onCreate(Bundle)處理的XML中的id屬性的圖。

所以我錯過了這裏的東西還是這本書不正確?

沙发
0
0

在Activity中使用findViewById()在onCreate()的setContentView()中使用的佈局xml文件中搜索。

如果兩個活動使用不同的layout.xml文件,這些文件中的按鈕可能具有相同的id,並且不會混淆(通過findViewById())。

板凳
0
0

在活動1

public static Button btn; 
void onCreate(...) { 
    btn = (Button) findViewById(R.id.btn_OK); 
} 

在活性2:

?Button btn = Activity1.btn; 

注意:當您使用意向導航到活性2,不叫activity1.finish(),因爲這會破壞BTN;

390
votes
answers
17 views
+10

How to send parameters from a notification-click to an activity?

I can find a way to send parameters to my activity from my notification.

I have a service that creates a notification. When the user clicks on the notification I want to open my main activity with some special parameters. E.g an item id, so my activity can load and present a special item detail view. More specific, I'm downloading a file, and when the file is downloaded I want the notification to have an intent that when clicked it opens my activity in a special mode. I have tried to use putExtra on my intent, but cant seem to extract it, so I think I'm doing it wrong.

Code from my service that creates the Notification:

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

Code from my Activity that tries to fetch the extra parameter from the notification:

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

The extras is always null and I never gets anything into my log.

Btw... the onCreate is only run when my activity starts, if my activity is already started I also want to collect the extras and present my activity according to the item_id I receive.

Any ideas?

up vote 230 down vote accepted favorite
沙发
+2300
+50

Take a look at this guide (creating a notification) and to samples ApiDemos "StatusBarNotifications" and "NotificationDisplay".

For managing if the activity is already running you have two ways:

  1. Add FLAG_ACTIVITY_SINGLE_TOP flag to the Intent when launching the activity, and then in the activity class implement onNewIntent(Intent intent) event handler, that way you can access the new intent that was called for the activity (which is not the same as just calling getIntent(), this will always return the first Intent that launched your activity.

  2. Same as number one, but instead of adding a flag to the Intent you must add "singleTop" in your activity AndroidManifest.xml.

If you use intent extras, remeber to call PendingIntent.getActivity() with the flag PendingIntent.FLAG_UPDATE_CURRENT, otherwise the same extras will be reused for every notification.

+890

I had the similar problem my application displays message notifications. When there are multiple notifications and clicking each notification it displays that notification detail in a view message activity. I solved the problem of same extra parameters is being received in view message intent.

Here is the code which fixed this. Code for creating the notification Intent.

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

Code for view Message Activity.

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


}

你為什麼要自己調用NewIntent()? - katzenhut 2014年8月25日14:04

據推測,所以在onCreate上調用txtView代碼。我認為有一個更整潔的解決方案,但是 - public void onNewIntent(Intent intent){setIntent(intent); 然後,在onCreate()中,你可以使用Intent latestIntent = getIntent(); 獲得最新的意圖。 - 禁止地球工程2014年9月7日8:54

@katzenhut我在onCreate事件中調用onNewIntent,因為在onCreate事件中沒有觸發onNewIntent事件,所以我必須手動調用它。第一次只觸發onCreate事件。 - Muhammad Yousaf Sulahria 2014年12月29日15:27

這裡的請求代碼有什麼用?你不能得到它onCreate和一個待定的意圖不會調用onActivityResult(..) - Roel 2015年9月11日在8:33

+260

Maybe a bit late, but: instead of this:

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

Use this:

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

對於OP來說可能已經晚了,但對於互聯網上的其他人來說,它永遠不會遲到:) - espinchi 2011年4月10日在18:03

@pinaise謝謝老兄,它對我有用:) - Akshay 12年8月8日在14:56

或者更短:getIntent()。getStringExtra(“keyName”); - Juhani 2013年9月18日中午12點

+180

Encounter same issue here. I resolve it by using different request code, use same id as notification, while creating PendingIntent. but still don't know why this should be done.

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

這對我有用。它必須與一致的請求代碼有關。遺憾的是,我在本文檔中找不到相關內容。如果有人有解釋,請發帖或評論。developer.android.com/reference/android/app/PendingIntent.html - Nlinscott 2014年9月1日2:55

適合我。我也想解釋一下! - koherent 2016年3月10日21:27

意味著兩個id應該相同還是應該不同? - Dhrupal 2017年4月13日9:09

+130

After reading some email-lists and other forums i found that the trick seems to add som unique data to the intent.

like this:

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

I dont understand why this needs to be done, It got something to do with the intent cant be identified only by its extras...

Anroid重用意圖,意圖動作和請求代碼使其獨特,但不是額外的數據。因此,您需要設置唯一的請求ID或使用不同的intent操作。 - Bachi 2011年8月15日11:58

@Bachi我需要的是更改requestID - Mehdi Khademloo 2017年2月5日23:26

工作得很好:)(即使它是一個黑客)。 - Dimitar Vukman 18年1月9日16:17

+90

I tried everything but nothing worked.

eventually came up with following solution.

1- in manifest add for the activity android:launchMode="singleTop"

2- while making pending intent do the following, use bundle instead of directly using intent.putString() or 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); 

這個對我有用。必須使用不同的requestCode值和PendingIntent.FLAG_UPDATE_CURRENT標誌。 - phuongle 2015年6月9日10:31

只有這個解決方案適合我 - 2015年8月19日12:23

這應該是公認的答案 - Vivek Mishra 2016年3月11日11:17

只有這個解決方案有效 notificationIntent的標誌是可選的。 - ZimaXXX 2017年3月20日11:45

這對我來說就像一個魅力隨機數和捆綁做了工作:) - Abhilash 2017年4月3日在11:50

+20

AndroidManifest.xml

Include launchMode="singleTop"

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

SMSReceiver.java

Set the flags for the Intent and 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() - gets called everytime, load the extras.

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

Hope it helps, it was based on other answers here on stackoverflow, but this is the most updated that worked for me.

+20

It's easy,this is my solution using objects!

My POJO

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Method Notification

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

New Activity

 private Person person;

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

Good Luck!!

+10

After doing some search i got solution from android developer guide

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

To Get Intent extra value in Test Activity class you need to write following code :

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

什麼是stackBuilder? - AlexioVay 17年3月21日16:15

0

If you use

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

in your AndroidManifest.xml file for the Activity to launch, you have to use the following in your intent:

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

Important is to set unique data e.g. using an unique id like:

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

for Services use PendingIntent.FLAG_UPDATE_CURRENT

for me work.

0

Please use as PendingIntent while showing notification than it will be resolved.

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

Add PendingIntent.FLAG_UPDATE_CURRENT as last field.

0
votes
answers
25 views
+10

Android 4.0的啓動應用程序無法正常工作

1

IM有一個奇怪的問題,而不是在那裏一個URL應該啓動我的應用程序,它加載應用程序到瀏覽器本身,在這種情況下進入mozella!Android 4.0的啓動應用程序無法正常工作

這裏是意圖過濾器我用我的應用程序如果有人能告訴我什麼即時做錯了。

<uses-sdk android:minSdkVersion="15" /> 
<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

<application 
    android:name=".Globals" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
     android:name=".RSS_ViewerActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 

     <intent-filter> 
       <action android:name="android.intent.action.VIEW" /> 
       <category android:name="android.intent.category.DEFAULT" /> 
       <data android:scheme="itpc" /> 
       <data android:scheme="pcast" /> 
       <data android:scheme="feed" /> 
       <data android:scheme="feeds" /> 
       <data android:scheme="rss" /> 
     </intent-filter> 

     <intent-filter> 
       <action android:name="android.intent.action.VIEW" /> 
       <category android:name="android.intent.category.DEFAULT" /> 
       <data android:mimeType="text/xml" android:scheme="http" /> 
       <data android:mimeType="application/rss+xml" android:scheme="http" /> 
       <data android:mimeType="application/atom+xml" android:scheme="http" /> 
       <data android:mimeType="text/xml" android:scheme="https" /> 
       <data android:mimeType="application/rss+xml" android:scheme="https" /> 
       <data android:mimeType="application/atom+xml" android:scheme="https" /> 
     </intent-filter> 

    </activity> 
    <activity android:name="RSSFeedActivity"></activity> 
    <activity android:name="com.CertificateAuthentication.Authenticator"></activity> 
</application> 

謝謝。

UPDATE

稍微多一些的信息,當對話框,詢問是否要選擇和應用,以打開彈出鏈接起來,它並不曾顯示我的應用程序,或任何與此有關。

UPDATE

我刪除了第二和第三意圖過濾器,我試圖將2個其餘意圖過濾器合併成1,但是這不加載來自瀏覽器的應用程序。上面的代碼是什麼樣子現在讓我相同的結果=前(這是煩人的,因爲它意味着用戶可以在應用程序運行的2次會議,一個從瀏覽器和一個從發射器。

沙发
0
0

你第二和第三<intent-filter>元素可能無法正常工作,因爲android:host未記錄支持通配符。這裏

+0

乾杯但是,不幸的是沒有工作=( 我試圖改變動作爲主,但不工作的對話框,詢問是否要選擇一個應用程序犯規不斷顯示我的應用程序! – 2012-08-13 13:44:15

板凳
0
0

問題是,這是轉義字符,所以讓你需要\這個表達式的工作。 Documentation clearly says,你需要使用\.爲點(有例如用\*)。

我也同意CommonsWare答案,我在documentation這樣的表述已經發現:

所有這些屬性是可選的,但它們不是獨立的 對方:對於權力是有意義的,一個方案還必須指定 。爲了使路徑有意義,必須指定方案和權威 。

而且The host and port together constitute the URI authority所以在實踐中權力意味着主機所以你不能省略,顯然你不能把一個明星出現。

IMO你讓它變得複雜,你不需要在這裏定義路徑! MIME類型應該做這項工作。嘗試找到一些讀取RSS的開源項目,看看他們如何定義清單。

我想你需要類似的東西:

<activity 
    android:name=".RSS_ViewerActivity" 
    android:label="@string/app_name" > 
    <intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 

     <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 

    <intent-filter> 
     <action android:name="android.intent.action.VIEW" /> 
     <category android:name="android.intent.category.BROWSABLE" /> 
     <category android:name="android.intent.category.DEFAULT" /> 
     <data android:scheme="itpc" /> 
     <data android:scheme="pcast" /> 
     <data android:scheme="feed" /> 
     <data android:scheme="feeds" /> 
     <data android:scheme="rss" /> 
     <data android:mimeType="text/xml" android:scheme="http" /> 
     <data android:mimeType="application/rss+xml" android:scheme="http" /> 
     <data android:mimeType="application/atom+xml" android:scheme="http" /> 
     <data android:mimeType="text/xml" android:scheme="https" /> 
     <data android:mimeType="application/rss+xml" android:scheme="https" /> 
     <data android:mimeType="application/atom+xml" android:scheme="https" /> 
    </intent-filter> 

</activity> 
+0

感謝您的幫助,我拿出那些2個意圖過濾器,你和commonsware的建議,我已經更新了我上面的帖子。 我仍然會得到相同的結果,雖然=(我也嘗試過從另一個瀏覽器,股票安卓一,我得到的應用程序的相同結果從瀏覽器查看,而不是啓動/恢復,如果它是運行。 – 2012-08-14 08:25:34

84
votes
answers
21 views
+10

getExtra from Intent launched from a pendingIntent

I am trying to make some alarms after the user selects something with a time from a list and create a notification for it at the given time. My problem is that the "showname" that a putExtra on my Intent cant be received at the broadcast receiver. It always get null value. This is the way I do it for most of my intents but I think this time maybe because of the pendingIntent or the broadcastReceiver something need to be done differentelly. Thank you

The function that sends the Intent through the pending intent

public void setAlarm(String showname,String time) {

    String[] hourminute=time.split(":");
    String hour = hourminute[0];
    String minute = hourminute[1];
    Calendar rightNow = Calendar.getInstance();
    rightNow.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour));
    rightNow.set(Calendar.MINUTE, Integer.parseInt(minute));
    rightNow.set(Calendar.SECOND, 0);
    long t=rightNow.getTimeInMillis();
    long t1=System.currentTimeMillis();

    try {   

    Intent intent = new Intent(this, alarmreceiver.class);  
    Bundle c = new Bundle();            
    c.putString("showname", showname);//This is the value I want to pass
    intent.putExtras(c);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 12345, intent, 0);

    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, rightNow.getTimeInMillis(),pendingIntent);
    //Log.e("ALARM", "time of millis: "+System.currentTimeMillis());
    Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();

    } catch (Exception e) {
        Log.e("ALARM", "ERROR IN CODE:"+e.toString());
    }
}

And this is the receiving end

public class alarmreceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();      
    Bundle b = intent.getExtras();
    String showname=b.getString("showname");//This is where I suppose to receive it but its null
    NotificationManager manger = (NotificationManager) context
            .getSystemService(context.NOTIFICATION_SERVICE);

    Notification notification = new Notification(R.drawable.icon,
            "TVGuide Υπενθ?μιση", System.currentTimeMillis());
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
            new Intent(context, tvguide.class), 0);

    notification.setLatestEventInfo(context, "Το Πρ?γραμμα Ξεκ?νησε",
            showname, contentIntent);

    notification.flags = Notification.FLAG_ONLY_ALERT_ONCE;

    notification.sound = Uri.parse("file:///sdcard/dominating.mp3");
    notification.vibrate = new long[]{100, 250, 100, 500};
    manger.notify(1, notification);
}           
}
沙发
+510

If you change the Extra's value in the intent, then while creating the pending intent you should use the flag PendingIntent.FLAG_CANCEL_CURRENT.

A simple example would be

PendingIntent pi = PendingIntent.getBroadcast(context, 0,intentWithNewExtras,PendingIntent.FLAG_CANCEL_CURRENT);

This is the right way and will ensure that your new values are delivered.

Hope it helps.

一旦啟動了一個意圖,系統試圖重新使用它並且沒有額外的更改,這似乎不適用於具有翻板的小部件。 - Necronet 12年11月11日15:37

為我工作,我被困了幾個小時! - 阿里12年3月3日11:31

解決了2個小時的問題.... - Shajeel Afzal 2013年8月21日11:31

謝謝你的回答...... - Satheesh 13年11月26日7:52

像往常一樣訪問打算捆綁? - Chad Bingham 2014年12月8日5:06

板凳
+240

Intents are reused in the system, unless they differ on context/action I believe. Documentation Link. That is, if you have already constructed an Intent, that intent might be used later as well.

As a debug-test, you could try to add intent.setAction("" + Math.random()) below intent.putExtras(c) and see if your extras are received in the other end.

Relevant Documentation:

Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.

這是正確答案......... - Necronet 12年11月11日15:38

+1,這是正確的答案,應該被接受。這真的很有用,謝謝。(順便說一句,你也可以在創建待定意圖時使用不同的請求代碼,使用哈希,這非常方便)。--Snicolas 2013年7月25日9:11

地板
+90

use different request code for different alarm notifications to avoid overwriting of same alarm time.

這是這類問題的最佳答案!解決問題的簡單而美觀的解決方法。 - Andrey Novikov 12年10月10日18:01

我同意,非常簡單的解決方法。 - jp36 12年12月18日22:43

4楼
0

You should use intent.putExtra() method. Not set bundle to extras segment. IF you set string, you whould intent.putExtra(<key>, value); Try this it will be done. I used it.

5楼
0

I was had same problem. I solved it with setting an action to intent as suggested by @aioobe here, and my intent works like a magic.

Here what i did

  ` intent.putExtra("Name", mName);
    intent.putExtra("dateTime", newdate);
    intent.setAction("" + Math.random());`

Hope it will help someone, happy coding..! :)