简体   繁体   中英

Start Activity and Service from broadcastreceiver

First of all sorry for my English. So i am making a program which will alert the user when he/she need to get in his/her medicines. My base idea:

1 The AlarmManager send me the signal
2 i catch that signal with my broadcast receiver,
3 and that the broadcast receiver start my Service and my Activity.

The service count down from 10 minutes and every minute will check other parameters from database and the Activity will make sound and vibrate. Because there will be more medicine i made a list with buttons. And because the service and activity use the same cursor the service has the connection with the database. So when my Activity start, it need to get the cursor from the Service (for the cursoradapter). And if the service or the activity changed the cursor i need to refresh that cursor, so i make a requery in the Service.

The only problem is that although my bindService give me true result, my onServiceConnected method doesn't run down, so i get a nullpointer exception, when i try to call the public service method (for cursor) from my activity. I tried to start my Activity from the service after onStartCommand but the result is also a nullpointer.

What is the best way to achive my task? Should i delete my service and make another thread(AsyncTask) from activity which will do the service job?

Ok, i tried to grab out the important part.

package elte.thesis.broadcastreceivers;

import elte.thesis.alarmsmanager.AlarmActivity;
import elte.thesis.alarmsmanager.WakeLockManager;
import elte.thesis.database.Utility;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/*
 * This BroadcastReceiver will receive the ALARM from the AlarmManager
 * and it will 
 * 1, start the Service and 
 * 2, show the AlarmActivity 
 */
public class DosageAlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Log.v("Szakbarbar",
            "AlarmManager send me the next " + "alarm time: " +    intent.getStringExtra("AlarmTime"));

    /*
     * It seems that the alarmmanager release the wakelock as soon as our
     * onReceive method return, so we need to make our own wakelock
     */
    WakeLockManager.acquireCpuWakeLock(context);

    /*
     * Start the service and give him the time what we got from alarm manager
     */
    Log.v("Szakbarbar", "Elinditjuk a servicunket");
    Intent serviceIntent = new Intent(Utility.ALARM_SERVICE);
    serviceIntent.putExtra("AlarmTime", intent.getStringExtra("AlarmTime"));
    context.startService(serviceIntent);

    /*
     * Start the AlarmActivity where the user can sign that he got in the
     * pills
     */
    Log.v("Szakbarbar", "Elinditjuk az activitinket");
    Intent alarmActivity = new Intent(context, AlarmActivity.class);
    alarmActivity.putExtra("AlarmTime", intent.getStringExtra("AlarmTime"));
    alarmActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
    context.startActivity(alarmActivity);

}

 }

In mine AlarmActivity

 AlarmService mService;
 ...
@Override
public void onStart() {
    super.onStart();

    Log.v("Szakbarbar", "Bind to the Service");
    Intent intent = new Intent(Utility.ALARM_SERVICE);
    boolean connection = bindService(intent, mConnection,      Context.BIND_AUTO_CREATE);
    Log.v("Szakbarbar", "Binded to the Service : " +      ((connection==true)?"kapcsolt":"nemkapcsolt"));
}

@Override
public void onResume() {
    super.onResume();

    Log.v("Szakbarbar", "Need the cursor from the Service");
    updateDosageAdapter();

    //Make one private register to now when the AlarmService made change on the cursor
    registerReceiver(mReceiver, new IntentFilter(Utility.ALARMS_CHANGED));

    if (!mute) {
        if (volume < 1)
            incAlarmVolume();
        mVibrator.vibrate(sVibratePattern, 0);
        player.start();
    }
}

/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className, IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        Log.v("Szakbarbar", "mService itt még nulla");
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
        Log.v("Szakbarbar", "mService itt már nem nulla");          
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};
public void updateDosageAdapter() {
    Log.v("Szakbarbar", "1");
    alarmsCursor = mService.refreshCursor();
    Log.v("Szakbarbar", "2");       
    startManagingCursor(alarmsCursor);
    Log.v("Szakbarbar", "3");       
    if (alarmsAdapter == null) {
        Log.v("Szakbarbar", "4");           
        alarmsAdapter = new AlarmsAdapter(this, alarmsCursor);
        alarmsList = (ListView) findViewById(R.id.dosage_alarm_list);
        alarmsList.setAdapter(alarmsAdapter);
        alarmsList.setVerticalScrollBarEnabled(true);
        alarmsList.setScrollContainer(false);
        alarmsList.setOnCreateContextMenuListener(this);
    } else {
        Log.v("Where is nullpointerexception", "5");            
        alarmsAdapter.changeCursor(alarmsCursor);
    }
}

And in my Service

 private final IBinder mBinder = new LocalBinder();
 ...
// Return this instance of AlarmService so clients can call public methods
public class LocalBinder extends Binder {
    AlarmService getService() {
        return AlarmService.this;
    }
}

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

//Refresh the cursor
public Cursor refreshCursor() {

    Log.v("Szakbarbar", "ResreshCrusor : " + alarmTime);

    alarmCursor = Utility.selectDosageAlarms(alarmTime);        
    return alarmCursor;
}

Short description of my problem I think you don't know what is my problem yet. I am not good at English, sorry for the trouble. Although i called bindService() on the onStart() method of the AlarmActivity, when i call (also from AlarmActivity) updateDosageAdapter() which use the refreshCursor() method from the Service i got a null pointer exception, because the onServiceConnected() method didn't run down yet and my mService varieble which should hold the reference of my Service is null.

I managed to find a solution, described in this post

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