I want to recall an activity after 12 minutes whole the times who get my JSON but i don't know how use timertask and timershedule can you help me please?
I try this but isn't work
my program:
public class recuperationJson extends AppCompatActivity implements getData.ReturnValue {
private getData data;
private TextView t;
private String json_string;
private String json_url = "http://192.168.0.14/projet/php/fichier.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
data = new getData(json_url);
data.setReturnListener(this);
data.execute((Void) null);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new Testing(), 0,5000);
}
#Override
public String renvoyerValeurString(String valeurARenvoyer) {
data = null;
//Ici je récupère directement mon json contenu dans la variable valeurARenvoyer
json_string = valeurARenvoyer;
Intent intent = new Intent(this,Accueil.class);
intent.putExtra("json_data", json_string);
startActivity(intent);
// Toast.makeText(this, json_string, Toast.LENGTH_SHORT).show();
return json_string;
}
public class Testing extends TimerTask {
public void run() {
Toast.makeText(recuperationJson.this, "test", Toast.LENGTH_SHORT).show();
}
}
My log
E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: com.suprem.projetfinal, PID: 3196
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.widget.Toast$TN.<init>(Toast.java:344)
at android.widget.Toast.<init>(Toast.java:100)
at android.widget.Toast.makeText(Toast.java:258)
at com.suprem.projetfinal.recuperationJson$Testing$override.run(recuperationJson.java:48)
at com.suprem.projetfinal.recuperationJson$Testing$override.access$dispatch(recuperationJson.java)
at com.suprem.projetfinal.recuperationJson$Testing.run(recuperationJson.java:0)
at java.util.Timer$TimerImpl.run(Timer.java:284)
This works for me. In calling class schedule your timer.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new Testing(), 0,5000);
in the testing class perform your activity
import java.util.TimerTask;
public class Testing extends TimerTask
{
public void run()
{
//your task here
}
}
Timer doesn't work once server get shutdown or restart. Better to use quartz.
There are 2 methods come up with my mind.
1 - Handler
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
System.out.println("RUN AFTER 12 minutes");
}
}, 12*60*1000);
2 - AlarmManager
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override public void onReceive( Context context, Intent _ )
{
System.out.println("RUN AFTER 12 minutes");
context.unregisterReceiver( this );
}
};
registerReceiver( receiver, new IntentFilter("message") );
PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("message"), 0 );
AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
// set alarm to fire
manager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60*1000*12, pintent );
Related
I'm developing a countdown app, and currently trying to show a notification when you exit the app while the countdown is running. Correspondingly, I want the notification to disappear when the user returns to the app.
So far I've managed to make it work for a simple notification with static text, do the following: in MainActivity.java, in onStop(), I create an intent and initiate the service with startService(intent). Symmetrically, in onStart() I run stopService(intent) so that when you return to the app the service gets canceled. This works like a charm, the notification appears and disappears when it must.
The next step has been trying to make the notification show a text that varies (it will say "X minutes remaining"). According to the info out there, to update an existing notification you have to create a new one, give it the same ID as the existing one, and call .notify of a NotificationManager. When I do this the notification indeed gets updated correctly (the text changes as expected), BUT: now, returning to the main activity does not cancel the notification. The icon stays up there and doesn't get interrupted.
I've been trying to solve this for hours and hours. I've also tried hacks like sending signals via shared preferences to tell the service to stop, but for some reason, it seems to completely ignore the command stopself() too.
Does anybody have a suggestion of what could be the cause? Any help would be greatly appreciated. Here is the relevant code:
MainActivity.java:
#Override
protected void onStart() {
super.onStart();
Intent serviceIntent = new Intent(getBaseContext(), CounterService.class);
stopService(serviceIntent);
}
protected void onStop() {
super.onStop();
Intent serviceIntent = new Intent(getBaseContext(), CounterService.class);
startService(serviceIntent);
}
CounterService.java:
public class CounterService extends Service {
Notification notification;
NotificationManager notificator;
Intent intentNoti;
CountDownTimer counter;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
intentNoti = new Intent(this, MainActivity.class);
final PendingIntent pending = PendingIntent.getActivity(this, 0, intentNoti, 0);
final Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.common_full_open_on_phone);
//Countdown
counter = new CountDownTimer (30000, 1000) {
public void onTick(long millisUntilFinished) {
String time = String.valueOf(System.currentTimeMillis());
notification = new Notification.Builder(CounterService.this)
.setContentTitle("Name")
.setContentText(time)
.setSmallIcon(R.drawable.icon_start)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pending)
.setOngoing(true).build();
notificator = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificator.notify(1001, notification);
}
public void onFinish() {
}
}.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
counter.cancel();
}
}
First create a Timer like this
private Timer timer;
private TimerTask timerTask;
public void startTimer() {
timer = new Timer();
timerTask = new TimerTask() {
public void run() {
// Add your code
}
};
timer.schedule(timerTask, 1000, 1000); //
}
Also you need to stop your timer.
So
public void stoptimertask() {
if (timer != null) {
timer.cancel();
timer = null;
}
}
Call StartTimer and StopTimer in OnStartCommand() and onDestroy() respectively. Add these lines in onDestroy()
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("restartservice");
broadcastIntent.setClass(this, Restarter.class);
this.sendBroadcast(broadcastIntent);
it can be handled in multiple ways, you have not stopped your timer
Note:- posting code in Kotlin
1)
override fun onDestroy() {
counter.cancel()
}
in your activity
override fun onResume() {
super.onResume()
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancelAll()
}
I have an application in which I'm receiving a sms containing his location.On receiving sms it calls another activity to start and passes that location to that activity to plot it on the map.Before calling the second activity it shows a toast like notification on the screen but somehoe due to calling second activity that toast doesn't come up.My question is how can we delay the calling of second activity from this activity ?
You can use something like this:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i=new Intent(SearxhJobs.this,JobsTypes.class);
startActivity(i);
}
}, 5000);
Here it waits upto 5 seconds to launch activity.
Hope it helps
You can do it with a Handler like this
Handler h = new Handler(){
#Override
public void handleMessage(Message msg) {
Intent i = new Intent().setClass(ctx, MainActivity.class);
startActivity(i);
}
};
h.sendEmptyMessageDelayed(0, 1500); // 1500 is time in miliseconds
Make an AsyncClass that does Thread.sleep() in the doInBackground() method, then navigate to your new activity in the your onPostExecute() method.
Call your toast message and then execute the AsyncClass.
For Kotlin
Handler().postDelayed({
val i = Intent(this, MainActivity::class.java)
startActivity(i)
}, 5000)
Try:
Runnable r = new Runnable() {
#Override
public void run() {
// if you are redirecting from a fragment then use getActivity() as the context.
startActivity(new Intent(SplashActivity.this, MainActivity.class));
// To close the CurrentActitity, r.g. SpalshActivity
finish();
}
};
Handler h = new Handler();
// The Runnable will be executed after the given delay time
h.postDelayed(r, 1500); // will be delayed for 1.5 seconds
Simply set the layout!
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.next); //where <next> is you target activity :)
}
}, 5000);
An example would be the following:
Handler TimeDelay=new Handler();
if(previous=="geofence"){
tts.speak(previous,TextToSpeech.QUEUE_ADD,null, null);
Runnable r = new Runnable() {
#Override
public void run() {
/*
Intent intent = new Intent(
MyBroadcastMessageReceiver.class.getName());
intent.putExtra("some additional data", choice);
someActivity.sendBroadcast(intent);*/
tts.speak(previous,TextToSpeech.QUEUE_ADD,null, null);
}
};
TimeDelay.postDelayed(r, 150000);
I created a simple android app that will send notification every minutes. For that I use Service in this app. Look the Service code bellow.
public class notiService extends Service {
private final static int interval = 1000 * 60;
Handler myHandler;
Runnable myRunable;
MediaPlayer mp;
Intent intent;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mp = MediaPlayer.create(this,R.raw.noti2);
createRunnable();
startHandler();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
/**
* Destroy Handler and Runnable
*/
myHandler.removeCallbacks(myRunable);
super.onDestroy ();
}
/**
* Runnable method
*/
public void createRunnable(){
myRunable = new Runnable() {
#Override
public void run() {
mp.start();
send_notification("Notification title", "10");
myHandler.postDelayed(this, interval); /* The interval time */
}
};
}
/**
* Handler method
*/
public void startHandler(){
myHandler = new Handler();
myHandler.postDelayed(myRunable, 0);
}
/**
* Notification method
*/
public void send_notification(String title, String min){
intent = new Intent(getApplicationContext(),MainActivity.class);
//intent.putExtra("open_fragment","open_f2");
PendingIntent my_pIntent = PendingIntent.getActivities(notiService.this,0, new Intent[]{intent},0);
Notification mynoti = new Notification.Builder(notiService.this)
.setContentTitle(title)
.setContentText("It will be start after "+min+" minutes.")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(my_pIntent).getNotification();
mynoti.flags = Notification.FLAG_AUTO_CANCEL;
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(0,mynoti);
}
}
It work properly when the app running. But if I close the app and device go to sleep mode, this code don't work properly.
This time it send notification after 10 minutes or more.
I can't understand why it behave like this! How I can fixed this problem?
Thank you for your response.
you are using handler for this. Handler does not work when device goes to sleep . you can see this link for running handler in sleep mode
I created sticky background service, that should be started on boot:
public class AutostartReceiver extends BroadcastReceiver
{
public AutostartReceiver()
{
}
#Override
public void onReceive(Context context, Intent intent)
{
context.startService(new Intent(context, MyService.class));
}
}
My service is intended to do some work in background, it's implemented by creating thread for this. Also there is Messenger class used for sending work status to my main activity:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i(TAG, "Service onStartCommand " + startId);
final int currentId = startId;
Messenger callback = null;
if(intent!=null)
{
callback = intent.getParcelableExtra("messenger");
}
final Messenger finalCallback = callback;
Runnable r = new Runnable()
{
public void run()
{
... do something, then stop
stopSelf();
}
};
if(t == null)
{
t = new Thread(r);
t.start();
}
return Service.START_STICKY;
}
Main activity receives messages sent from background thread running inside my service (some commands, that service is sending periodically:
Handler mHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case 0:
Toast.makeText(MainActivity.this,"Service runing", Toast.LENGTH_LONG).show();
break;
}
}
};
This works only if I start my service from activity, with activity's context. Obviously, if service is started on boot, or my app was closed (removed from last app list) and opened again, my activity is unable to get any messages from service any more.
If I invoke start service while service is already running, it will simply run OnStartCommand again, so either new thread will be created (I don't want it) or I need to destroy running thread and run thread again.
Is there any way to get my activity receiving messages from service, without actually touching already running thread inside it? I know about bound services, but it's not clear for me how to use them in my specific case.
As Alternate way You can use LocalBroadcastManager to send Data from Service to Activity.
Broadcast Your message from Service:
private void broadcastMessage(Context context){
Intent intent = new Intent("UI_UPDATE_BROADCAST");
intent.putExtra("MESSAGE", "MyMessage");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
Register Broadcast Receiver in your activity to receive messages:
#Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(mContext).registerReceiver(mMessageReceiver, new IntentFilter("UI_UPDATE_BROADCAST"));
}
#Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mMessageReceiver);
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Do Something With Received Data
String msg = intent.getStringExtra("MESSAGE");
}
};
I would use a broadcast receiver for Service-to-Activity communication.
Code:
public class MyActivity extends Activity {
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Toast here
}
#Override
protected void onCreate(Bundle savedInstanceState) {
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter("message-name"));
}
#Override
public void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
}
Then in your service you would broadcast the message like this:
Intent intent = new Intent("message-name");
intent.putExtra("data", 1);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
I need to create a schedule service in android with java. I have tried some codes , but all time after build the application it doesn't run. My logic is simple , I want to make a service to check the existence of a file in the bluetooth folder path, If this file is there , so this service will run another application , I need this with a schedule which run every 2 minutes.
Until now that's great, but now I have an error The method startActivity(Intent) is undefined for the type MyTimerTask. I have tried this code...
public class MyTimerTask extends TimerTask {
java.io.File file = new java.io.File("/mnt/sdcard/Bluetooth/1.txt");
public void run(){
if (file.exists()) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
}
}
}
Could someone please help me with this.
There are two ways to achieve your requirement.
TimerTask
Alarm Manager Class
TimerTask has a method that repeats the activity on the given particular time interval. look at the following sample example.
Timer timer;
MyTimerTask timerTask;
timer = new Timer();
timerTask = new MyTimerTask();
timer.schedule ( timerTask, startingInterval, repeatingInterval );
private class MyTimerTask extends TimerTask
{
public void run()
{
...
// Repetitive Activity goes here
}
}
AlarmManager does same thing like TimerTask but as it occupies lesser memory to execute tasks.
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
try
{
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
AlarmClass,
private static Intent alarmIntent = null;
private static PendingIntent pendingIntent = null;
private static AlarmManager alarmManager = null;
// OnCreate()
alarmIntent = new Intent ( null, AlarmReceiver.class );
pendingIntent = PendingIntent.getBroadcast( this.getApplicationContext(), 234324243, alarmIntent, 0 );
alarmManager = ( AlarmManager ) getSystemService( ALARM_SERVICE );
alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, ( uploadInterval * 1000 ),( uploadInterval * 1000 ), pendingIntent );