📜 ⬆️ ⬇️

Manual Start Timer

Hi, Habr. This article is addressed to comprehending the art of Android development, just like me.

Recently, I had to do a timer that starts a task after a certain period of time.

But the differences from the standard solution were as follows:

The problem was solved as follows.

Let's write a test application. Create a project with empty activity.

The form:
')
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="ru.alerttest.MainActivity"> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" " android:id="@+id/checkBox" android:checked="true" android:layout_below="@+id/button" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" " android:id="@+id/button" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="  " android:id="@+id/checkBox2" android:checked="true" android:layout_below="@+id/checkBox" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> </RelativeLayout> 


Create a new IntentService, with the name UniversalService.

In the MainActivity we make changes to onCreate:

onCreate
  CheckBox checkBox, checkBox1; SharedPreferences sPref; SharedPreferences.Editor editor; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); checkBox = (CheckBox)findViewById(R.id.checkBox); sPref = getSharedPreferences("AlertTest",MODE_PRIVATE); editor = sPref.edit(); editor.putBoolean("chbAutomatic", checkBox.isChecked()); editor.putBoolean("success", checkBox.isChecked()); editor.commit(); checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { editor.putBoolean("chbAutomatic", checkBox.isChecked()); editor.commit(); setServiceAlarm(MainActivity.this); } }); checkBox1 = (CheckBox)findViewById(R.id.checkBox2); checkBox1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { editor.putBoolean("success", checkBox1.isChecked()); editor.commit(); setServiceAlarm(MainActivity.this); } }); Button button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("AlertTest", "   "); Intent intent = new Intent(MainActivity.this, UniversalService.class); startService(intent); } }); } 


And add a method:

 public void setServiceAlarm(Context context){ SharedPreferences settings = getSharedPreferences("AlertTest", MODE_PRIVATE); Boolean automaticSynchronize = settings.getBoolean("chbAutomatic", false); Intent intent = new Intent(context, UniversalService.class); PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Integer period = 5; if(automaticSynchronize){ alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), period*1000, pendingIntent); Log.d("AlertTest", "   , : "+period*1000); } else { Log.d("AlertTest", " "); alarmManager.cancel(pendingIntent); pendingIntent.cancel(); } } 

In this code (in the onCreate method), we save in the General Settings, with the name “AlertTest”, the state of the checkboxes, and (in the setServiceAlarm method) we start the timer with a periodicity of 5 seconds, to run the UniversalService service.

Also, we want to receive a response from the service, about the success of the operation.

To do this, add a class to the MainActivity:

  public class MyBroadRec extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Boolean result = intent.getBooleanExtra(UniversalService.EXTRA_KEY_OUT, false); Intent intentRec = new Intent(MainActivity.this, UniversalService.class); if(!result){ Log.d("AlertTest", " "); startService(intentRec); } } } 

And add onCreate to the end:

  MyBroadRec myBroadRec = new MyBroadRec(); IntentFilter intentFilter = new IntentFilter(UniversalService.ACTION_MYINTENTSERVICE); intentFilter.addCategory(Intent.CATEGORY_DEFAULT); registerReceiver(myBroadRec, intentFilter); setServiceAlarm(MainActivity.this); 

And in UniversalService, we change the code to the following:

Universalservice
 package ru.alerttest; import android.app.IntentService; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; public class UniversalService extends IntentService { public static final String EXTRA_KEY_OUT = "EXTRA_OUT"; public static final String ACTION_MYINTENTSERVICE = "ru.timgor.alerttest.RESPONSE"; public UniversalService() { super("UniversalService"); } @Override protected void onHandleIntent(Intent intent) { Log.d("AlertTest", " "); if(!verify()){ Intent responseIntent = new Intent(); responseIntent.setAction(ACTION_MYINTENTSERVICE); responseIntent.addCategory(Intent.CATEGORY_DEFAULT); responseIntent.putExtra(EXTRA_KEY_OUT, false); Log.d("AlertTest", "  "); sendBroadcast(responseIntent); } else{ Log.d("AlertTest", "  "); } } public boolean verify(){ SharedPreferences settings = getSharedPreferences("AlertTest", MODE_PRIVATE); Boolean success = settings.getBoolean("success", false); return success; } } 


As you can see, the verify method emulates our task. In the event that it is executed unsuccessfully, an Intent is created that starts MyBroadRec, which starts our service again. We can configure through the checkbox "Very important option." If we put the “Auto Start” checkbox in an inactive state, the timer will stop working. As soon as the task is completed, we switch to normal mode.

But we still have the task of autostarting our application. To do this, create a UniversalReceiver class inheriting from BroadcastReceiver:

 package ru.alerttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; public class UniversalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d("AlertTest", "  "); Intent intentNew = new Intent(context, MainActivity.class); intentNew.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intentNew); } } 

And in the manifest we add the following lines:

  <receiver android:name=".UniversalReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> 

Everything, the problem is solved. So let me leave. I hope someone will be useful. If someone has comments and tips, I will listen to them with great pleasure.

PS: Classes in full:

MainActivity
 package ru.alerttest; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; public class MainActivity extends AppCompatActivity { CheckBox checkBox, checkBox1; SharedPreferences sPref; SharedPreferences.Editor editor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); checkBox = (CheckBox)findViewById(R.id.checkBox); sPref = getSharedPreferences("AlertTest",MODE_PRIVATE); editor = sPref.edit(); editor.putBoolean("chbAutomatic", checkBox.isChecked()); editor.putBoolean("success", checkBox.isChecked()); editor.commit(); checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { editor.putBoolean("chbAutomatic", checkBox.isChecked()); editor.commit(); setServiceAlarm(MainActivity.this); } }); checkBox1 = (CheckBox)findViewById(R.id.checkBox2); checkBox1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { editor.putBoolean("success", checkBox1.isChecked()); editor.commit(); setServiceAlarm(MainActivity.this); } }); Button button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("AlertTest", "   "); Intent intent = new Intent(MainActivity.this, UniversalService.class); startService(intent); } }); MyBroadRec myBroadRec = new MyBroadRec(); IntentFilter intentFilter = new IntentFilter(UniversalService.ACTION_MYINTENTSERVICE); intentFilter.addCategory(Intent.CATEGORY_DEFAULT); registerReceiver(myBroadRec, intentFilter); setServiceAlarm(MainActivity.this); } public class MyBroadRec extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Boolean result = intent.getBooleanExtra(UniversalService.EXTRA_KEY_OUT, false); Intent intentRec = new Intent(MainActivity.this, UniversalService.class); if(!result){ Log.d("AlertTest", " "); startService(intentRec); } } } public void setServiceAlarm(Context context){ SharedPreferences settings = getSharedPreferences("AlertTest", MODE_PRIVATE); Boolean automaticSynchronize = settings.getBoolean("chbAutomatic", false); Intent intent = new Intent(context, UniversalService.class); PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Integer period = 5; if(automaticSynchronize){ alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), period*1000, pendingIntent); Log.d("AlertTest", "   , : "+period*1000); } else { Log.d("AlertTest", " "); alarmManager.cancel(pendingIntent); pendingIntent.cancel(); } } } 


Universalservice
 package ru.alerttest; import android.app.IntentService; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; public class UniversalService extends IntentService { public static final String EXTRA_KEY_OUT = "EXTRA_OUT"; public static final String ACTION_MYINTENTSERVICE = "ru.timgor.alerttest.RESPONSE"; public UniversalService() { super("UniversalService"); } @Override protected void onHandleIntent(Intent intent) { Log.d("AlertTest", " "); if(!verify()){ Intent responseIntent = new Intent(); responseIntent.setAction(ACTION_MYINTENTSERVICE); responseIntent.addCategory(Intent.CATEGORY_DEFAULT); responseIntent.putExtra(EXTRA_KEY_OUT, false); Log.d("AlertTest", "  "); sendBroadcast(responseIntent); } else{ Log.d("AlertTest", "  "); } } public boolean verify(){ SharedPreferences settings = getSharedPreferences("AlertTest", MODE_PRIVATE); Boolean success = settings.getBoolean("success", false); return success; } } 


Universalreceiver
 package ru.alerttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; public class UniversalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d("AlertTest", "  "); Intent intentNew = new Intent(context, MainActivity.class); intentNew.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intentNew); } } 



PPS: Made changes to the BroadcastReceiver, for errors that Handy and BlackStream indicated to me.
Now I understand with the SyncAdapter.

Source: https://habr.com/ru/post/309408/


All Articles