I have a Service (Bound) which I am trying to start from my MainActivity.java. The below is my Main Activity code:
public class MainActivity extends AppCompatActivity {
Handler m_handler;
Runnable m_handlerTask ;
private static ServiceConnection sConnection;
static boolean serviceBound = false;
#Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, DataDownloaderService.class);
bindService(intent, sConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.NoActionBar);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
if (!Global.isMyServiceRunning(DataDownloaderService.class, this)) {
sConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
DataDownloaderService.LocalBinder binder = (DataDownloaderService.LocalBinder) service;
Global.dService = binder.getService();
serviceBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
serviceBound = false;
}
};
}
}
catch(Exception ex ){
String p="";
}
}
#Override
protected void onResume(){
super.onResume();
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
RefreshNowPlaying();
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
}
}
void RefreshNowPlaying(){
//Do something
}
}
The service code is as shown below:
public class DataDownloaderService extends Service {
private final IBinder dBinder = new LocalBinder();
public class LocalBinder extends Binder {
DataDownloaderService getService() {
// Return this instance of LocalService so clients can call public methods
return DataDownloaderService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return dBinder;
}
#Override
public void onCreate(){
}
#Override
public void onStart(Intent intent, int startid){
super.onStart(intent,startid);
Global.DataDownloaderServiceStatus = "STARTED";
}
#Override
public void onDestroy(){
Global.DataDownloaderServiceStatus = "STOPPED";
super.onDestroy();
}
}
I have also added the service to the AndroidManifest.xml under the Application element. However, I see that the service's onStart is never fired or the override onServiceConnected in the MainActivity is never called. I am new to Anrdoid development and Java. Can someone give me some pointers, please? I have noticed that the service's onCreate is getting hit, by putting breakpoints, but not onStart.
onStart() will be called only if the service was started via context.startService(), see here.
Related
I have codes in two classes
First class is ExampleBroadcastReceiver:
public class ExampleBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
boolean noConnectivity = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false
);
if (noConnectivity) {
Toast.makeText(context, "Disconnected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Connected", Toast.LENGTH_SHORT).show();
}
}
}
}
Second class is MainActivity:
public class MainActivity extends AppCompatActivity {
ExampleBroadcastReceiver exampleBroadcastReceiver = new ExampleBroadcastReceiver();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(exampleBroadcastReceiver, filter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(exampleBroadcastReceiver);
}
}
How can I make the two classes into one by passing the code from the ExampleBroadcastReceiver class to MainActivity? Is it possible? Please don't ask why. Thanks.
Use java interface to handle an event in MainActivity that occurs in ExampleBroadcastReceiver. This way you don't have to merge classes to share an event based data.
public class ExampleBroadcastReceiver extends BroadcastReceiver {
public interface ConnectivityMonitorCallback {
void onConnectivityChanged(boolean connectivity);
}
public ConnectivityMonitorCallback callback;
public ExampleBroadcastReceiver(#NonNull ConnectivityMonitorCallback eventCallback) {
callback = eventCallback;
}
#Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
boolean noConnectivity = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false
);
callback.onConnectivityChanged(noConnectivity);
}
}
}
Finally in the MainActivity you handle the event.
public class MainActivity extends AppCompatActivity {
ExampleBroadcastReceiver exampleBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Define event handling code here which occurs in ExampleBroadcastReceiver
exampleBroadcastReceiver = new ExampleBroadcastReceiver(new ExampleBroadcastReceiver.ConnectivityMonitorCallback {
#Override
void onConnectivityChanged(boolean connectivity) {
// Handle the event that occured in ExampleBroadcastReceiver
}
});
}
#Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(exampleBroadcastReceiver, filter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(exampleBroadcastReceiver);
}
}
I have a java background serviceA and serviceB. I have instantiated serviceA in onStart method in Mainactivity class . I need to start serviceB if the serviceA fails to start. I have written a callback method which gets called in MainActivity but when I tried to call serviceB it is not getting created.
I have written a callback method in MainActivity which gets called in serviceA but when I tried to call serviceB it is not getting created.
public class MainActivity extends Activity implements ServiceCallbacks{
private static final String TAG = "Main Activity";
private Context myContext = null;
Intent myTestService;
private MyTestService serviceA;
private boolean bound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myContext = this;
setContentView(R.layout.activity_main);
Log.d(TAG,"onCreate called.");
}
#Override
protected void onResume() {
super.onResume();
if(serviceA == null) {
serviceA = new Intent(this, MyTestService.class);
Log.d(TAG,"onResume called.");
Log.d(TAG,"myTestService instance created.");
}
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG,"onPause called.");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG,"OnDestory called");
}
#Override
protected void onStart() {
super.onStart();
// bind to Service
Intent intent = new Intent(this, MyTestService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
// Unbind from service
if (bound) {
myService.setCallbacks(null); // unregister
unbindService(serviceConnection);
bound = false;
}
}
/** Callbacks for service binding, passed to bindService() */
private ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
// cast the IBinder and get MyService instance
LocalBinder binder = (LocalBinder) service;
myService = binder.getService();
bound = true;
myService.setCallbacks(MainActivity.this); // register
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
bound = false;
}
};
#Override
public void callBackToActivity() {
unbindService(serviceConnection);
StartNewService();
}
private void StartNewService(){
Intent intent = new Intent(this, serviceB.class);
startService(intent);
}
}
I want to start serviceB if serviceA fails to start.
I am c# developer and new to java and need your help.
I am an absolute beginner working on my first android app. I am working on an audio stream app and i implemented the mediaPlayer inside a service. There is a play-pause button that toggles if bound or not. The issue i have is that when isPlaying, and i change the screen orientation, though the service continues, the activity is recreated which makes the play button appear rather than the pause button. I know for me to retain the pause button, i need to override two methods - onSaveInstanceState and onRestoreInstanceState but i dont know the right logic to use in order to retain mainActivity's state.
Pls help me because the examples i saw didnt solve my problem.
This is my main activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//.......
if(savedInstanceState != null) {
boolean isPlaying = savedInstanceState.getBoolean("isPlaying");
if(!isPlaying){
imageButton2.setImageResource(R.drawable.stop);
} else {
imageButton2.setImageResource(R.drawable.play);
}
}
#Override
protected void onStart() {
// bind to the radio service
Intent intent = new Intent(this, RadioService.class);
startService(intent);
bindService(intent, mConnection, BIND_AUTO_CREATE);
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStop() {
// unbind the radio
// service
if (boundToRadioService) {
unbindService(mConnection);
boundToRadioService = false;
}
super.onStop();
}
#Override
protected void onDestroy() {
radioService.hideNotification();
if (boundToRadioService) {
unbindService(mConnection);
boundToRadioService = false;
}
super.onDestroy();
}
public void setupMediaPlayer(View view) {
if (boundToRadioService) {
boundToRadioService = false;
imageButton2.setImageResource(R.drawable.stop);
radioService.play();
} else {
boundToRadioService = true;
imageButton2.setImageResource(R.drawable.play);
radioService.pause();
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("isPlaying", boundToRadioService);
super.onSaveInstanceState(outState);
}
}
This is my Service
// Binder given to clients
private final IBinder mBinder = new RadioBinder();
}
public void pause() {
audioManager.abandonAudioFocus(audioFocusChangeListener);
unregisterReceiver(audioBecomingNoisy);
mediaPlayer.pause();
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(this, "Oops! Error Occured, Check your network connection", Toast.LENGTH_SHORT).show();
mediaPlayer.reset();
return false;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
#Override
public void onPrepared(MediaPlayer mp) {
{
mp.start();
}
}
public class RadioBinder extends Binder {
RadioService getService() {
// Return this instance of RadioBinder so clients can call public methods
return RadioService.this;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
return mBinder;
}
public void play() {
registerReceiver(audioBecomingNoisy, noisyIntentFilter);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.reset();
showNotification();
Toast.makeText(this, "loading... please wait", Toast.LENGTH_LONG).show();
Log.i(TAG, "onCreate, Thread name " + Thread.currentThread().getName());
}
class PlayerTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(stream);
mediaPlayer.prepareAsync();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
}
try this,
public class MainActivity extends AppCompatActivity {
private boolean boundToRadioService = false;
private ImageButton imageButton2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageButton2 = (ImageButton) findViewById(R.id.my_button);
if(savedInstanceState != null){
boundToRadioService = savedInstanceState.getBoolean("isPlaying", false);
if(boundToRadioService){
imageButton2.setImageResource(R.drawable.stop);
} else {
imageButton2.setImageResource(R.drawable.play);
}
} else {
// bind to the radio service
Intent intent = new Intent(this, RadioService.class);
startService(intent);
bindService(intent, mConnection, BIND_AUTO_CREATE);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean("isPlaying", boundToRadioService);
super.onSaveInstanceState(outState);
}
public void setupMediaPlayer(View view){
if (boundToRadioService) {
boundToRadioService = false;
imageButton2.setImageResource(R.drawable.play);
radioService.pause();
} else {
boundToRadioService = true;
imageButton2.setImageResource(R.drawable.stop);
radioService.play();
}
}
}
and add android:src="#drawable/play" to the imagebutton in your xml file.
I'm stuck with these problem several day now, I don't know what is my problem is. I really need some help now, hopping can help me out here. These is my code.
public class MainActivity extends AppCompatActivity implements LocationListener {
TextView text;
String trip;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.id_trip);
scheduleAlarm();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras){
}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
public void onLocationChanged(Location location) {
new MyAsyncTask ().execute();
}
public class MyAsyncTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... arg0) {
trip = "Hai";
return null;
}
#Override
protected void onPostExecute(String strFromDoInBg) {
text.setText(trip);
}
}
public void scheduleAlarm() {
Intent intent = new Intent(getApplicationContext(), Track.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, Track.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), 60 * 1000, pIntent);
}
}
Services class
public class Services extends Service {
public LocationManager locationManager;
public MainActivity listener;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MainActivity();
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, listener, null);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}}
Track class
public class Track extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, Services.class);
context.startService(i);
}}
And the error are :
java.lang.NullPointerException: Attempt to invoke virtual method
'android.view.View android.view.Window.findViewById(int)' on a null
object reference
Thanks
Here is your error :
TextView text = (TextView) main.findViewById(R.id.id_trip);
text.setText(string);
you cannot get TextView object like this from Service. Either create TextView object as static or use BroadcastReceiver.
You are returning null value from doInBackground, that is the reason you are getting NullPointerException.
Change MyAsyncTask code with the following code.
public class MyAsyncTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
if(text==null){
text = MainActivity.this.findViewById(R.id.id_trip);
}
}
#Override
protected String doInBackground(String... arg0) {
trip = "Hai";
return trip;
}
#Override
protected void onPostExecute(String strFromDoInBg) {
text.setText(strFromDoInBg);
}
}
Remove below 2 lines from setText(String str) methood.
MainActivity main = new MainActivity();
TextView text = (TextView) main.findViewById(R.id.id_trip);
Hope this will help you.
The following code keeps throwing null pointer exception...
public class MainActivity extends Activity implements OnClickListener{
Button but;
Button but2;
LocalBinder binder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but = (Button) findViewById(R.id.button1);
but.setOnClickListener(this);
but = (Button) findViewById(R.id.button2);
}
ServiceConnection connection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
Log.d("D1", "connecting");
binder = (LocalBinder) arg1;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
Log.d("D1", "disconnecting");
}
};
public static class ServiceTest extends Service{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return new LocalBinder();
}
public class LocalBinder extends Binder{
public void toast(){
Toast.makeText(getApplicationContext(), "hope this works", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onClick(View arg0) {
Intent i = new Intent(getApplicationContext(), ServiceTest.LocalBinder.class);
bindService(i, connection, Context.BIND_AUTO_CREATE);
Toast.makeText(getApplicationContext(), "bind completed", Toast.LENGTH_LONG).show();
}
public void binderMethod(View v){
binder.toast();
}
}
I guess that the reason is that onServiceConnected does not execute, which causes binder to stay null. (The but button binds the service to the activity while but2 executes binder.toast(); - the exception is thrown when but2 is pressed)
Basicly the question is : why doesnt onServiceConnected execute ?
I think, that intent should lead to service, not binder in service: Intent i = new Intent(getApplicationContext(), ServiceTest.class);