简体   繁体   中英

Android services not running while exit application

I'm having a problem to run a service, actually the service is not running when I exit the my application wether exit from application itself or click 'exit application' button from task manager. If the app is not close, the services is running and user will be notify. The service actually will notify user latest comment. below is my service class.

package com.android.my.hotnews;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.Cursor;

public class CommentNotificationService extends Service{

    private Notification notifyMe;
    private NotificationManager notifyManager;
    private PendingIntent pIntent;
    private Intent intent;
    private static String DBPATH="data/data/com.android.my.hotnews/databases/";
    private static String DBNAME="mydb.db"; 
    private String path = DBPATH+DBNAME;
    private Timer timer = new Timer();
    private static final long UPDATE_INTERVAL = 5000;
    String title = null;
    String content = null;
    String date = null;
    Calendar cal = null;

    public void onCreate(){
        super.onCreate();
        notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notifyMe = new Notification(R.drawable.comment_icon, "New Comment", System.currentTimeMillis());

        intent = new Intent(android.content.Intent.ACTION_VIEW, null, getApplicationContext(), CommentViewer.class);
        pIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
        inComingComment();
    }

    public void inComingComment() throws SQLiteException{
        SQLiteDatabase db;
        db=SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        Cursor rs = db.rawQuery("SELECT * FROM Comment_Log ORDER BY Comment_Date_Time ASC", null);

        if(rs.getCount()>0){
            rs.moveToFirst();
            try {
                String[] dmy = rs.getString(1).split("/");
                String[] hm = rs.getString(2).split(":");
                cal = Calendar.getInstance();
                cal.set(Calendar.DATE, Integer.parseInt(dmy[0]));
                cal.set(Calendar.MONTH, Integer.parseInt(dmy[1])-1);
                cal.set(Calendar.YEAR, Integer.parseInt(dmy[2]));
                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hm[0]));
                cal.set(Calendar.MINUTE, Integer.parseInt(hm[1]));
                title="new comment";
                content=rs.getString(3);                
                db.close();
            } catch (Exception e) {             
                log.d("error ocurred",e.getClass().getName());
                db.close();
            }           
        }       
        //timer.scheduleAtFixedRate(new TimerTask(){
        timer.schedule(new TimerTask(){
            @Override
            public void run() {
                notifyMe.setLatestEventInfo(getApplicationContext(), title , content, pIntent);             
                notifyManager.notify(0, notifyMe);              
            }           
        }, cal.getTime(), UPDATE_INTERVAL);

    }

    public void onDestroy(){

    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

below is my manifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.android.my.hotnews"
   android:versionCode="1"
   android:versionName="1.0">
<supports-screens
     android:largeScreens="true"
     android:normalScreens="true"
     android:smallScreens="true"
     android:resizeable="true"
     android:anyDensity="true"
 />
<application android:icon="@drawable/apps_icon" android:label="@string/app_name" android:debuggable="true">
   <activity android:name=".ContentLoader"
       android:configChanges="orientation|keyboardHidden">
     <intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
   </activity> 
   <activity android:name=".CommentViewer" android:configChanges="orientation|keyboardHidden"/>  
   <service android:name=".CommentNotificationService"/>
</application>
</manifest>

Implement onStartCommand in your service and ensure that you return Service.START_STICKY; from it.

the service is not running when I exit the my application wether exit from application itself or click 'exit application' button from task manager

There is no "exit from application itself" in Android, so it is unclear what you mean by this.

There is no "task manager" in Android, let alone one with an "exit application" button. If you mean that you are using a task killer or via the Settings application, then your entire application is stopped, including any services that you may have had running.

Also, it is highly unlikely that a "comment viewer" needs android:configChanges="orientation|keyboardHidden" , as few activities should use this.

This morning I found ugly solution to my problem by using Alarmmanager, so eventhought my application is not running the user still be notify. Here is my code:

package com.android.my.hotnews;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.Cursor;

public class CommentNotificationService extends Service{

    private Notification notifyMe;
    private NotificationManager notifyManager;
    private PendingIntent pIntent;
    private Intent intent;
    private static String DBPATH="data/data/com.android.my.hotnews/databases/";
    private static String DBNAME="mydb.db"; 
    private String path = DBPATH+DBNAME;
    private Timer timer = new Timer();
    private static final long UPDATE_INTERVAL = 5000;
    String title = null;
    String content = null;
    String date = null;
    Calendar cal = null;

    public void onCreate(){
        super.onCreate();
        notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notifyMe = new Notification(R.drawable.comment_icon, "New Comment", System.currentTimeMillis());

        intent = new Intent(android.content.Intent.ACTION_VIEW, null, getApplicationContext(), CommentViewer.class);
        pIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
        inComingComment();
    }

    public void inComingComment() throws SQLiteException{
        SQLiteDatabase db;
        db=SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        Cursor rs = db.rawQuery("SELECT * FROM Comment_Log ORDER BY Comment_Date_Time ASC", null);

        if(rs.getCount()>0){
            rs.moveToFirst();
            try {
                String[] dmy = rs.getString(1).split("/");
                String[] hm = rs.getString(2).split(":");
                cal = Calendar.getInstance();
                cal.set(Calendar.DATE, Integer.parseInt(dmy[0]));
                cal.set(Calendar.MONTH, Integer.parseInt(dmy[1])-1);
                cal.set(Calendar.YEAR, Integer.parseInt(dmy[2]));
                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hm[0]));
                cal.set(Calendar.MINUTE, Integer.parseInt(hm[1]));
                title="new comment";
                content=rs.getString(3);                
                db.close();
            } catch (Exception e) {             
                log.d("error ocurred",e.getClass().getName());
                db.close();
            }           
        }       
        timer.schedule(new TimerTask(){
            @Override
            public void run() {
//here i set time for AlarmManager
                Intent intent = new android.content.Intent(getApplicationContext(), CommentReceiver.class);
                intent.putExtra("Title", title);
                intent.putExtra("Content", content);
                PendingIntent pIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
                am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pIntent);
            }           
        }, 0, UPDATE_INTERVAL);

    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

below is my CommentReceiver class

package com.android.my.hotnews;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.app.PendingIntent;
import android.app.Notification;
import android.app.NotificationManager;

public class CommentReceiver extends BroadcastReceiver{ 

    private NotificationManager nm;
    private Notification notify;

    @Override
    public void onReceive(Context context, Intent intent) {
        String title = intent.getExtras().get("Title").toString();
        String content = intent.getExtras().get("Content").toString();
        Intent notifyIntent = new Intent(context, CommentViewer.class);
        PendingIntent pending = PendingIntent.getActivity(context, 0, notifyIntent, 0);

        nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notify = new Notification(R.drawable.app_icon, "Incoming comment", System.currentTimeMillis());
        notify.setLatestEventInfo(context, title, content, pending);
        nm.notify(1, notify);
    }
}

Btw I'm beginner in android development so I'm sorry if my question is unclear. I don't think this is the best way as service might be crashed on low memory available. So should I directly using AlarmManager instead of calling the AlarmManager in the service, in case of no interaction between user and the apps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM