My app has an activity, an admin receiver and an alarm manager receiver. I want to be able to do the following things even when the app is closed:
1- disable the alarm and make a boolean preference false when device administrator is disabled
2- do some administrative tasks after the alarm is received.
I tried putting the code in the receivers but then the code only worked when the app is working. Then I tried initializing all the code related to the alarm manager and the device administrator before onCreate() but I couldn't reference the code in the receiver because some of it was dynamic.
So how can I achieve this?
The code
public class mainActivity extends ActionBarActivity {
static EditText numberOfHours;
static TextView hourText;
static Button setButton;
static Context context;
static DevicePolicyManager dpm;
static ComponentName admin;
static boolean adminCheck;
static Intent intent;
static SharedPreferences preferences;
static SharedPreferences.Editor editor;
static boolean appSet;
static AlarmManager alarmManager;
static PendingIntent alarmIntent;
static Intent mIntent;
static Calendar calendar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hourText = (TextView) findViewById(R.id.hourText);
numberOfHours = (EditText) findViewById(R.id.numberOfHours);
setButton = (Button) findViewById(R.id.setButton);
context = this;
dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
admin = new ComponentName(context, adminReceiver.class);
intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "The app needs to be a device administrator to be able to lock the screen");
preferences = getPreferences(Context.MODE_PRIVATE);
editor = preferences.edit();
editor.putBoolean("appSet", false);
appSet = preferences.getBoolean("appSet", false);
alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mIntent = new Intent(context, alarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 24, mIntent, 0);
calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 24);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
setButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (adminCheck) {
numberOfHours.setEnabled(false);
setButton.setEnabled(false);
setButton.setText("Done");
editor.putBoolean("appSet", true).commit();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),1000 * 60 * 60 * 24, alarmIntent);
}
else {
startActivityForResult(intent, 1);
}
}
});
}
static public class adminReceiver extends DeviceAdminReceiver {
#Override
public void onEnabled(Context context, Intent intent) {
super.onEnabled(context, intent);
}
#Override
public void onDisabled(Context context, Intent intent) {
super.onDisabled(context, intent);
}
#Override
public void onPasswordChanged(Context context, Intent intent) {
super.onPasswordChanged(context, intent);
}
}
static public class alarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm", Toast.LENGTH_SHORT).show();
}
}
}
If you want your code to run when your app is closed, you might want to look into Services.
Related
In my program, I am getting 2 dates from user. First date is for activating silence mode and the second date is deactivating it. For handling this issue, I have tried to use 2 different AlarmManager and 2 different BroadcastReceiver but I couldn't achieve it.
I can activate silence mode at the first date but I couldn't deactivate it. This a part of my code:
public class AddEvent extends AppCompatActivity {
private static PendingIntent silenceActivatorPendingIntent;
private static PendingIntent silenceDeactivatorPendingIntent;
private static AlarmManager manager1;
private static AlarmManager manager2;
#Override
protected void onCreate(Bundle savedInstanceState) {
Intent silenceActivatorIntent = new Intent(this, SilenceModeActivator.class);
Intent silenceDeactivatorIntent = new Intent(this, SilenceModeDeactivator.class);
silenceActivatorPendingIntent = PendingIntent.getBroadcast(this, 0, silenceActivatorIntent, 0);
silenceDeactivatorPendingIntent = PendingIntent.getBroadcast(this, 0, silenceDeactivatorIntent, 0);
manager2 = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
manager1 = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
}
public void addEvent(View view) {
GregorianCalendar targetStartDate = new GregorianCalendar(startYear, startMonth, startDay, startHour, startMinute, 0);
GregorianCalendar targetEndDate = new GregorianCalendar(endYear, endMonth, endDay, endHour, endMinute, 0);
manager1.set(AlarmManager.RTC_WAKEUP, targetStartDate.getTimeInMillis(), silenceActivatorPendingIntent);
manager2.set(AlarmManager.RTC_WAKEUP, targetEndDate.getTimeInMillis(), silenceDeactivatorPendingIntent);
}
public static void stopAlarm1() {
manager1.cancel(silenceActivatorPendingIntent);
}
public static void stopAlarm2() {
manager2.cancel(silenceDeactivatorPendingIntent);
}
}
addEvent is my button clicker method.
Silence Mode Activator:
public class SilenceModeActivator extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
activateSilentMode(context);
AddEvent.stopAlarm1();
}
public void activateSilentMode(Context context) {
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
// Check if the notification policy access has been granted for the app.
if (!mNotificationManager.isNotificationPolicyAccessGranted()) {
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
context.startActivity(intent);
}
mNotificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE);
}
}
Silence Mode Deactivator:
public class SilenceModeDeactivator extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
deactivateSilentMode(context);
AddEvent.stopAlarm2();
}
public void deactivateSilentMode(Context context) {
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
// Check if the notification policy access has been granted for the app.
if (!mNotificationManager.isNotificationPolicyAccessGranted()) {
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
context.startActivity(intent);
}
mNotificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
}
}
Do you have any idea about how I can fix this?
Thanks in advance.
I am new to android. I was playing with the AlarmManager and had successufully go a piece of code running with the BroadcastReceiver as a separate class.
I am now trying to put the BroadcastReceiver as inner class but have no luck on firing the BroadcastReceiver. I had no idea what might have gone wrong after hours looking at the code...
Here is my code:
public class InnerService extends Service{
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(InnerBroadcastReceiver.class.toString());
Log.d("InnerService","InnerService starts!");
Log.d("InnerService","class : "+InnerBroadcastReceiver.class.toString());
this.registerReceiver(new InnerBroadcastReceiver(), filter);
scheduleTestAlarmReceiver(this);
}
public static void scheduleTestAlarmReceiver(Context context) {
Log.d("scheduleTestAlarmReceiver", "scheduleTestAlarmReceiver start");
Intent receiverIntent = new Intent(context, InnerBroadcastReceiver.class);
receiverIntent.setAction("com.example.alarmmanagertest.InnerService$InnerBroadcastReceiver");
PendingIntent sender = PendingIntent.getBroadcast(context, 123456789,
receiverIntent, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), 1000, sender);
Log.d("scheduleTestAlarmReceiver", "scheduleTestAlarmReceiver complete");
}
private class InnerBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d("InnerBroadcastReceiver","InnerBroadcastReceiver ALARM Manager fires success!");
}
}
}
It looks like the AlarmManager tried to fire the BroadcastReceiver every second but failed
Logcat:
V/AlarmManager(2439): waitForAlarm result :4
V/AlarmManager(2439): trigger ELAPSED_REALTIME_WAKEUP or RTC_WAKEUP
UPDATE
I have tried to change the code for creating intent in onCreate() and scheduleTestAlarmReceiver() to intent = new intent("action_string") and it works. It seems that intent.setAction() is not working.
What will be the pros and cons for creating intent with and without context (Intent(Context packageContext, Class<?> cls) and Intent(String action))?
But I would still like to know why the above code failed. Can anyone explain?
True, it works!
Small changes in my code. Apk with AsyncTask (downloading file from web and parsing it). "OneMeeting" is my class from project.
public class MainActivity extends AppCompatActivity {
public static final String INPUT_FILE_URL = "https://.../";
private RecyclerView recyclerView;
private String getFilesDir;
private ArrayList<OneMeeting> meetingsArr = new ArrayList<>();
private BroadcastReceiver receiver;
private RefreshFile refreshFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
getFilesDir = getFilesDir().getAbsolutePath();
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
meetingsArr.add(new OneMeeting("Launching..." , "", "", ""));
recyclerView.setAdapter(new MyAdapter(meetingsArr, recyclerView));
Intent alarmIntent = new Intent("commaciejprogramuje.facebook.conferenceapplication.MainActivity$RefreshFile");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 111, alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 5, pendingIntent);
}
#Override
protected void onResume() {
super.onResume();
refreshFile = new RefreshFile();
IntentFilter filter = new IntentFilter("commaciejprogramuje.facebook.conferenceapplication.MainActivity$RefreshFile");
this.registerReceiver(refreshFile, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(refreshFile);
}
private class RefreshFile extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Refresh", Toast.LENGTH_LONG).show();
ParsePage refreshParsingPage = new ParsePage(new ParsePage.OnTaskCompletedListener() {
#Override
public void onTaskCompletedListener(ArrayList<OneMeeting> parsingResultArr) {
meetingsArr = parsingResultArr;
recyclerView.setAdapter(new MyAdapter(meetingsArr, recyclerView));
}
});
refreshParsingPage.execute(getFilesDir);
}
}
}
I have my alarms that calls onReceive() in my broadcast receiver.
public class MainActivity extends ActionBarActivity {
private Button bLoggOut, bStartTracking, bStop;
final private static String myAction = "com.brucemax.MY_ALARM_OCCURED";
Context ctx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
setContentView(R.layout.activity_main);
Log.d("myTag", "Alarm set "+String.valueOf(isAlarmSet()));
bStartTracking = (Button) findViewById(R.id.bStartTracking);
bStartTracking.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(myAction);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ContextHolder.getAppContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, 0/*updateTime.getTimeInMillis()*/, 5 * 1000, pendingIntent);
}
});
bStop = (Button) findViewById(R.id.bStop);
bStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
canselSetWakeUpMode();
}
});
}
public void canselSetWakeUpMode() {
Log.d("myTag", "MainActivity canselSetWakeUpMode()");
Intent myAlarm = new Intent(myAction);
// myAlarm.putExtra("project_id",project_id); //put the SAME extras
PendingIntent recurringAlarm = PendingIntent.getBroadcast(ctx, 1, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
alarms.cancel(recurringAlarm);
}
public boolean isAlarmSet() {
Intent myAlarm = new Intent(myAction);
return (PendingIntent.getBroadcast(ctx,1, myAlarm, PendingIntent.FLAG_NO_CREATE) != null) ;
}
}
MyReciever in manifest:
<receiver android:name=".Service.StartServiseWakefulReceiver">
<intent-filter>
<action android:name="com.brucemax.MY_ALARM_OCCURED"/>
</intent-filter>
</receiver>
Receiver:
public class StartServiseWakefulReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to our service.
Intent service = new Intent(context, HandleLocationService.class);
Log.d("myTag", "StartServiseWakefulReceiver onReceive()");
// Start the service, keeping the device awake while it is launching.
//Log.i("SimpleWakefulReceiver", "Starting service # " + SystemClock.elapsedRealtime());
startWakefulService(context, service);
}
}
It is work. When i run app at first isAlarmSet() is false. I start alarming, it is work, then I stop alarming (and it is realy stops), close app. But when I start app again the isAlarmSet() is true!!! But alarming not run. Why???
Regards!
I developed an app to start an activity at everyday 11pm. I also added a boot receiver on it. the output of this app gives nothing but a blank screen. Kindly someone help me.
This is my first class OnBootService
public class boot extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent bootintent) {
Intent mServiceIntent = new Intent();
mServiceIntent.setAction("com.thenga.nilavilak.timer_test001.alarm");
context.startService(mServiceIntent);
}
}
This is my alarm class
public class alarm extends boot {
public void onReceiveboot(final Context context) {
Calendar vtime = Calendar.getInstance();
vtime.set(Calendar.HOUR_OF_DAY,23);
vtime.set(Calendar.MINUTE,0);
vtime.set(Calendar.SECOND,0);
;
PendingIntent pi = PendingIntent.getService(context, 0,
new Intent(context, sasi.class),PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, vtime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pi);
}
public IBinder onBind(Intent arg0) {
return null;
}
}
This is my third class the want to run at 11 pm
public class sasi extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toast.makeText(getApplicationContext(),"Output received",Toast.LENGTH_SHORT).show();
}
}
Ok, I've tried two examples of AlarmManager- one from the commonsware website, and one from the manning website.
The code I am currently working with is from the manning website : [http://unlocking-android.googlecode.com/svn/chapter8/trunk/SimpleAlarm/][1]
There are two classes, AlarmReceiver and GenerateAlarm. Anyone have any idea why the toast will not display in the emulator? I was thinking that it was because I am located in the Eastern Time Zone and it uses UTC, but I have fiddled with different things and none of them seem to work.
public class GenerateAlarm extends Activity {
Toast mToast;
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.set_alarm_button);
button.setOnClickListener(this.mOneShotListener);
}
private OnClickListener mOneShotListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(GenerateAlarm.this, AlarmReceiver.class);
PendingIntent appIntent = PendingIntent.getBroadcast(GenerateAlarm.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// calendar.add(Calendar.MINUTE, 1);
calendar.add(Calendar.SECOND, 10);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), appIntent);
if (GenerateAlarm.this.mToast != null) {
GenerateAlarm.this.mToast.cancel();
}
GenerateAlarm.this.mToast = Toast.makeText(GenerateAlarm.this, R.string.alarm_message, Toast.LENGTH_LONG);
//GenerateAlarm.this.mToast.show();
}
};
}
public class AlarmReceiver extends BroadcastReceiver {
public void onReceiveIntent(Context context, Intent intent) {
Toast.makeText(context, R.string.app_name, Toast.LENGTH_SHORT).show();
}
#Override
public void onReceive(Context context, Intent intent) {
}
}
You have to add your toast in the onReceived method where you should add the handling of the intent received.
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, R.string.app_name, Toast.LENGTH_SHORT).show();
}
onReceiveIntent is not a method of broadcastreceiver
public abstract void onReceive
(Context context, Intent intent)
Since: API Level 1 This method is
called when the BroadcastReceiver is
receiving an Intent broadcast.