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)
Related
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.
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.
I am trying to make an app in Android Studio which sends a push notification every 15 seconds, using a service. The problem is that the mobiles I tested the code on acted really slowly when a notification pops up. When I use an emulator, it works fine. Does anyone know what makes this code really slow?
Thanks in advance!
MainActivity.java
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i = new Intent(this, MyService.class);
startService(i);
}
}
MyService.java
public class MyService extends Service {
public MyService() {
}
public void showPushNotification (){
NotificationCompat.Builder pushbericht;
final int IDnummer = 123;
pushbericht = new NotificationCompat.Builder(this);
pushbericht.setAutoCancel(true);
pushbericht.setSmallIcon(R.drawable.icoontje);
pushbericht.setContentTitle("Poll App");
pushbericht.setContentText("Hoi");
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
pushbericht.setContentIntent(pendingIntent);
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(IDnummer, pushbericht.build());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Runnable r = new Runnable() {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
long futureTime = System.currentTimeMillis() + 15000;
while (System.currentTimeMillis() < futureTime) {
synchronized (this) {
try {
wait(futureTime - System.currentTimeMillis());
showPushNotification();
} catch (InterruptedException e) {
}
}
}
}
}
};
Thread thread = new Thread(r);
thread.start();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I want to reject call after 1 sec and make notification
But when i make notification then it give syntax error in getSystemService
What can i do
Here is my code for rejecting call and make notification
private String incomingnumber;
#Override
public void onReceive(Context context, Intent intent) {
String s[] = { "045193117", "800000000" };
Bundle b = intent.getExtras();
incomingnumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
try {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
final com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m
.invoke(tm);
for (int i = 0; i < s.length; i++) {
if (s[i].equals(incomingnumber)) {
Runnable mMyRunnable2 = new Runnable() {
#Override
public void run() {
try {
telephonyService.endCall();
NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notify= new Notification(android.R.drawable.ic_lock_idle_low_battery, "Battery Notification",SystemClock.currentThreadTimeMillis());
CharSequence title="Battery Level ";
CharSequence details= "Continue with what you were doing";
Intent intent= new Intent(context, MainActivity.class);
PendingIntent pi= PendingIntent.getSctivity(con, 0, intent, 0);
notify.setLatestEventInfo(con, title, details, pi);
nm.notify(0, notify);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Handler myHandler = new Handler();
myHandler.postDelayed(mMyRunnable2, 1000);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
replace
NotificationManager nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
with
NotificationManager nm= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
and make the context parameter as final to access it inner class (here Runnable).
public void onReceive(final Context context,Intent intent) {
//
}
when you say getSystemService() in Runnable, it will look for that method in Runnable implementation class which is actually not.
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).