定时短信的实现

定时发送短信

主要依赖AlarmManager以及SmsManager

配置xml


        <receiver android:name="com.chenggongyun.receiver.AlarmReceiver"
            android:permission="android.provider.Telephony.SMS_RECEIVED"
            >
            <intent-filter >
                <action android:name="AlarmReceiver"/>
                <category android:name="android.intent.category.DEFAULT" />
            intent-filter>
        receiver>
<uses-permission android:name="android.permission.SEND_SMS"/>

定时闹钟

if(TextUtils.isEmpty(smsEdit.getText().toString())){
            Toast.makeText(getApplicationContext(), "请输入短信内容", Toast.LENGTH_SHORT).show();
            return;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, datePicker.getYear());
        calendar.set(Calendar.MONTH, datePicker.getMonth());
        calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
        calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
        calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());
        Intent intent=new Intent(Activity_kehudetail_addSMS.this,AlarmReceiver.class);
        intent.putExtra("SMS", smsEdit.getText().toString());
        intent.putExtra("Phone", kehu.getShouji());
        intent.setAction("AlarmReceiver");  
         pi=PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
         am = (AlarmManager) Activity_kehudetail_addSMS.this.getSystemService(Context.ALARM_SERVICE);
        if (calendar.getTimeInMillis()<=System.currentTimeMillis()) {
            Toast.makeText(getApplicationContext(), "请重新设置时间", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getApplicationContext(), "成功设置定时短信,请保存"+datePicker.getYear()+datePicker.getMonth()
                    +datePicker.getDayOfMonth()+timePicker.getCurrentHour()+timePicker.getCurrentMinute(), Toast.LENGTH_SHORT).show();
            am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),pi);
            // AlarmManager.RTC_WAKEUP休眠时会运行,如果是AlarmManager.RTC,在休眠时不会运行
            //am.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), 86400000, pi);此方法为循环发广播,即周期性提醒,86400000为时间间隔单位为毫秒
        }

处理广播即时间到达发送广播然后发送短信,建议不使用内部类创建广播接受者,否则需要用static修饰,然后里面的传过来的参数也得是static的

SmsManager smsManager = SmsManager.getDefault();
        String content=intent.getStringExtra("SMS");
        Log.e("main", "收到广播"+content);
        Toast.makeText(context, "收到广播", Toast.LENGTH_SHORT).show();
        smsManager.sendTextMessage(intent.getStringExtra("Phone"), null, content, null, null);
        Toast.makeText(context, "已经发送定时短信", Toast.LENGTH_SHORT).show();

简单做一个notify作为发短信后的提醒

NotificationManager manager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context)
                        .setSmallIcon(R.drawable.ic_action_expand)
                        .setTicker("有新提醒")
                        .setContentTitle("app提醒")
                        .setContentText("短信发送成功")
                        .setDefaults(Notification.DEFAULT_ALL);
        PendingIntent contentIntent = PendingIntent.getActivities(context, 0,
                makeIntentStack(context), PendingIntent.FLAG_CANCEL_CURRENT);
        mBuilder.setContentIntent(contentIntent);
        Notification notification = mBuilder.build();
        notification.flags |= Notification.FLAG_AUTO_CANCEL; //可以手动清除提醒
        notification.ledOnMS = 10000;
        manager.notify(0, notification);
//makeIntentStack(context)下拉菜单 点击提醒的跳转,可以是new intent

private static Intent[] makeIntentStack(Context context) {
        Intent[] intents = new Intent[1];
        intents[0] = Intent.makeRestartActivityTask(new ComponentName(context,
                com.chengxiang.zhaogongjiang.ui.LoginActivity.class));
        return intents;
    }

以上经验证只能有一条定时短信存在原因为:

1.如果声明的triggerAtMillis是一个过去的时间,闹钟将会立即被触发。
2.如果已经有一个相同intent的闹钟被设置过了,那么前一个闹钟将会取消,被新设置的闹钟所代替。
两个Intent从intent resolution(filtering)(Intent决议或过滤)的角度来看是一致的,即认为两个Intent相等。即是说,Intent的action,data,type,class,categories是相同的,其他的数据都不在比较范围之内
由此可知,intent为相同的,所以只有一个有效。

另外

 <receiver
            android:process=":remote" />

在此讨论一下process属性,它规定了组件(activity, service, receiver等)所在的进程。

  通常情况下,没有指定这个属性,一个应用所有的组件都运行在应用的默认进程中,进程的名字和应用的包名一致。

  比如manifest的package=”com.example.helloalarm”,则默认进程名就是com.example.helloalarm。
  元素的process属性可以为全部的组件设置一个不同的默认进程。
  组件可以override这个默认的进程设置,这样你的应用就可以是多进程的。
  如果你的process属性以一个冒号开头,进程名会在原来的进程名之后附加冒号之后的字符串作为新的进程名。当组件需要时,会自动创建这个进程。这个进程是应用私有的进程。
  如果process属性以小写字母开头,将会直接以属性中的这个名字作为进程名,这是一个全局进程,这样的进程可以被多个不同应用中的组件共享。

你可能感兴趣的:(2016)