【问题标题】:String loss in alarm manager警报管理器中的字符串丢失
【发布时间】:2012-07-26 13:29:07
【问题描述】:

我对附加到警报的文本字符串有疑问。似乎触发警报时,附加到警报的字符串为空。显然我犯了一个错误 - 但不知道在哪里。

我设置闹钟的代码是;

static void set_alarm(long alarm_time_in_millis,Context cont,AlarmManager alarm_manager,String str)
{
    Intent intent = new Intent(cont, to_call_when_alarm_goes_off.class);
    intent.putExtra("string_passed_in_bundle", str); 

    Log.i("xx","set_alarm ["+str+"]"); // The string I see in the Log is correct
    PendingIntent pIntent = PendingIntent.getBroadcast(cont,0, intent, 0);

    alarm_manager.cancel(pIntent);

    alarm_manager.set(AlarmManager.RTC_WAKEUP,alarm_time_in_millis, pIntent);
}

接收报警代码如下:

public class to_call_when_alarm_goes_off extends BroadcastReceiver
{
    Bundle bundle_from_whoever_called_this_activity;

    @Override
    public void onReceive(Context arg0, Intent arg1) 
    {
        String str;

        bundle_from_whoever_called_this_activity = arg1.getExtras();

        str = bundle_from_whoever_called_this_activity.getString("string_passed_in_bundle");

        Log.i("xx","to_call_when_alarm_goes_off: TIME TO WAKE UP!!! ["+str+"]");

        try 
        {
            Intent i = new Intent(arg0, dingaling.class);
            i.putExtra("string_passed_in_bundle", str);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            arg0.startActivity(i);
        } 
        catch (Exception e) 
        {
        }
    }
}

当我设置警报然后等待它被触发时,日志文件会显示类似这样的内容

set_alarm [Go to meeting]
to_call_when_alarm_goes_off: TIME TO WAKE UP!!! [null]

编辑:会不会有一些“超级”。我忘记调用的函数?

编辑:我经常对传递给各种函数的上下文类型感到困惑,例如getBaseContext(),getApplicationContext(),"this" etc...如果我在某处涉及到错误的上下文类型,会导致这个问题吗?

【问题讨论】:

  • 第一个日志语句 (xx) 有正确的字符串,我接受了吗?另外,您可以尝试将您的附加键重命名为比“字符串”更唯一可识别的名称吗?我怀疑这是问题所在,但你永远不知道..
  • @Scen:是的,第一个日志有正确的字符串 - 好的,我会尝试“字符串”以外的其他内容。
  • @Scen:从使用“string”改为“alarm_string”,但没有区别。
  • 这真的很奇怪,它应该可以工作。如果您自己解决了这个问题,请不要忘记更新问题!我真的很想知道这里发生了什么,呵呵。

标签: android


【解决方案1】:

我只是将您的代码复制并粘贴到我的应用程序中,它运行良好。只需创建活动并复制您的广播接收器。在活动中单击一个按钮,然后按钮的 onCLick 调用您的 setAlarm 函数。

我可以在 broadcastReceiver 中获取字符串。

这是我的代码。

 public class MainActivity extends Activity {

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

        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
            AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

                set_alarm(System.currentTimeMillis(), MainActivity.this, manager, "Time for tea");
            }
        });
    }


    static void set_alarm(long alarm_time_in_millis,Context cont,AlarmManager alarm_manager,String str)
    {
        Intent intent = new Intent(cont, to_call_when_alarm_goes_off.class);
        intent.putExtra("string_passed_in_bundle", str); 

        Log.i("xx","set_alarm ["+str+"]"); // The string I see in the Log is correct
        PendingIntent pIntent = PendingIntent.getBroadcast(cont,0, intent, 0);

        alarm_manager.cancel(pIntent);

        alarm_manager.set(AlarmManager.RTC_WAKEUP,alarm_time_in_millis, pIntent);
    }
}

广播接收器和你的一样,这里就不放了。

最后在清单中声明广播接收器

输出

set_alarm [Time for tea]
to_call_when_alarm_goes_off: TIME TO WAKE UP!!! [Time for tea]

【讨论】:

    【解决方案2】:

    您可能希望单步执行此代码并确保您得到的字符串是您所期望的。我敢打赌,你没有得到你所期望的。

    【讨论】:

      【解决方案3】:

      当您更改密钥时

      "string"
      

      "alarm_string"
      

      你还在 to_call_when_alarm_goes_off 类中得到一个字符串吗?还是你得到null?

      如果您在此处删除 cancel(pIntent) 函数会发生什么:

      alarm_manager.cancel(pIntent);
      
      alarm_manager.set(AlarmManager.RTC_WAKEUP,alarm_time_in_millis, pIntent);
      

      只是想减少噪音。 “字符串”可能用于序列化或其他用途,它可能会让人感到困惑。更独特的价值也有帮助。

      【讨论】:

      • 我现在使用“string_passed_in_bundle”而不是“string”。我现在在我的广播接收器中收到 null 。我尝试注释掉 cancel() - 但它没有任何区别 - 仍然为空。
      • 我已对原始问题进行了编辑以反映最新版本
      【解决方案4】:

      使用Intent 而不是Bundle,所以...

      str = arg1.getStringExtra("string");
      

      【讨论】:

      • 如果我使用该方法,变量 str 为 null :-(
      【解决方案5】:

      下面的代码对我有用。我通过 AndroidManifest 中带有意图过滤器的自定义意图调用 BroadcastReceiver。但是,我真的不能说为什么这会有所作为。话虽如此,下面的代码有效。

      public class MainActivity extends Activity implements OnClickListener {
      private Button button;
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          button = (Button) findViewById(R.id.button1);
          button.setOnClickListener(this);
      }
      
      public void onClick(View v) {
          switch (v.getId()) {
          case R.id.button1:
              setAlarm();
              break;
          }       
      } 
      
      private void setAlarm() {
          AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
          long interval = System.currentTimeMillis() + 10000; // 10 seconds from now
          Intent launchIntent = new Intent();
          launchIntent.putExtra("your_key", "your string value");
          launchIntent.setAction(MyBroadcastReceiver.CUSTOM_INTENT);
          PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, launchIntent, 0);
          alarmManager.set(AlarmManager.RTC_WAKEUP,interval,
                  pendingIntent);     
      }
      }
      

      还有广播接收器:

      public class MyBroadcastReceiver extends BroadcastReceiver {
      public static final String CUSTOM_INTENT = "com.your_custom_intent";
      
      @Override
      public void onReceive(Context context, Intent intent) {
          Bundle bundle = intent.getExtras();
          String message = bundle.getString("your_key");
          Log.d("test", message);
      }
      }
      

      还有 AndroidManifest:

      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.test2_2"
      android:versionCode="1"
      android:versionName="1.0" >
      
      <uses-sdk
          android:minSdkVersion="8"
          android:targetSdkVersion="8" />
      
      <application
          android:icon="@drawable/ic_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme" >
          <activity
              android:name=".MainActivity"
              android:label="@string/title_activity_main" >
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
      
                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
      
          <receiver
              android:name=".MyBroadcastReceiver">
              <intent-filter>
                  <action android:name="com.your_custom_intent" />
              </intent-filter>
          </receiver>
      </application>
      
      </manifest>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-23
        • 1970-01-01
        相关资源
        最近更新 更多