我正在安排在特定时间触发警报,它会在Oreo之前在设备上触发,而不是在Oreo上触发。我已经浏览了很多帖子和博客,讨论了Oreo中引入的背景限制和其他内容。所以我想要做的是在特定时间发出警报,删除选定的联系人并向用户显示有关该事件的通知。我已将此作为Reactnative项目完成,其中后台任务是在本机java上编写的。
BackgroundJobModule
public class BackgroundJobModule extends ReactContextBaseJavaModule {
private ReactApplicationContext reactContext;
BackgroundJobModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "BackgroundJob";
}
//function to schedule a new job
@ReactMethod
void scheduleJob(String contactID, Double time) {
Intent setAlarm = new Intent(reactContext.getBaseContext(), AlarmReceiver.class);
setAlarm.putExtra("_ID", contactID);
PendingIntent pendingIntent = PendingIntent.getBroadcast(reactContext.getBaseContext(),
getPendingIntentId(), setAlarm, 0);
Log.e("Reactcontext",reactContext.getLifecycleState()+"||");
AlarmManager alarmManager = (AlarmManager) reactContext.getSystemService(ALARM_SERVICE);
//if the user selects value less than 3 minutes then immediately show him the foreground notification
//else minus 3 minutes from the actual value and show the foreground service at that time
if(time.longValue()<180000){
if (SDK_INT >= Build.VERSION_CODES.M) {
Log.e("BJM Alarm Manager","SetExactAndAllowWhileIdle");
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time.longValue(), pendingIntent);
} else {
Log.e("BJM Alarm Manager","SetExact");
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() +time.longValue(), pendingIntent);
}
}else{
//fire before 10 seconds
if (SDK_INT >= Build.VERSION_CODES.M) {
Log.e("BJM Alarm Manager","SetExactAndAllowWhileIdle");
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (time.longValue()-10000), pendingIntent);
} else {
Log.e("BJM Alarm Manager","SetExact");
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (time.longValue()-10000), pendingIntent);
}
}
}
private int getPendingIntentId(){
SharedPreferences preferences = reactContext.getSharedPreferences("BackgroundJobCounter",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
String TAG = "pendingIntentID";
int id = preferences.getInt(TAG,0);
if(id == 0){
editor.putInt(TAG,id+1);
editor.commit();
}else{
editor.putInt(TAG,id+1);
editor.commit();
}
Log.e("PendingIntentId",preferences.getInt(TAG,0)+" || ");
return preferences.getInt(TAG,0);
}}
AlarmReceiver
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
super();
}
@Override
public void onReceive(Context context, Intent intent) {
Log.e("Alarm Receiver"," Received at "+System.currentTimeMillis());
Intent foregroundIntent = new Intent(context,DeleteContactService.class);
foregroundIntent.putExtra("_ID",intent.getStringExtra("_ID"));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(foregroundIntent);
}else{
context.startService(foregroundIntent);
}
}}
DeleteContactService
public class DeleteContactService extends Service {
Context context;
String _ID="";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent.getExtras()!=null){
_ID = intent.getStringExtra("_ID");
}else{
return Service.START_REDELIVER_INTENT;
}
if(doTheJob(_ID,context)){
stopSelf();
stopForeground(true);
}else{
stopForeground(true);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate() {
super.onCreate();
Log.e("DeleteContactService","OnCreate");
context = getApplicationContext();
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel("1001", "Purgee", NotificationManager.IMPORTANCE_HIGH);
notificationChannel.enableVibration(true);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.CYAN);
manager.createNotificationChannel(notificationChannel);
}
Notification mBuilder = new NotificationCompat.Builder(context, "1001")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Purgee")
.setChannelId("1001")
.setContentText(" Contact will be deleted ")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.build();
startForeground(getNotificationID(),mBuilder);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private boolean doTheJob(String _ID,Context context){
//check whether Write Contacts permission is granted then proceed
String readContactPermission = Manifest.permission.WRITE_CONTACTS;
int callingPermission = context.checkCallingPermission(readContactPermission);
//if permission is available t
// if(callingPermission== PackageManager.PERMISSION_GRANTED){
//Only project ID, DisplayName and LookupKey
String[] projection = new String[]{
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.LOOKUP_KEY
};
//Create a cursor to get all the contacts
Cursor contactCursor = context.getContentResolver()
.query(ContactsContract.Contacts.CONTENT_URI,
projection,
null,
null,
null);
//if Cursor has values then proceed
if (contactCursor.getCount() > 0) {
//move the cursor to the beginning
contactCursor.moveToFirst();
//while there is next value iterate
while (contactCursor.moveToNext()) {
String contactName = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String ID = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts._ID));
//if the ID matches then fetch the lookup key
if (contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts._ID))
.equalsIgnoreCase(_ID)) {
String lookUpKey = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookUpKey);
//delete the contact using the lookup key
if (context.getContentResolver().delete(uri, null, null) == 1) {
SharedPreferences sharedPreferences = context.getSharedPreferences("DeletedContacts", Context.MODE_PRIVATE);
SharedPreferences.Editor prefEditor = sharedPreferences.edit();
prefEditor.putInt(ID, Integer.parseInt(ID));
prefEditor.apply();
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel("1000", "Purgee", NotificationManager.IMPORTANCE_HIGH);
notificationChannel.enableVibration(true);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.WHITE);
manager.createNotificationChannel(notificationChannel);
}
Notification mBuilder = new NotificationCompat.Builder(context, "1000")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Purgee")
.setChannelId("1000")
.setContentText(contactName.concat(" has been deleted."))
.setPriority(NotificationCompat.PRIORITY_MAX)
.build();
manager.notify(getNotificationID(), mBuilder);
}else{
Log.e("Deleting ","Failed");
}
}else{
Log.e("Lookup","Failed");
}
}
}
//if the cursor Count is zero
else {
Log.e("Contacts", "Query Result Zero");
}
//close the cursor
contactCursor.close();
return true;
}
private int getNotificationID(){
SharedPreferences preferences = context.getSharedPreferences("NotificationCounter",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
String TAG = "NotificationID";
int id = preferences.getInt(TAG,0);
if(id == 0){
editor.putInt(TAG,id+1);
editor.commit();
}else{
editor.putInt(TAG,id+1);
editor.commit();
}
Log.e("Notification",preferences.getInt(TAG,0)+" || ");
return preferences.getInt(TAG,0);
}}
BackgroundJobModule根据用户给定的输入调度警报。 AlarmReceiver应接收广播并启动前台服务,通知用户该联系人将被删除。 DeleteContactService删除联系人并通知用户。
我需要此代码才能在Oreo及以上设备上运行。