1

我想要的是:-

  • 制作一个应用程序,由用户在给定时间发出通知。
  • 它也应该在后台运行。
  • 我可以将时间小时和分钟 24 小时格式保存在 SharedPreferences 数据库中,以便我可以再次覆盖时间。
  • 其他部分,如何不发出通知?

但是我得到了什么

我做了这个,但我面临几个问题: -

  1. 我可以发出通知,但只有当我的应用程序处于运行状态时。
  2. 无法将变量 Xhours 和 Xminute 存储到 SharedPrefrences DB 中。
  3. 我的广播接收器类和通知类工作正常,但在应用程序未运行时无法获得通知。访问此:>链接以查看屏幕截图

请帮忙,谢谢。

我的 settings_aztro.java 活动

    public void TimePickerDialog() {


        TimeTv_settings.setOnClickListener(new View.OnClickListener() {
            @SuppressWarnings("deprecation")
            @Override
            public void onClick(View v) {

                showDialog(DIALOG_ID);
            }
        });

    }

    @SuppressWarnings("deprecation")
    @Override
    protected Dialog onCreateDialog(int id) {
        if (id == DIALOG_ID) {
            return new TimePickerDialog(settings_aztro.this, mTimePickerListener, Xhour, Xminute, false);
        } else {
            Toast.makeText(this, "Unable to locate time picker", Toast.LENGTH_SHORT).show();
            return null;

        }

    }




    protected TimePickerDialog.OnTimeSetListener mTimePickerListener = new TimePickerDialog.OnTimeSetListener() {
        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute)
        {
            // This will give 24hr value for the notification
            Xhour = hourOfDay;
            Xminute = minute;

            // This will show the 12 hour time on the TextView
            YHour = hourOfDay;
            Yminute = minute;


            if (YHour == 0) {
                YHour += 12;
                format = "AM";
            } else if (YHour == 12) {
                format = "PM";
            } else if (YHour > 12) {
                YHour -= 12;
                format = "PM";
            } else {
                format = "AM";
            }
            SharedPreferences sharedPreferences = getSharedPreferences("timeinfo", Context.MODE_ENABLE_WRITE_AHEAD_LOGGING);
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putInt("keyHour",Xhour);
            editor.putInt("keyMinute",Xminute);
            editor.commit();
            TimeTv_settings.setText(YHour + ":" + Yminute + " " + format);
            if(NotifyMe==true)
            {
                SharedPreferences xsharedPreferences = getSharedPreferences("timeinfo", Context.MODE_ENABLE_WRITE_AHEAD_LOGGING);
                savedHour = xsharedPreferences.getInt("keyHour", Integer.parseInt(""));
                savedMinute = xsharedPreferences.getInt("keyMinute",Integer.parseInt(""));

                Toast.makeText(settings_aztro.this, "YHour: "+YHour+"Ymin: "+Yminute+" "+format+"\tNotify: "+NotifyMe, Toast.LENGTH_SHORT).show();
                generateCustomNotification();
            }
            else
            {
                NotifyMe = false;

            }
        }
    };

public void generateCustomNotification()
{

    CustomCalendar.set(Calendar.HOUR_OF_DAY,savedHour);
    CustomCalendar.set(Calendar.MINUTE,savedMinute);
    CustomCalendar.set(Calendar.SECOND,0);

    Intent CallReciverIntent = new Intent(settings_aztro.this,NotificationBReceiver.class);
    PendingIntent pIntent = PendingIntent.getBroadcast(settings_aztro.this,0,CallReciverIntent,PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager alarmManager = (AlarmManager) settings_aztro.this.getSystemService(ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP,CustomCalendar.getTimeInMillis(),pIntent);
    Log.d("samay","Hour-> "+Xhour+" Minute-> "+Xminute+"Time in milis -> "+CustomCalendar.getTimeInMillis());

}


public void saveNotificationTime()
{

}



    @Override
    public void onClick(View v)
    {

        switch (v.getId())
        {
            case R.id.About_settingsTv2:
                Toast.makeText(this, "C", Toast.LENGTH_SHORT).show();
                generateCustomNotification();
                Log.d("Timeqq","Hour-> "+Xhour+" Minute-> "+Xminute);
                Xhour = 0;Xminute=0;
                break;

            case R.id.FacebookSignin_settings:

                Log.d("newtime","hour= "+Xhour+" minute= "+Xminute+"Time in milis -> "+CustomCalendar.getTimeInMillis()+"Notify "+NotifyMe);
                Log.d("newtime","hour= "+savedHour+" minute= "+savedMinute+"Time in milis -> "+CustomCalendar.getTimeInMillis()+"Notify "+NotifyMe);
                break;


        }


    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
    {
        if(switch_settings.isChecked())
        {
            NotifyMe = true;
            TimeRLayout.setVisibility(View.VISIBLE);
            Toast.makeText(this, "On", Toast.LENGTH_SHORT).show();
            Toast.makeText(this, "Hr -> "+Xhour+"Min -> "+Xminute, Toast.LENGTH_SHORT).show();
            Log.d("Waqt","Hour-> "+Xhour+" Minute-> "+Xminute);

        }
        else if(!switch_settings.isChecked())
        {
            NotifyMe = false;
            Toast.makeText(this, "Off", Toast.LENGTH_SHORT).show();
            if(NotifyMe==false)
            {
                TimeRLayout.setVisibility(View.GONE);

            }
            else
            {

            }

        }
    }

我的接收器类

 public class NotificationBReceiver extends BroadcastReceiver
{
    int MID = 98;
    @Override
    public void onReceive(Context context, Intent intent)
    {

long when = System.currentTimeMillis();
        NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        Intent notificationIntent = new Intent(context, list_of_signs.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 10,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder NotificationBuilder =  new NotificationCompat.Builder(context)
                .setSmallIcon(R.drawable.aztro2)
                .setSound(defaultSoundUri)
                .setContentTitle("Hello! Check Your Today's Horoscope.")
                .setAutoCancel(true)
                .setWhen(when)
                .setContentIntent(pendingIntent)
                .setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
        nManager.notify(MID, NotificationBuilder.build());
        MID++;;

清单文件

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_main_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/NoActionBar">
        <activity android:name=".list_of_signs">
            <!--list_of_signs-->
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity"/>
        <activity android:name=".AllSignsData.class_aquarius"/>
        <activity android:name=".AllSignsData.class_aries"/>
        <activity android:name=".AllSignsData.class_cancer"/>
        <activity android:name=".AllSignsData.class_gemini"/>
        <activity android:name=".AllSignsData.class_capricorn"/>
        <activity android:name=".AllSignsData.class_leo"/>
        <activity android:name=".AllSignsData.class_libra"/>
        <activity android:name=".AllSignsData.class_pisces"/>
        <activity android:name=".AllSignsData.class_sagittarius"/>
        <activity android:name=".AllSignsData.class_scorpio"/>
        <activity android:name=".AllSignsData.class_taurus"/>
        <activity android:name=".AllSignsData.class_virgo"/>

        <activity android:name=".settings_aztro"/>



        <receiver android:name=".NotificationBReceiver"/>
    </application>

</manifest>
4

1 回答 1

1

好的,这是警报管理器的模式。在这个实现中,没有使用静态定义的广播接收器/也不应该使用它来调度任务,根据 Android O 最佳实践,简而言之,如果你想要后台通知,请忘记广播接收器。

1) 创建一个意图服务 (ex.ReminderAlarmService) 来发布您的通知。此服务将使用 alarmManager 使用的待处理意图启动。onHandleIntent 应该创建通知并显示它:例如。

ReminderAlarmService.class
 @Override
    protected void onHandleIntent(Intent intent) {

        //..... Create your notification here
        manager.notify(NOTIFICATION_ID, notification);

        //..... Persist your data here in sharedPreferences here too, with or without user action
    }

2)在服务中,创建一个公共的util方法来返回“操作”挂起的意图以启动上述意图服务,(也称为深度链接意图)ex。

public static PendingIntent getReminderPendingIntent(Context context, Uri uri) {
    Intent action = new Intent(context, ReminderAlarmService.class);
    action.setData(uri);
    return PendingIntent.getService(context, 0, action, PendingIntent.FLAG_UPDATE_CURRENT);
}

3) 创建一个 util 类来获取警报管理器的实例,使用它来设置时间和使用上述方法创建的“操作”意图。操作意图启动意图服务,该服务执行您在 onHandleIntent 中所做的任何事情。前任。

public class AlarmScheduler {

    public static void scheduleAlarm(Context context, long alarmTime, Uri reminderTask) {
        AlarmManager manager = AlarmManagerProvider.getAlarmManager(context);

        PendingIntent operation =
                ReminderAlarmService.getReminderPendingIntent(context, reminderTask);

        manager.setExact(AlarmManager.RTC, time, operation);
    }
}

整体设计流程:

  1. AlarmManager 使用待定意图安排警报,以便在时间选择器作为参数启动您的服务。
  2. 当时间到达时,您的意图服务由待处理的意图启动
  3. 在意图服务中,构建并显示您的通知
  4. 当您的意图服务完成工作时,该服务会自动停止并清理。
于 2017-10-03T05:50:22.683 回答