IntentService which is started by AlarmManager doesn't work - java

I'm trying to get IntentService started by AlarmManager, but the service isn't started.
(Obviously my service is defined in the manifest...)
Here's a little bit of code:
Starting the alarm service:
Intent myIntent = new Intent(Main.this, TestsNotification.class);
PendingIntent pendingIntent = PendingIntent.getService(Main.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 15);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Here's my IntentService:
public class TestsNotification extends IntentService {
public TestsNotification() {
super("myApp");
}
private SharedPreferences settings;
private final String PREFERENCE_SETTINGS_FILENAME = "Settings";
private int number=0;
Tests tests;
#Override
public void onCreate() {
// TODO Auto-generated method stub
settings = getSharedPreferences(PREFERENCE_SETTINGS_FILENAME, MODE_PRIVATE);
tests=new Tests();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
#Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}
public void Notify(String title)
{
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent= new Intent (this,Splash.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
String body = " בליך";
//String title = "יש מחר מבחן!";
Notification n =new Notification(R.drawable.test, body, System.currentTimeMillis());
n.flags |=Notification.FLAG_AUTO_CANCEL;
n.setLatestEventInfo(getApplicationContext(), title, body, pi);
n.defaults = Notification.DEFAULT_ALL;
number++;
n.number=number;
try {
nm.notify(0,n);
FileMethods FM = new FileMethods(this);
Date current = new Date();
FM.Write("LOG", "I Dont Care!",FM.Read("LOG", this, "") + current.getDay()+"/"+current.getMonth()+"/"+ current.getYear()+" "+current.getHours()+":"+current.getMinutes() + "Notified" + title+ "\n");
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
String Attribute = "Class";
String info = settings.getString(Attribute, "none");
if(!info.equals("none")) {
String classLetter = info.substring(0, info.lastIndexOf(" "));
String classNum1 = info.substring(info.lastIndexOf(" ")+1);
int classNum = Integer.parseInt(classNum1);
try {
Tests nextTest = this.tests.GetTests(classLetter, classNum)[0];
Date current = new Date();
Date testDate = new GregorianCalendar(nextTest.getDate().getYear(), nextTest.getDate().getMonth(), Integer.parseInt(nextTest.getDate().getDay())).getTime();
long difference = testDate.getTime()-current.getTime();
if (difference <=86400000) {
Notify("יש מחר מבחן!");
}//SHOULDNT BE HARDCODED!!!
else {
Notify("אין מחר מבחן!!");
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
FileMethods is just a class to handle File reading and writing (to make sure the AlarmManager runs every 1 day)
Thank you!!

Since you are using set(), there is a 40% chance that you have now specified a time that is in the past.
Also, if the device is asleep at the time, it may fall back asleep before your service is started. There is a very specific pattern for using _WAKEUP alarms successfully, involving a BroadcastReceiver and a WakeLock. My WakefulIntentService tries to handle some of this work for you.
Also, onStart() has been deprecated for quite some and should not be implemented on an IntentService.

You override #onCreate() in your IntentService without calling super.onCreate(). Don't do that.
#Override
public void onCreate() {
super.onCreate();
settings = getSharedPreferences(PREFERENCE_SETTINGS_FILENAME, MODE_PRIVATE);
tests=new Tests();
}
The IntentService base implementation does a lot of necessary setup in that method (such as initializing the executor & whatnot) required to actually call IntentService#onHandleIntent(Intent).

Related

How can I stop my service using broadcast receiver

I'm trying to stop my service with stopService(), but it will still running. It only stops when I unregister the brodcast receiver, but when I register that again, there will be two actions activated at the same time.
The thread is still running somehow, I really tried everything and reading every single post on the forum but I dind't find a solution.
Service Class
public class MyService extends Service {
final static String MY_ACTION = "MY_ACTION";
private static Context context;
private Timer timer;
public String Data;
String ok = "Database\n";
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
MyThread myThread = new MyThread();
myThread.start();
return super.onStartCommand(intent, flags, startId);
}
public class MyThread extends Thread{
#Override
public void run() {
// TODO Auto-generated method stub
try {
int delay = 1000; // delay for 1 sec.
int period = 5 * 1000; // repeat every 120 sec.
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Calendar c = Calendar.getInstance();
Data = String.valueOf((c.get(Calendar.MILLISECOND)));
Intent intent = new Intent();
intent.setAction(MY_ACTION);
intent.putExtra("DATAPASSED", ok);
sendBroadcast(intent);
}
}, delay, period);
} catch (Exception ex) {
ex.printStackTrace();
}
stopSelf();
}
}
}
MainActivity
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MyService.MY_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
final Intent intent = new Intent(MainActivity.this, MyService.class);
//Start our own service
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//registerReceiver(broadcastReceiver, intentFilter);
startService(intent);
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//unregisterReceiver(broadcastReceiver);
stopService(intent);
}
});
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
unregisterReceiver(broadcastReceiver);
super.onStop();
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int datapassed = intent.getIntExtra("DATAPASSED", 0);
String s = intent.getAction().toString();
String s1 = intent.getStringExtra("DATAPASSED");
textview.append(s1);
}
};
What I'm doing wrong is calling stopSelf() inside my Thread which is causing the service calling the onDestroy() method. I just removed that and added myTimer and myTask as local variables, then I could add myTimer.cancel() onDestroy and it worked.

SharedPreferences getSharedPreferences always returns previous value even it has been changed

I have a service that is started when the main activity starts. I call the Service using this code
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, CheckService.class));
finish();
}
The Service has the following code:
public class CheckService extends Service {
private static final String TAG = "CheckService";
WakeLock wakeLock;
public CheckService() {
// TODO Auto-generated constructor stub
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
// TODO Auto-generated method stub
Intent restartService = new Intent(getApplicationContext(),
this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
//Restart the service once it has been killed android
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 100, restartServicePI);
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
PowerManager pm = (PowerManager) getSystemService(this.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNotSleep");
Log.e("Checker", "Service Created");
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
check_pref();
}
}, 0, 5000);
}
#Override
#Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
sendBroadcast(new Intent("YouWillNeverKillMe"));
}
public void check_pref( ) {
Context con;
Log.e("check_pref", "Restarting");
try {
Process p = Runtime.getRuntime().exec("su");
DataOutputStream dos = new DataOutputStream(p.getOutputStream());
dos.writeBytes("chmod -R 0777 /data/data/com.my.project.app/\n");
dos.writeBytes("exit\n");
dos.flush();
dos.close();
p.waitFor();
p.destroy();
con = createPackageContext("com.my.project.app", 0);
SharedPreferences pref = con.getSharedPreferences("myprefs", 0);
String login_id = pref.getString("login", "");
System.out.println(login_id);
} catch (PackageManager.NameNotFoundException e)
{
Log.e("check_pref", e.toString());
}
catch (NullPointerException e){
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
Every 5 seconds in my service runs method check_pref(), which checks login in another app (com.my.project.app) and prints it in Logcat. But even login has been changed it returns same value as previously. Only if I restart app it returns actual value. My device(android 5.1.1) is rooted and I allowed permissions for my app. Whats wrong with my code? How to make it always return the actual value, which located in /data/data/com.my.project.app/myprefs.xml ?
PS. I found a solution. I changed
SharedPreferences pref = con.getSharedPreferences("myprefs", 0);
to
SharedPreferences pref = con.getSharedPreferences("myprefs", MODE_MULTI_PROCESS); and it works now.
I changed
SharedPreferences pref = con.getSharedPreferences("myprefs", 0);
to
SharedPreferences pref = con.getSharedPreferences("myprefs", MODE_MULTI_PROCESS);
and it works now.

call activity from service

It has been asked a few times before but the solution provided couldn't solve my problem. I am working on the app which has several classes: mainactivity, SMS, and MService. service has a timer. I am trying to call SMS to send a text message every time timer is over. Can please someone help me ....
Thanks for consideration...
public class MService extends Service {
private Handler HandleIt = new Handler();
private final int INTERVAL = 60 * 1000;
private Timer timer = new Timer();
boolean timeout = false;
public interface SmsService
{
void SmsServiceSenter();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
HandleIt.post(new Runnable(){
public void run(){
Toast.makeText(getApplicationContext(), TextonScreen(), Toast.LENGTH_SHORT).show();
// Intent smsintent = new Intent(getBaseContext(), SMS.class);
// startService(smsintent);
}
});
}
}
private String TextonScreen()
{
timeout = true;
return "it is running";
}
boolean isTimeout()
{
return timeout;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "Service is created", Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
// Display the Toast Message
Toast.makeText(this, "Start it", Toast.LENGTH_SHORT).show();
// Execute an action after period time
//comes from the TimeDisplayTimerTask class
timer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, INTERVAL);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
// Display the Toast Message
Toast.makeText(this, "Stop it", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
}
public class SMS extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
message();;
}
boolean issent = false;
String text = "I am here";
String num = "2085578209";
SmsManager smsManager = SmsManager.getDefault();
public void message()
{
// if(Timeout.isTimeout()) {
smsManager.sendTextMessage(num, null, text, null, null);
issent = true;
// }
}
boolean isSent()
{
return issent;
}
}
It is really simple.
After you create your Intent variable, before starting activity add a flag to it like below
Intent launch = new Intent(this, MyActivity.class);
launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(launch);
With this above code you can call activity from service

Android IntentService for Notifications

I'm trying to make a service, that is completely independent from the activity and running all the time in background to send the notification about incoming event. I have solved the problem of service killing along with activity by returning START_STICKY value in onStartCommand. It works well, but then I have problem with sending notifications. The problem is in the setSmallIcon method. When i pass there the reference to R.drawable.ic_launcher, I have got error, which says, that icon == 0. Is there any way to make it work properly?
Here is my NotificationService.java
public class NotificationService extends IntentService {
private static final int UPDATE_TIME = 60 * 1000;
private ArrayList<Group> groups;
public NotificationService() {
super("NotficationService");
// TODO Auto-generated constructor stub
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return START_STICKY;
}
private void showNotification(String name, int remindTime) {
Intent intent = new Intent();
intent.setClass(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification n = new Notification.Builder(this)
.setContentTitle(contentTitle)
.setContentText(contentText)
.setContentIntent(pIntent)
.setSmallIcon(android.R.drawable.ic_delete)
.setSound(sound)
.setAutoCancel(true)
.build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
}
#Override
protected void onHandleIntent(Intent intent) {
while(true) {
checkForNotification();
try {
Thread.sleep(UPDATE_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Try using:
.setSmallIcon(Resources.getSystem().getDrawable(android.R.drawable.ic_delete))
instead of
.setSmallIcon(android.R.drawable.ic_delete)

How to solve Multiple alarms in a single class

I want to execute two code blocks at pre-defined times. I am using AlarmManager for that purpose.
Two separte AlarmManagers and two separate pending intents. I have set 2 alarms to trigger (1st one triggered after 5 seconds, 2nd one after 19 seconds), when i press a button on screen. My problem is both alarms, and as a result both corresponding code blocks are simultaneously triggered at same time after 5 seconds. I changed Ids of both Pending Intents yet i am facing this problem.
Following is my main activity java class code:
public class PerseusAndroid extends Activity implements OnClickListener, OnItemClickListener {
PendingIntent pi,pi2;
AlarmManager amon,amoff;
BroadcastReceiver br,br2;
BluetoothSocket m_btSck;
public static final int idTab2FWD = Menu.FIRST + 1,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.PreseusAndroid);
setup();
setup2();
}
private void setup()
{
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
if (m_btSck != null )
try {
m_btSck.getOutputStream().write('1');
Toast.makeText(getBaseContext(), "Led is ON.. : )", Toast.LENGTH_LONG).show();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
registerReceiver(br, new IntentFilter("net.pocketmagic.perseus") );
final int _id2 = (int) System.currentTimeMillis();
pi = PendingIntent.getBroadcast( this,_id2 , new Intent ("net.pocketmagic.perseus"),PendingIntent.FLAG_CANCEL_CURRENT );
amon = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
}
private void setup2()
{
br2 = new BroadcastReceiver() {
#Override
public void onReceive(Context c1, Intent i1) {
if (m_btSck != null )
try {
m_btSck.getOutputStream().write('0');
Toast.makeText(getBaseContext(), "Led is Off.. : )", Toast.LENGTH_LONG).show();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
registerReceiver(br2, new IntentFilter("net.pocketmagic.perseus") );
final int _id = (int) System.currentTimeMillis();
pi2 = PendingIntent.getBroadcast( this, _id, new Intent("net.pocketmagic.perseus"),PendingIntent.FLAG_ONE_SHOT );
amoff = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
}
#Override
public void onClick(View v) {
int cmdId = v.getId();
if (cmdId == idTab2FWD)
{
amon.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() +5000, pi );
//amoff.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() +19000, pi2);
}
}
}
}
You are registering both intents/receivers with the same intent/filter. This means it will trigger the other receiver as well. Just make the Intent/IntentFilter specific for each action, i.e instead of "net.pocketmagic.perseus" use: "net.pocketmagic.perseus.ACTION_1" and "net.pocketmagic.perseus.ACTION_2".

Categories

Resources