안드로이드 스튜디오 BroadcastReceiver에서 mainActivity의 메소드에 접근할때 메소드에 static을 추가하지 않고 접근할 수 있는 방법은 없을까요?
NotificationReciever
package com.example.dontforgetbirthdayproject;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import com.example.dontforgetbirthdayproject.activity.MainActivity;
import com.example.dontforgetbirthdayproject.fragment.HomeFragment;
import java.time.LocalDate;
public class NotificationReceiver extends BroadcastReceiver {
private String TAG = this.getClass().getSimpleName();
NotificationManager manager;
NotificationCompat.Builder builder;
//오레오 이상은 반드시 채널을 설정해줘야 Notification이 작동함
private static String CHANNEL_ID = "channel1";
private static String CHANNEL_NAME = "Channel1";
//수신되는 인텐트 - The Intent being received.
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive 알람이 들어옴!!");
String contentValue ="";
contentValue= intent.getStringExtra("content");
int requestCode = intent.getIntExtra("requestCode",0);
int id = intent.getIntExtra("id",0);
int day = intent.getIntExtra("day",0);
int year = intent.getIntExtra("year",0);
int month = intent.getIntExtra("month",0);
int hour = intent.getIntExtra("hour",0);
int minute = intent.getIntExtra("minute",0);
int alarmStartDay = intent.getIntExtra("alarmStartDay",0);
Log.e(TAG, "onReceive contentValue값 확인 : " + contentValue);
builder = null;
//푸시 알림을 보내기위해 시스템에 권한을 요청하여 생성
manager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
//안드로이드 오레오 버전 대응
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
manager.createNotificationChannel(
new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT)
);
builder = new NotificationCompat.Builder(context, CHANNEL_ID);
} else {
builder = new NotificationCompat.Builder(context);
}
//알림창 클릭 시 지정된 activity 화면으로 이동
Intent intent2 = new Intent(context, HomeFragment.class);
// FLAG_UPDATE_CURRENT ->
// 설명된 PendingIntent가 이미 존재하는 경우 유지하되, 추가 데이터를 이 새 Intent에 있는 것으로 대체함을 나타내는 플래그입니다.
// getActivity, getBroadcast 및 getService와 함께 사용
PendingIntent pendingIntent;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
pendingIntent = PendingIntent.getActivity(context,requestCode,intent2,
PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_MUTABLE);
} else {
pendingIntent = PendingIntent.getActivity(context,requestCode,intent2,
PendingIntent.FLAG_UPDATE_CURRENT);
}
LocalDate now = LocalDate.now(); //현재 날짜 가져오기
int dday = day-alarmStartDay; //생일 날짜 - 현재날 해서 생일로부터 남은 날 계산
//알림창 제목
builder.setContentTitle(contentValue+dday+"일 남았습니다."); //회의명노출
//builder.setContentText(intent.getStringExtra("content")); //회의 내용
//알림창 아이콘
builder.setSmallIcon(R.drawable.cake_alarm_icon);
//알림창 터치시 자동 삭제
builder.setAutoCancel(true);
builder.setContentIntent(pendingIntent);
//푸시알림 빌드
Notification notification = builder.build();
//NotificationManager를 이용하여 푸시 알림 보내기
manager.notify(id,notification);
if(day+2- now.getDayOfMonth()>=0){
Log.d("인수 확인",String.valueOf(year)+String.valueOf(month)+String.valueOf(day)+String.valueOf(hour)+String.valueOf(minute)
+String.valueOf(id)+contentValue+String.valueOf(requestCode));
MainActivity.isPushAlarmSend = true;
}
}
}
MainActivity의 setNotice 메소드
//알람매니저에 알람등록 처리
@RequiresApi(api = Build.VERSION_CODES.O)
public void setNotice(int year, int month, int alarmStartDay,int day, int hour, int minute, int id, String content, int requestCode) {
//알람을 수신할 수 있도록 하는 리시버로 인텐트 요청
Intent receiverIntent = new Intent(this, NotificationReceiver.class);
receiverIntent.putExtra("content", content);
receiverIntent.putExtra("requestCode", requestCode);
receiverIntent.putExtra("id",id);
receiverIntent.putExtra("year",year);
receiverIntent.putExtra("month",month);
receiverIntent.putExtra("day",day);
receiverIntent.putExtra("alarmStartDay",alarmStartDay);
receiverIntent.putExtra("hour",hour);
receiverIntent.putExtra("minute",minute);
/**
* PendingIntent란?
* - Notification으로 작업을 수행할 때 인텐트가 실행되도록 합니다.
* Notification은 안드로이드 시스템의 NotificationManager가 Intent를 실행합니다.
* 즉 다른 프로세스에서 수행하기 때문에 Notification으로 Intent수행시 PendingIntent의 사용이 필수 입니다.
*/
/**
* 브로드캐스트로 실행될 pendingIntent선언 한다.
* Intent가 새로 생성될때마다(알람을 등록할 때마다) intent값을 업데이트 시키기 위해, FLAG_UPDATE_CURRENT 플래그를 준다
* 이전 알람을 취소시키지 않으려면 requestCode를 다르게 줘야 한다.
* */
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getBroadcast(this, requestCode, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
} else {
pendingIntent = PendingIntent.getBroadcast(this, requestCode, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
//date타입으로 변경된 알람시간을 캘린더 타임에 등록
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DATE, alarmStartDay);
calendar.set(Calendar.HOUR_OF_DAY,hour);
calendar.set(Calendar.MINUTE,minute);
//알람시간 설정
//param 1)알람의 타입
//param 2)알람이 울려야 하는 시간(밀리초)을 나타낸다.
//param 3)알람이 울릴 때 수행할 작업을 나타냄
LocalDate now = LocalDate.now();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
이것저것 하다보니 접근을 하려면 setNotice 부분에 static을 붙여야 하던데 그러면 PendingIntent 안에 있는 this에 빨간줄이 쳐져서 어떻게 해야할지 모르겠습니다..
notificationReceiver에서 푸시알림을 보내고 나면 다시 setNotice에 다음날짜를 넣어서 호출하고 싶은데..
아무리 검색해봐도 자료가 적기도 하고 해답을 찾지 못해서 질문드립니다!