java生成自定义通知的textView,以便为每个激发的通知记住特定字符串
问题摘要: 我有一个listView,它存储了单词记忆类、NotificationWorker类和NotificationReceiver类中的词汇表,用于处理通知。我的目标是点击listView中的一个项目(例如,一个名为“棒球”的单词),该项目将触发一个时间选择器,我将在其中设置一个特定的时间(例如,5分钟后)来触发通知。通知出现时,应该显示一个标题:“你还记得这个词吗:棒球?”。当我只发出一个通知时,通知会正常工作,但如果我立即为另一个单词(如“apple”)发出第二个通知,第一个和第二个通知的标题都会变成“你还记得这个单词吗:apple?”。我的意思是,当这两个通知出现时,第一个应该是“棒球”,第二个应该是“苹果”。问题是,当我发出第二次通知时,“棒球”已经被替换了
那么,有没有一种方法可以让通知记住它们的具体单词呢
我尝试过的事情: 我尝试为每个通知设置不同的通知id,但没有成功。我想生成一个时间标签,在点击“棒球”(或listView中的任何其他项目)时获取当前系统时间,并让通知管理器将时间标签与“棒球”配对,这样它将是“棒球”的标识符,因此通知可以记住这个词。然而,这远远高于我的编码水平,我不知道如何在代码中实现这一点
以下是我的代码供参考:
单词记忆类
public class WordsToMemorize extends AppCompatActivity {
static String vocabularyToBeMemorized;
Calendar c;
WorkManager mWorkManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.words_to_memorize);
final ListView myVocabularyListview;
final ArrayAdapter myVocabularyArrayAdapter;
//findViewById
myVocabularyListview = findViewById(R.id.my_vocabulary_listview);
mWorkManager = WorkManager.getInstance();
//Initialize the adapter
myVocabularyArrayAdapter = new ArrayAdapter<>(this, 安卓.R.layout.simple_list_item_1, myVocabularyArrayList);
myVocabularyListview.setAdapter(myVocabularyArrayAdapter);
/**
* Let the user click on an item and set notification timings
*/
myVocabularyListview.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
final String selectedMyVocabularyListviewItemValue=myVocabularyListview.getItemAtPosition(position).toString();
AlertDialog.Builder AlertDialog = new AlertDialog.Builder(WordsToMemorize.this);
AlertDialog .setTitle(getString(R.string.Choose_the_timing_to_recall_a_word));
AlertDialog .setCancelable(false);
AlertDialog .setView(R.layout.custom_alert_dialog_dictionary_providers);
//Time Picker Button
AlertDialog .setPositiveButton(getString(R.string.Customize_timing), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//I couldn't directly fetch the values of the myVocabularyListview items so I had to pass them to a dummy texView called "wordInputView" and then fetch them from there.
MainActivity.wordInputView.setText(selectedMyVocabularyListviewItemValue);
setCustomizedNotificationTiming();
}
});
//Cancel Button
AlertDialog .setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog .create();
AlertDialog .show();
}
});
@Override
protected void onStart() {
super.onStart();
c = Calendar.getInstance();
}
// Helper Method
public void setCustomizedNotificationTiming() {
vocabularyToBeMemorized = MainActivity.wordInputView.getText().toString();
// on Time
new TimePickerDialog(this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
long nowMillis = System.currentTimeMillis();
long millis = c.getTimeInMillis() - nowMillis;
if (c.before(Calendar.getInstance())) {
Toast.makeText(getApplicationContext(), getString(R.string.Hey_thats_too_early),Toast.LENGTH_LONG).show();
} else {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.TAIWAN);
Long scheduledDateInMilliSeconds=c.getTimeInMillis();
String FormattedScheduledDate = dateFormat.format(scheduledDateInMilliSeconds);
Toast.makeText(getApplicationContext(), getString(R.string.Will_send_the_notification_at) + FormattedScheduledDate + getString(R.string.blank_space),Toast.LENGTH_LONG).show();
OneTimeWorkRequest UserDefinedNotificationRequest = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.addTag("UserDefinedNotificationTag" + " for " + vocabularyToBeMemorized)
.setInitialDelay(millis, TimeUnit.MILLISECONDS)
.build();
mWorkManager.enqueue(UserDefinedNotificationRequest);
}
}
},
c.get(Calendar.HOUR_OF_DAY),
c.get(Calendar.MINUTE),
false).show();
// on Date
new DatePickerDialog(this,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, monthOfYear);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
}
},
c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH)).show();
}
}
通知工人阶级
public class NotificationWorker extends Worker {
public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
showNotification("Hey I'm your worker", "Work is done");
return Result.success();
}
public int createID(){
Date now = new Date();
int id = Integer.parseInt(new SimpleDateFormat("ddHHmmssSS", Locale.TAIWAN).format(now));
return id;
}
private void showNotification(String task, String desc) {
RemoteViews collapsedNotificationView = new RemoteViews(getApplicationContext().getPackageName(),R.layout.custom_notification_normal_view);
collapsedNotificationView.setTextViewText(R.id.normal_notification_title,"Do you Remember this word:" + WordsToMemorize.vocabularyToBeMemorized + "?");
RemoteViews expandedNotificationView = new RemoteViews(getApplicationContext().getPackageName(),R.layout.custom_notification_expanded_view);
expandedNotificationView.setTextViewText(R.id.expanded_notification_title,"Do you Remember this word:" + WordsToMemorize.vocabularyToBeMemorized + "?");
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext());
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
Intent broadcastIntent = new Intent(getApplicationContext(), NotificationReceiver.class);
broadcastIntent.putExtra("vocabularyToBeMemorized", WordsToMemorize.vocabularyToBeMemorized);
PendingIntent actionIntent = PendingIntent.getBroadcast(getApplicationContext(),
0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new
NotificationChannel("simplfiedcoding", "simplfiedcoding", NotificationManager.IMPORTANCE_DEFAULT);
manager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), "simplfiedcoding")
.setSmallIcon(R.mipmap.ic_launcher)
.setLights(Color.YELLOW , 1000 , 1000)
.setColor(Color.BLUE)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setOnlyAlertOnce(true)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(collapsedNotificationView)
.setCustomBigContentView(expandedNotificationView)
.setContentIntent(resultPendingIntent)
.addAction(R.mipmap.dictionary,"yes",actionIntent);
int id = createID();
manager.notify(id, builder.build());
}
}
通知接收器类
public class NotificationReceiver extends BroadcastReceiver{
@Override
public void onReceive(final Context context, Intent intent) {
final String vocabularyToBeMemorizedFromNotification = intent.getStringExtra("vocabularyToBeMemorized");
Intent launchMainActivityIntent = context.getPackageManager().getLaunchIntentForPackage("com.example.安卓.dictionaryalmighty2");
if (launchMainActivityIntent != null) {
context.startActivity(launchMainActivityIntent);//null pointer check in case package name was not found
}
// This is only for null pointer errors before the app is fully launched and loaded
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Intent intent = new Intent(context.getApplicationContext(), ComboSearchActivity.class);
context.startActivity(intent);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// Just plain methods to look up dictionaries
loadFirstDefaultDictionaries();
loadSecondDefaultDictionaries();
loadThirdDefaultDictionaries();
}
}, 1000);
}
}, 1000); //1 second delay
}
# 1 楼答案
我认为这可能确实与通知的ID有关。您可以尝试this solution proposed by @sagar.android:
让我知道它是否有效
# 2 楼答案
正如我在评论中所建议的,您可以使用LinkedList(将用作队列):
替换
用你的话记住课堂上的内容:
然后,将该值添加到列表中,而不是将静态字符串设置为值:
并简单地替换
与
并在生成器中使用它来设置标题
希望有帮助
# 3 楼答案
我试着为你制作一个小应用程序来证明我的意思。现在,我不确定发布新通知的等待时间可能有多长,例如,如果时间是一周,您可以查看AlarmManager(如建议的here),而不是像我现在这样使用处理程序
现在,转到应用程序。这是一个至少有两个按钮的工作示例,“蝴蝶”和“棒球”:
main使用两个按钮进行活动强>
处理通知的自定义通知管理器:
我测试了这个应用程序,它似乎工作得很好