Service (android) can't start - android

I am a really junior android developer and do some practices on service right now. But I get some problems when doing this practice.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWidget();
registerListener();
}
public void getWidget()
{
startService = (Button) findViewById(R.id.startService);
shutdownService = (Button) findViewById(R.id.shutdownService);
}
public void registerListener()
{
ButtonListener bl = new ButtonListener();
startService.setOnClickListener(bl);
shutdownService.setOnClickListener(bl);
}
class ButtonListener implements View.OnClickListener
{
#Override
public void onClick(View v) {
Intent intent = null;
switch(v.getId())
{
case R.id.startService:
intent = new Intent(MainActivity.this,CountService.class);
startService(intent);
Log.v(TAG,"start service");
break;
case R.id.shutdownService:
intent = new Intent(MainActivity.this,CountService.class);
stopService(intent);
Log.v(TAG,"stop service");
break;
public class CountService extends Service{
boolean threadDisable ;
int count;
public IBinder onBind(Intent intent){
return null;
}
public void onCreate(){
super.onCreate();
/**New thread, count increased by 1 every 1s*/
new Thread(new Runnable(){
public void run(){
while(!threadDisable){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
}
count++;
Log.v("CountService","Count is"+count);
}
}
}).start();
}
public void onDestroy(){
super.onDestroy();
/**service ends*/
this.threadDisable = true;
}
public int getConunt(){
return count;
}
class ServiceBinder extends Binder{
public CountService getService(){
return CountService.this;
}
}
When I click the button, the service doesn't run. Who can help me with that? Thank you.
Thanks for Perroloco's help. I forgot to add service permission in mainfest files.
<service android:name=".CountService"></service>

First of all, you don't need two instances of ButtonListener. This should be enough:
public void registerListener()
{
ButtonListener bl = new ButtonListener();
startService.setOnClickListener(bl);
shutdownService.setOnClickListener(bl);
}
Also, the intent you use is equal in both cases, so:
class ButtonListener implements View.OnClickListener
{
#Override
public void onClick(View v) {
intent = new Intent(MainActivity.this,CountService.class);
switch(v.getId())
{
case R.id.startService:
startService(intent);
Log.v(TAG,"start service");
break;
case R.id.shutdownService:
stopService(intent);
Log.v(TAG,"stop service");
break;
...
Now, I think your code is right, at least for starting the service. You should look at your service's code. I would start the thread in the onStartCommand method, and not in onCreate.
Also, did you declare your service in the manifest?

Related

why public variables change in Binding Service after run App?

I use bind service in Android .I start Service and stop Service with button and it work correctly.The story: I press start service button so Service start then,I increase x with showint button and x increase well, then I close App without stopping service then run App again , but public x turn to zero and initial again.I need service without re-initial public variable.How can i do that? How can bind .
public class MainActivity extends AppCompatActivity {
BoundService mBoundService;
boolean mServiceBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView timestampText = (TextView) findViewById(R.id.timestamp_text);
Button shownum = (Button) findViewById(R.id.shownum);
Button stopService= (Button) findViewById(R.id.stop_service);
Button start = (Button) findViewById(R.id.start);
shownum.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (mServiceBound) {
timestampText.setText(mBoundService.shownum());
}
}
});
stopService.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (mServiceBound) {
unbindService(mServiceConnection);
mServiceBound = false;
}
Intent intent = new Intent(MainActivity.this,
BoundService.class);
stopService(intent);
}
});
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, BoundService.class);
startService(intent);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
});
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
BoundService.MyBinder myBinder = (BoundService.MyBinder) service;
mBoundService = myBinder.getService();
mServiceBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
mServiceBound = false;
}
};
}
and BoundService class:
public class BoundService extends Service {
private IBinder mBinder = new MyBinder();
public int x;
#Override
public void onCreate() {
// super.onCreate();
Toast.makeText(this,"onCreate",Toast.LENGTH_SHORT).show();
}
#Override
public IBinder onBind(Intent intent) {
Toast.makeText(this,"onBind",Toast.LENGTH_SHORT).show();
return mBinder;
}
#Override
public void onRebind(Intent intent) {
Toast.makeText(this,"onRebind",Toast.LENGTH_SHORT).show();
super.onRebind(intent);
}
#Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this,"UUUUnbind",Toast.LENGTH_SHORT).show();
return true;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"onDestroy",Toast.LENGTH_SHORT).show();
}
public String shownum()
{
x++;
return String.valueOf(x);
}
public class MyBinder extends Binder {
BoundService getService() {
return BoundService.this;
}
}
}
Starting from Android 8 (Oreo) all Services that should stay alive when the App is closed should be started using startForegroundService() and should show a statusbar icon while running.
If you don't do that the Service is killed when the App is closed.
However you should see some log in Logcat regarding WHY the Service is killed.

How to know if phone app is closed

please explain me how does android call lock screen after closing emergency dialer. I've tried to check every second if emergency call is the top activity if it's not then i just lock device but this didn't do it's job in android 5.0 and higher. So, I need another solution.
My code:
private static final long INTERVAL = TimeUnit.SECONDS.toMillis(1/100);
private Thread t = null;
private Context ctx = null;
private boolean running = false;
public MyService2() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
running = true;
ctx = this;
Log.i("Point","PreRun");
t = new Thread(new Runnable() {
#Override
public void run() {
Log.i("Point","preloop");
do {
Log.i("Point", "Prechech");
if (activityManager.getRunningTasks(1).get(0).topActivity.getPackageName().equals("com.android.phone") || activityManager.getRunningTasks(1).get(0).topActivity.getPackageName().equals("com.android.dialer"))
{
try {
Thread.sleep(INTERVAL);
} catch (InterruptedException e) {
Log.i("Point", "Thread interrupted: 'KioskService'");
}
} else {
running=false;
Log.i("Task is",activityManager.getRunningTasks(1).get(0).topActivity.getPackageName());
stopSelf();
}
}while (running) ;
}
});
t.start();
Log.i("Point","Done");
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("Point","Service is stopped");
}
}
And this:
public class MyActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent("com.android.phone.EmergencyDialer.DIAL");
startActivity(intent);
Intent intent1 = new Intent(MyActivity.this,MyService2.class);
startService(intent1);
}
});
}
}
You can launch your emergency dialer like this:
Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(ComponentName.unflattenFromString("com.android.phone/.EmergencyDialer"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Moreover please check if you have declared your service properly in manifest.
<service
android:name=".MyService2">
</service>

Home Button Service Background Music

I have a background music which is in Service, it works fine but when I pressed the HOME Button the music won't stop. Help me.
Service:
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.haha);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
This is my Activity where have the intent:
public class MainActivity extends Activity implements OnClickListener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent svc=new Intent(this, BackgroundSoundService.class);//This is the intent
startService(svc);
View adventuretime1 = this.findViewById(R.id.button1);
adventuretime1.setOnClickListener(this);
View advanced2 = this.findViewById(R.id.button2);
advanced2.setOnClickListener(this);
}
#Override
public void onBackPressed(){
new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle("Exit")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
System.exit(0);
}
}).setNegativeButton("No", null).show();
}
public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
Intent button1 = new Intent(this, AdventureTime.class);
startActivity(button1);
break;
case R.id.button2:
Intent button2 = new Intent(this, AdvancedKids.class);
startActivity(button2);
break;
}
Well it is a Service and Services are supposed to have a longer life time that your UI activity or fragments. From your code I don't see the case where you are handling the HOME button click in your app and stopping the service or likewise. You should probably be doing that.Its just another H/W button which triggers events on which you can piggyback.
By the way whats System.exit(0); doing in your android code?
Because when you click the HOME_BUTTON,the service will not call onDestory().
You can register a broadcastReceiver for the HOME_BUTTON,like this:
context.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//destory the service if you want
}
}, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
If you just want to stop the Service, then you can call this method.

Stop service in an activity

I'm using following code to stop my service
Intent intent = new Intent(MainActivity.this, UsageRecorderService.class);
stopService(intent);
And this is my service that works indefinitely
public class UsageRecorderService extends IntentService {
public UsageRecorderService() {
super("UsageRecorder");
}
#Override
protected void onHandleIntent(Intent intent) {
while (true) {
UsageRecorder.recordUsages(this, false);
SystemClock.sleep(10000);
}
}
}
Why does not stop my service?
This code would work
public class UsageRecorderService extends IntentService {
private boolean mStop = false;
public UsageRecorderService() {
super("UsageRecorder");
}
public final Object sLock = new Object();
public void onDestroy() {
synchronized (sLock) {
mStop = true;
}
}
#Override
protected void onHandleIntent(Intent intent) {
while (true) {
synchronized (sLock) {
if (mStop) break;
}
UsageRecorder.recordUsages(this, false);
SystemClock.sleep(10000);
}
}
}
You can use stopService
Intent intent = new Intent(MainActivity.this, UsageRecorderService.class);
stopService(intent);
Also I recommend to read Services guide to understand what is going there.
Activity:
sendBroadcast(new Intent(ACTION_STOP));
IntentService
public class UsageRecorderService extends IntentService {
private static final String TAG = "UsageRecorderService";
String ACTION_STOP = "com.xxx.UsageRecorderService.ACTION_STOP";
boolean stop;
public UsageRecorderService() {
super("UsageRecorder");
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
if (ACTION_STOP.equals(intent.getAction())) {
stop = true;
}
}
};
#Override public void onCreate() {
super.onCreate();
IntentFilter intentFilter = new IntentFilter(ACTION_STOP);
registerReceiver(receiver, intentFilter);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG,"onHandleIntent");
while (true && !stop) {
Log.i(TAG,"----running----");
//UsageRecorder.recordUsages(this, false);
SystemClock.sleep(10000);
}
}
#Override public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
An IntentService is designed to stop itself only when all the requests present in the work queue have been handled.Android stops the service after all start requests have been handled.

Start android activity from receiver (inside running service)

I want to display an alert when a sms is received, so my idea is to start a new activity that launch the alertdialog.
My service starts with no problem, and starts receiver as well..
I can receive sms and display toast alerts fine.. but i'd like to show a custom alertdialog instead.
This is the activity that starts my service (ServiceExampleActivity ):
public class ServiceExampleActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnStartService = (Button) findViewById(R.id.btnStart);
Button btnStopService = (Button) findViewById(R.id.btnStop);
btnStartService.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
StartMyService();
}
});
btnStopService.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
StopMyService();
}
});
}
private void StartMyService() {
Intent myServiceIntent = new Intent(this, ServiceTest.class);
startService(myServiceIntent);
}
private void StopMyService() {
Intent myServiceIntent = new Intent(this, ServiceTest.class);
stopService(myServiceIntent);
}
}
This is my Service (ServiceTest):
public class ServiceTest extends Service {
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
private BroadcastReceiver myBroadcastReceiver = null;
#Override
public void onCreate() {
super.onCreate();
final IntentFilter theFilter = new IntentFilter();
theFilter.addAction(ACTION);
this.myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
StartDialogActivity(context, intent);
}
};
this.registerReceiver(myBroadcastReceiver, theFilter);
}
#Override
public IBinder onBind(Intent arg) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d("ServiceTest", "Started");
Toast.makeText(this, "Service started...", 3000).show();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
Toast.makeText(this, "Service destroyed...", 3000).show();
}
private void StartDialogActivity(Context context, Intent intent) {
Intent dlgIntent = new Intent(context, DialogActivity.class);
dlgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(dlgIntent);
}
}
And this is the activity i want to launch to display the alertdialog normally..
public class DialogActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog);
}
}
When it tries to start the activity, the app crashes..
Can you tell me were is the error..??
Like this, you want start activity from service
Intent dlgIntent = new Intent(context, DialogActivity.class);
dlgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(dlgIntent );

Categories

Resources