I am creating a game app and I have a few activities for the different screens. I have a service I am using to play music through out the activities. A really simple service, I have the title screen with image buttons to turn it on and off. Now I am getting a unexpected close and this error message from eclipse:
[2011-05-19 19:50:04 - ddms]null
java.lang.NullPointerException
at com.android.ddmlib.Client.sendAndConsume(Client.java:571)
at com.android.ddmlib.HandleHello.sendHELO(HandleHello.java:142)
at com.android.ddmlib.HandleHello.sendHelloCommands(HandleHello.java:65)
at com.android.ddmlib.Client.getJdwpPacket(Client.java:670)
at com.android.ddmlib.MonitorThread.processClientActivity(MonitorThread.java:317)
at com.android.ddmlib.MonitorThread.run(MonitorThread.java:263)
EDIT: Code For Service
public class BGMusic extends Service {
MediaPlayer player;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.still_wana);
}
public void onStart(Intent intent, int startId) {
super.onCreate();
player.start();
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
}
}
EDIT: Console Android Msg
Starting activity com.android.hitmanassault.HitmanTitle on device emulator-5554
ActivityManager: DDM dispatch reg wait timeout
ActivityManager: Can't dispatch DDM chunk 52454151: no handler defined
ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.android.hitmanassault/.HitmanTitle }
java.lang.NullPointerException
at com.android.ddmlib.Client.sendAndConsume(Client.java:571)
You have a null pointer problem at line 571 of Client.java.
Probably caused by passing a parameter that can't be null as null. Maybe this for example:
R.raw.still_wana
You are calling the wrong super method in onStart():
public void onStart(Intent intent, int startId) {
super.onCreate();
It should be:
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Related
I have a start activity which is using services to play a background sound and after 5 seconds another activity is loaded.
The problem is in the second activity the sound doesn't load or service doesn't work... i'm not sure what is happening.
Sound works in the first activity when the app start.
here is the first activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//remove window title and make it fullscreen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//bind activity
setContentView(R.layout.start_activity);
ButterKnife.bind(this);
Intent intent = new Intent(StartActivity.this, SoundService.class);
intent.putExtra("filename", "audiostart");
//start service and start music
startService(intent);
int TIME_OUT = 5000;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(StartActivity.this, AvatarsActivity.class);
startActivity(i);
finish();
}
}, TIME_OUT);
Log.d(TAG, "APP Started!");
}
#Override
protected void onDestroy() {
//stop service and stop music
stopService(new Intent(StartActivity.this, SoundService.class));
super.onDestroy();
}
and the second activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.avatars_activity);
ButterKnife.bind(this);
Intent intent = new Intent(AvatarsActivity.this, SoundService.class);
intent.putExtra("filename", "audioavatars");
//start service and start music
startService(intent);
}
#Override
protected void onDestroy() {
//stop service and stop music
stopService(new Intent(AvatarsActivity.this, SoundService.class));
super.onDestroy();
}
here is the service:
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
player = MediaPlayer.create(this, R.raw.audio);
player.setLooping(false);
}
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null){
String mFilename = intent.getStringExtra("filename");
Toast toast = Toast.makeText(getApplicationContext(), "Filename: " + mFilename, Toast.LENGTH_SHORT);
toast.show();
}
player.start();
return Service.START_NOT_STICKY;
}
public void onDestroy() {
player.stop();
player.release();
stopSelf();
super.onDestroy();
}
I want a background sound when the second activity loads after 5 seconds passed in first activity.
And a second problem is that i want to pass a variable in onCreate method in service with what sound to play depending on the activity. (This task i think i can do it but doesn't hurt to ask opinions how to do it)
Your code seems fine. But have you registered your service in your manifest file? Please check your manifest. Your service is not registered can be possible cause.
You are starting second activity after 5sec delay and immediately, after you queue start intent, you call finish() on first activity which will trigger onDestroy callback of the same activity. In onDestroy() of that 1st activity you implemented stop service, which causes service to stop.
Remove that implementation of onDestroy() in both activities and provide to user a way to stop service explicitly (clicking on a button or whatever) instead of doing it in a activity lifecycle callback.
i'm trying to make a very simple service that plays an audio file by putting a button that its onClick() -> starts the service which in turn plays the sound.
but when i destroy the activity the song stops ( i can't tell Service state)[that i put a toast in onDestroy method in Service class , and it didn't come out.]
Any One Can HELP ?!!
AndroidManifest
<service android:name=".ExampleService"
android:enabled="true"
android:exported="true"
></service>
ExampleService.java
public class ExampleService extends Service {
MediaPlayer mpService;
private final static String TAG="ExampleService";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mpService.start();
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
mpService=MediaPlayer.create(this,R.raw.lwyashko);
Toast.makeText(this,"*** STARTED *** ",Toast.LENGTH_SHORT).show();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public void onDestroy() {
Log.d(TAG,"onDestroy was Called ");
Toast.makeText(this,"Service Destroyed",Toast.LENGTH_SHORT).show();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
MainActivity.java
playService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
i=new Intent(getApplication(),ExampleService.class);
startService(i);
}
});
As of API 26, only foreground services will usually be allowed to run without an Activity still active. You make a service a foreground one by calling startForeground() within the service. You will need to create and provide a notification in the call. Here's the relevant documentation page.
Normally, after the service is started by startService, the service will not be destroyed after the activity is closed. However, if the user manually cleans up the task, the entire APP process will be closed and the Service will stop.
I am trying to stop a service from my BroadCastReceiver when the charger is disconnected but when I run my code I get IntentReceiverLeaked in LogCat.
I am registering my receiver from a Service MyAlarmServiceClass.
public class MyAlarmServiceClass extends Service
{
#Nullable
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
listener=new StopListener();
registerReceiver(listener,new IntentFilter(Intent.ACTION_POWER_DISCONNECTED));
return START_STICKY;
}
#Override
public void onDestroy()
{
if(listener!=null)
{
this.unregisterReceiver(listener);
}
super.onDestroy();
}
}
Here is my BroadcastReceiver
public class StopListener extends BroadcastReceiver
{
SharedPreferences Stop_SharedPreferences;
boolean stop;
NotificationManager manager;
#Override
public void onReceive(Context context, Intent intent)
{
Stop_SharedPreferences=context.getSharedPreferences("stopService", Context.MODE_PRIVATE);
stop= Stop_SharedPreferences.getBoolean("stopServices",true);
if(stop)
{
context.stopService(new Intent(context, MyAlarmServiceClass.class));
}
}
}
Here is the logcat report
android.app.IntentReceiverLeaked: Service www.androidghost.com.batteryalarm.MyAlarmServiceClass has leaked IntentReceiver www.androidghost.com.batteryalarm.StopListener#d029e6f that was originally registered here. Are you missing a call to unregisterReceiver()?
at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:1167)
at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:950)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1339)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1319)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1313)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:596)
at www.androidghost.com.batteryalarm.MyAlarmServiceClass.onStartCommand(MyAlarmServiceClass.java:64)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3375)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1621)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6221)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
Your onStartCommand was called multiple times (and your receiver was registered multiple times). Try to register your receiver in onCreate of your service
I created sticky background service, that should be started on boot:
public class AutostartReceiver extends BroadcastReceiver
{
public AutostartReceiver()
{
}
#Override
public void onReceive(Context context, Intent intent)
{
context.startService(new Intent(context, MyService.class));
}
}
My service is intended to do some work in background, it's implemented by creating thread for this. Also there is Messenger class used for sending work status to my main activity:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i(TAG, "Service onStartCommand " + startId);
final int currentId = startId;
Messenger callback = null;
if(intent!=null)
{
callback = intent.getParcelableExtra("messenger");
}
final Messenger finalCallback = callback;
Runnable r = new Runnable()
{
public void run()
{
... do something, then stop
stopSelf();
}
};
if(t == null)
{
t = new Thread(r);
t.start();
}
return Service.START_STICKY;
}
Main activity receives messages sent from background thread running inside my service (some commands, that service is sending periodically:
Handler mHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case 0:
Toast.makeText(MainActivity.this,"Service runing", Toast.LENGTH_LONG).show();
break;
}
}
};
This works only if I start my service from activity, with activity's context. Obviously, if service is started on boot, or my app was closed (removed from last app list) and opened again, my activity is unable to get any messages from service any more.
If I invoke start service while service is already running, it will simply run OnStartCommand again, so either new thread will be created (I don't want it) or I need to destroy running thread and run thread again.
Is there any way to get my activity receiving messages from service, without actually touching already running thread inside it? I know about bound services, but it's not clear for me how to use them in my specific case.
As Alternate way You can use LocalBroadcastManager to send Data from Service to Activity.
Broadcast Your message from Service:
private void broadcastMessage(Context context){
Intent intent = new Intent("UI_UPDATE_BROADCAST");
intent.putExtra("MESSAGE", "MyMessage");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
Register Broadcast Receiver in your activity to receive messages:
#Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(mContext).registerReceiver(mMessageReceiver, new IntentFilter("UI_UPDATE_BROADCAST"));
}
#Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mMessageReceiver);
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Do Something With Received Data
String msg = intent.getStringExtra("MESSAGE");
}
};
I would use a broadcast receiver for Service-to-Activity communication.
Code:
public class MyActivity extends Activity {
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Toast here
}
#Override
protected void onCreate(Bundle savedInstanceState) {
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter("message-name"));
}
#Override
public void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
}
Then in your service you would broadcast the message like this:
Intent intent = new Intent("message-name");
intent.putExtra("data", 1);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
I want to listen the power key event in the service.
How can in do that ?
Currently I am working with an app, where I need to listen the power button for some events, from a service which is running in a background, even when the app is killed or stopped.
Somehow I can manage to get it.
But when I kill/stop the app, the service is getting stopped.
How can i overcome this ?
Currently the code i am using this :
Service Class:
public class SampleService extends Service
{
SettingContentObserver mSettingsContentObserver;
AudioManager mAudioManager;
private ComponentName mRemoteControlResponder;
private Intent intent;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("StartServiceAtBoot", "StartAtBootService -- onStartCommand()");
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Toast.makeText(getApplicationContext(), "On", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Off", Toast.LENGTH_SHORT).show();
}
}
public void onCreate()
{
mSettingsContentObserver = new SettingContentObserver(this,new Handler());
getApplicationContext().getContentResolver().registerContentObserver
(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver );
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mRemoteControlResponder = new ComponentName(getPackageName(),
StartAtBootServiceReceiver.class.getName());
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new StartAtBootServiceReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onDestroy()
{
getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);
}
}
BroadcastReceiver Class:
public class StartAtBootServiceReceiver extends BroadcastReceiver
{
static boolean wasScreenOn;
private boolean screenOff;
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
wasScreenOn = false;
Toast.makeText(context, "Power Off", Toast.LENGTH_SHORT).show();
}
else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
wasScreenOn = true;
}
Intent i = new Intent(context, SampleService.class);
i.putExtra("screen_state", screenOff);
i.setAction("com.example.antitheft.SampleService");
context.startService(i);
//
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i1 = new Intent();
i1.setAction("com.example.sampleonkeylistener.MainActivity");
context.startService(i1);
}
}
}
given above is the sample code and i have created AndroidManifest.xml files also with user's permission but i cannot get the app continue service if it is killed or stopped.
Thanks in Advance.
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, SampleService.class));
}
This is one way to ensure that service will never stop even user want to destroy it.
This is one Just ONE of ways to achieve what you are trying to achieve.
Secondly, you can try and run service in "foreground" by using startForeground().
Also, make sure that in you return "START_STICKY" (which you are doing in the sample code that you shared and I trust that you are also doing in App's code too :) ) in Services's onStartCommand().
This will ensure that If this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service.
And you may find some additional pointers/hints to make sure your service is not stopped at below link.
How can we prevent a Service from being killed by OS?
Just pick and choose the approach that best suits YOUR Need/implementation.