Android: Async Task on CountDownTimer - java

I have a button on my activity that starts a notification and then also starts a Countdown Timer with an Async Task. The purpose of the code is to convert the millisUntilFinished to readable time and send it to my GUI in the second activityI get this fatal exception:
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.idkbro.pashchallenge, PID: 25702
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.os.CountDownTimer$1.<init>(CountDownTimer.java:114)
at android.os.CountDownTimer.<init>(CountDownTimer.java:114)
at com.idkbro.pashchallenge.MainActivity$1CDTTask$1.<init>(MainActivity.java:0)
at com.idkbro.pashchallenge.MainActivity$1CDTTask.doInBackground(MainActivity.java:250)
at com.idkbro.pashchallenge.MainActivity$1CDTTask.doInBackground(MainActivity.java:196)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:761) 
Here they said the error could be because of trying to update the GUI in the asynctask, but this isnt in my case because í send variable to the activity using an intent service. I think the problem could be how i "set up" my asynctask
The MainActivity class when the accept button is(P.S: so sorry about the code if its a but messy :( ):
public void agreeButton (View v){
Intent intent = new Intent(MainActivity.this, CountdownPage.class);
startActivity(intent);
NotificationCompat.Builder notificationBuiler = new NotificationCompat.Builder(this)
.setContentTitle("Pash Challenge")
.setContentText("You have so many minutes left")//TODO make notification display countdown
.setTicker("Alert new message")
.setSmallIcon(R.drawable.pashicon);//Code to display notification
Intent moreInfoIntent = new Intent(MainActivity.this, MoreInfoNotification.class);
notificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationID,notificationBuiler.build());
// Used to stack tasks across activites so we go to the proper place when back is clicked
TaskStackBuilder tStackBuilder = TaskStackBuilder.create(this);
// Add all parents of this activity to the stack
tStackBuilder.addParentStack(MoreInfoNotification.class);
// Add our new Intent to the stack
tStackBuilder.addNextIntent(moreInfoIntent);
// Define an Intent and an action to perform with it by another application
// FLAG_UPDATE_CURRENT : If the intent exists keep it but update it if needed
PendingIntent pendingIntent = tStackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
// Defines the Intent to fire when the notification is clicked
notificationBuiler.setContentIntent(pendingIntent);
isNotificationActive =true;
class CDTTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
Calendar calendar = Calendar.getInstance();
Long preTime = calendar.getTimeInMillis();
calendar.add(Calendar.DATE, 2);// set milliseconds for 2 days
Long postTime = calendar.getTimeInMillis();
Long delay = postTime - preTime;
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.RTC_WAKEUP, postTime, null);
CountDownTimer timer = new CountDownTimer(delay, 1) {
#Override
public void onTick(final long millisUntilFinished) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//SendAndCovert milliseconds to CoundownPage
SAndCDays(millisUntilFinished);
SAndCHours(millisUntilFinished);
SAndCMinutes(millisUntilFinished);
SAndCSeconds(millisUntilFinished);
}//End run
});//End runOnUiThread
}//End onTick
#Override
public void onFinish() {
}//End OnFinish
void SAndCDays(Long milli){ //Code to convert milliseconds to days and send it to CountdownPage.java
Long millis = (milli / (1000*60*60*24));
String days = ""+millis;
Intent numIntent = new Intent(getApplicationContext(), CountdownPage.class);
numIntent.putExtra("days", days);
startActivity(numIntent);
}//End SAndCDays
void SAndCMinutes(Long milli){ //Code to convert milliseconds to minutes and send it to CountdownPage.java
long millis = ((milli / (1000 * 60)) % 60);
String minutes = ""+millis;
Intent numIntent = new Intent(getApplicationContext(), CountdownPage.class);
numIntent.putExtra("minutes", minutes);
startActivity(numIntent);
}//End SAndCMinutes
//Code to convert milliseconds to hours and send it to CountdownPage.java
void SAndCHours(Long milli){
long millis = (milli/ (1000 * 60 * 60)) % 24;
String hours = ""+millis;
Intent numIntent = new Intent(getApplicationContext(), CountdownPage.class);
numIntent.putExtra("hours", hours);
startActivity(numIntent);
}//End SAndCHours
//Code to convert milliseconds to seconds and send it to CountdownPage.java
void SAndCSeconds(Long milli){
long millis = (milli/ 1000) % 60;
String seconds = ""+millis;
Intent numIntent = new Intent(getApplicationContext(), CountdownPage.class);
numIntent.putExtra("seconds", seconds);
startActivity(numIntent);
} //End SAndCSeconds
};
timer.start();
return null;
}//End doInBackground
}
CDTTask object = new CDTTask();
object.execute();//Code to start Countdown Async task
} // End agreeButton
Here is my Alert Receiver class if its of any help:
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
createNotification(context, "Times Up", " x Seconds has past","alert");// TODO change to CDT Time
}//End onReceive
public void createNotification(Context context, String msg,
String txtMsg,String msgAlert) {
PendingIntent notificIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
// Builds a notification
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.pashicon)
.setContentTitle(msg)
.setTicker(msgAlert)
.setContentText(txtMsg);
mBuilder.setContentIntent(notificIntent);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
}//End createNotification
}//End AlertReceiver.class
And how i receive and display the coveted times from the service:
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_challenge_page);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
TextView txtTimerDay=(TextView)findViewById(R.id.txtTimerDay);
TextView txtTimerMinute=(TextView)findViewById(R.id.txtTimerMinute);
TextView txtTimerHour=(TextView)findViewById(R.id.txtTimerHour);
TextView txtTimerSecond=(TextView)findViewById(R.id.txtTimerSecond);
txtTimerDay.setText(getIntent().getStringExtra("days"));
txtTimerMinute.setText(getIntent().getStringExtra("minutes"));
txtTimerHour.setText(getIntent().getStringExtra("hours"));
txtTimerSecond.setText(getIntent().getStringExtra("seconds"));
}

Related

Passing countdown timer value to next activity

i'm trying to pass the countdown timer value as textview to next activity, but i don't know how, do i need do use intent.putextra() ?
There is my code:
countDownTimer = new CountDownTimer(5000, 1000) {
#SuppressLint("DefaultLocale")
public void onTick(long millisUntilFinished) {
timpRamas.setText(String.format("%d:%d",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
public void onFinish() {
Intent intent = new Intent(c1_1.this,TimpExpirat.class);
startActivity(intent);
finish();
}
}.start();
You must pass the data of the textView to the next activity and in the next activity you can set the data in another view or do whatever with it:
public void onFinish() {
Intent intent = new Intent(c1_1.this,TimpExpirat.class);
intent.putExtra("data" , timpRamas.getText().toString());
startActivity(intent);
finish();
}
In the TimpExpirat activity:
//get the data in onCreate()
Intent intent = getIntent();
String time = intent.getStringExtra("data");
//time now has the time that was last set on your textview, you can set it
//to a new textview or do whatever with it.

Need some help troubleshooting code that schedules daily notifications

I am new to android programming and just started working on my first app recently. I am trying to create a daily notification that a user would get at the same time every day. I've looked through documentation and some tutorials and came up with this. For some reason the code below does not work. It has no errors, runs just fine, but doesn't do the job and I can't seem to find the problem. There is also some code that is responsible for re-scheduling notifications when the device restarts but I don't think the problem lies there since I don't even get the initial notifications.
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
show = (Button)findViewById(R.id.btn_show);
show.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startAlarm(true,true);
}
});
myWebView = (WebView)findViewById(R.id.webView1);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("http://google.com");
myWebView.setWebViewClient(new WebViewClient());
}
private void startAlarm(boolean isNotification, boolean isRepeat) {
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent myIntent;
PendingIntent pendingIntent;
// SET TIME HERE
Calendar calendar= Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,14);
calendar.set(Calendar.MINUTE,45);
myIntent = new Intent(MainActivity.this,AlarmNotificationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,0);
if(!isRepeat)
manager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,pendingIntent);
else
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,pendingIntent);
}
AlarmNotificationReciever.Java
public class AlarmNotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Intent myIntent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
myIntent,
FLAG_ONE_SHOT );
builder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Zodiac")
.setContentIntent(pendingIntent)
.setContentText("Check out your horoscope")
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND)
.setContentInfo("Info");
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1,builder.build());
}
}
It should basically schedule a notification at 14:45 after pressing the button but for some reason it doesn't.
Since Android Oreo, implicit broadcast receivers won’t work when
registered in the AndroidManifest.xml
To use Implicit Receivers in your application, you need to define them programmatically in your code, using
registerReceiver().
3.Using registerReceiver() we can programmatically register and unregisterReceiver() during the lifecycle of the activity. This way
implicit receivers would only be called when our
activity/application is alive and not at other times.
we working fine:
[public class MainActivity extends AppCompatActivity {
Button show;
WebView myWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// register custom intent filter
*registerReceiver(new AlarmNotificationReceiver(),new IntentFilter(Intent.ACTION_BATTERY_CHANGED));*
\[enter image description here\]\[1\]
show = (Button)findViewById(R.id.btn_show);
show.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onClick(View v) {
startAlarm(true,true);
}
});
myWebView = (WebView)findViewById(R.id.webView1);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("http://google.com");
myWebView.setWebViewClient(new WebViewClient());
}
#RequiresApi(api = Build.VERSION_CODES.N)
private void startAlarm(boolean isNotification, boolean isRepeat) {
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent myIntent;
PendingIntent pendingIntent;
// SET TIME HERE
Calendar calendar= Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,14);
calendar.set(Calendar.MINUTE,45);
myIntent = new Intent(MainActivity.this,AlarmNotificationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,0);
if(!isRepeat)
manager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,pendingIntent);
else
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,pendingIntent);
}
}][1]
1)But the above code may not work in all versions i.e notofication will not came oreo(8.0) and above.beacause of NotificationBuilder is depricated and background execution limits.Go to
2)Use Notification Channel .like below
use this code.hope its works fine!!!
void issueNotification()
{
// make the channel. The method has been discussed before.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
makeNotificationChannel("CHANNEL_1", "Example channel", NotificationManager.IMPORTANCE_DEFAULT);
}
// the check ensures that the channel will only be made
// if the device is running Android 8+
NotificationCompat.Builder notification =
new NotificationCompat.Builder(this, "CHANNEL_1");
// the second parameter is the channel id.
// it should be the same as passed to the makeNotificationChannel() method
notification
.setSmallIcon(R.mipmap.ic_launcher) // can use any other icon
.setContentTitle("Notification!")
.setContentText("This is an Oreo notification!")
.setNumber(3); // this shows a number in the notification dots
NotificationManager notificationManager =
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
assert notificationManager != null;
notificationManager.notify(1, notification.build());
// it is better to not use 0 as notification id, so used 1.
}

How to back to Main activity from the notification activity?

When I press the notification the activity opens, but when I click back the App go to background and still on the same activity.
I wanna go back to MainActivity when I click back. what's wrong in my code?
public class MainActivity extends AppCompatActivity {
NotificationManagerCompat notificationManager;
NotificationCompat.Builder n;
String ID = "a" ;
int id=1 ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void b2(View view) {
Intent i = new Intent(MainActivity.this, Main2.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(i);
PendingIntent pi = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
n = new NotificationCompat.Builder(this, ID)
.setSmallIcon(R.drawable.xx)
.setContentTitle("don't forget")
.setContentText("Hello0o0o0o")
.setContentIntent(pi)
.setAutoCancel(true);
notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(id , n.build());
id++;
}
public void b1(View view) {
Intent i4 = new Intent(this,Read.class);
startActivity(i4);
}
}
From your code I don't see the problem, but you could override the onBackPressed() function to move back to MainActivity. It's a solution. Also check if you actually are calling this function b2.

Error with Notification.Builder in notify

Hello I am new to Android, and I 'm trying to create notifications Notification.Builder and I failed . When launching the notification I get error
nm.notify(IDNOTIFICACIONUNO,notif); // Error in notif
I have downloaded the API 'S 16 17 18 19 23,
and this is all code :
public class MainActivity extends AppCompatActivity {
NotificationManager nm;
private static final int IDNOTIFICACIONUNO = 1;
Notification notif;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnLanzar = (Button) findViewById(R.id.boton_notificacion);
btnLanzar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),segundaVentana.class);
PendingIntent intencionPendiente = PendingIntent.getActivity(getApplicationContext(),0,i,0);
Notification.Builder notif = new Notification.Builder(getApplicationContext());
notif.setSmallIcon(R.drawable.tree);
notif.setTicker("App Nature ¡TIP!");
notif.setWhen(System.currentTimeMillis());
notif.setContentTitle("App Nature ¡TIP!");
notif.setContentText("Cierra la llave, cuando te estes cepillando");
notif.setContentInfo("TIP");
notif.setContentIntent(intencionPendiente);
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
nm.notify(IDNOTIFICACIONUNO,notif);
}
});
}
I also libraries . Thank you for your help
there is a ` characheter after notif.setSmallIcon(R.drawable.tree);
remove that charachter and code will run.
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//Connect to the button
Button iconBtn = (Button) findViewById(R.id.btn_icon);
//Set the button on click listener
iconBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
Notification notification = builder.setContentIntent(contentIntent).setTicker("This is a notification marquee")
.setSmallIcon(R.drawable.ic_launcher).setWhen(System.currentTimeMillis())
.setAutoCancel(true).setContentTitle("Message Title")
.setContentText("Message Content").build();
//Show the notification
nm.notify(1, notification);
}
});

Broadcast Data using Alarm Manager

I am trying to send data to my parse SDK Database using Alarm Manager.
I am able to send data without Alarm manager.
My below code is not working correctly as parse sdk database is not showing updated data.
Here is my code:
Main Activity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create_todo);
setTitle(R.string.create_todo);
alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
AlarmManager.INTERVAL_FIFTEEN_MINUTES,
AlarmManager.INTERVAL_FIFTEEN_MINUTES, alarmIntent);
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
MyAsyncTask asyncTask = new MyAsyncTask();
asyncTask.execute(new String[]{});
}
class MyAsyncTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... params) {
try {
ParseObject parseObject = new ParseObject("Todo");
parseObject.put("name", "abc");
parseObject.save();
}
catch(ParseException e)
{
}
return null;
}
}
}
Register your broadcast in AndroidManifest.xml file
Try below code:
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + AlarmManager.INTERVAL_FIFTEEN_MINUTES , AlarmManager.INTERVAL_FIFTEEN_MINUTES, pIntent);
From above code, Below things will be happened.
first time Broadcast will be fired after 15 min. then it will be fired every 15 min.

Categories

Resources