I've been studying from the book "Pro Android 2." I'm working through a Service example that consists of two classes: BackgroundService.java and MainActivity.java. The MainActivity claims (erroneously?) it starts the Service as indicated by output to logcat from the Log.d call below:
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "starting service");
Button bindBtn = (Button)findViewById(R.id.bindBtn);
bindBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent backgroundService = new Intent(MainActivity.this, com.marie.mainactivity.BackgroundService.class);
startService(backgroundService);
}
});
Button unbindBtn = (Button)findViewById(R.id.unbindBtn);
unbindBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
stopService(new Intent(MainActivity.this, BackgroundService.class));
}
});
}
}
What puzzles me is the UI provides two buttons: Bind and UnBind as shown above. But according to the documentation if onBind() as shown below returns null that indicates you don't want to allow binding. But as shown above the onClick() method of (the Bind button) bindBtn.setOnClickListener(new OnClickListener() calls startService(backgroundService) which gives this error:"Unable to start service Intent { cmp=com.marie.mainactivity/.BackgroundService }: not found"
public class BackgroundService extends Service {
private NotificationManager notificationMgr;
#Override
public void onCreate() {
super.onCreate();
notificationMgr = NotificationManager)getSystemService(NOTIFICATION_SERVICE);
displayNotificationMessage("starting Background Service");
Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService");
thr.start();
}
class ServiceWorker implements Runnable
{
public void run() {
// do background processing here...
//stop the service when done...
//BackgroundService.this.stopSelf();
}
}
#Override
public void onDestroy()
{
displayNotificationMessage("stopping Background Service");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void displayNotificationMessage(String message)
{
Notification notification = new Notification(R.drawable.note, message, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
notification.setLatestEventInfo(this, "Background Service", message, contentIntent);
notificationMgr.notify(R.id.app_notification_id, notification);
}
}
I don't understand the point of this example. If onBind() returns null what's the point of having a Bind button (bindBtn)? I thought the point was to show how to start a BackgroundService. But it doesn't seem to work unless I'm missing something.
I should add I have added to my AndroidManifest.xml:
<service android:name=".BackgroundService"></service>
as follows:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<service android:name=".BackgroundService"></service>
</activity>
</application>
Remove the service from inside the activity. It is at the same level as the activity within the application. Eg:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".BackgroundService"></service>
</application>
Related
i want when boot run app server allow for receive message any time
without showing application
this code problem when boot show Notification twice only
but i want receive message any time
Is this "android:exported" important, What used
code AndroidManifest
<service
android:name=".appService"
android:exported="true"
android:enabled="true">
</service>
<receiver
android:name=".ServiceStarterBoot"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
code BroadcastReceiver
public class ServiceStarterBoot extends BroadcastReceiver {
private Context context ;
#Override
public void onReceive(Context context1, Intent intent) {
this.context = context1;
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceLauncher = new Intent(context, appService.class);
context.startService(serviceLauncher);
}}
code Service
public class appService extends Service {
#Override
public void onCreate() {
super.onCreate();
lood();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
//return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent, flags, startId);
}
private void lood(){
SystemClock.sleep(3000);
Runnable runnable = new Runnable() {
public void run() {
boolean p= true ;
while(p) {
SystemClock.sleep(5000);
showNotification();
}
}
};
Thread mythread = new Thread(runnable);
mythread.start();
}
please help
thanks
you have to make your service sticky:
Service.START_STICKY
then it is infinite and restarts itself when killed by OS for any reason.
It even starts itself when booting OS and app is NOT opened by user.
Best regards.
pseudo code:
onStartCommand(..){
...
//e.g. wifilisterner
Wifilistener WF = new Wifilistener(Interface yourInterfaceCallBackMethod);
}
something like this.
When I run my app in an emulator and kill the process, my service gets started and runs in the background (Toast: "Service Called") BUT it does not get called at all on a real device and no logcat runs because the broadcast receiver or my service does not get called:
MainFest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Service -->
<service android:name=".MyService">
<intent-filter>
<action android:name="com.mypackage.myapp.MyService" />
</intent-filter>
</service>
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:label="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- Service -->
MainActivity:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
//TODO your background code
Intent i = new Intent(MainActivity.this, PushNotification.class);
startActivity(i);
}
});
PushNotification.class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Context context = this;
if (!isMyServiceRunning()){
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
finish();
}
else
{
finish();
}
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (MyService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
BootReceiver:
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
}
}
}
MyService:
public class MyService extends Service {
Handler handler;
#Override
public int onStartCommand(Intent intent, int flags, int startId){
// START YOUR TASKS
Toast.makeText(MyService.this, "Service Called", Toast.LENGTH_SHORT).show();
Context context = this;
Intent in = new Intent(context, FragmentMain.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
in.putExtra("valuerunInBG", "1");
context.startActivity(in);;
//loop();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
// STOP YOUR TASKS
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
Modify your manifest as given below
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:label="BootReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I made a small change in it just given the priority by which it will start as early as possible
also change the code given below
#Override
public int onStartCommand(Intent intent, int flags, int startId){
// START YOUR TASKS
Toast.makeText(MyService.this, "Service Called", Toast.LENGTH_SHORT).show();
Context context = this;
Intent in = new Intent(context, FragmentMain.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
in.putExtra("valuerunInBG", "1");
context.startActivity(in);;
//loop();
return START_STICKY; //THIS WILL RESTART YOUR SERVICE IF IT GETS STOPPED BY ANDROID OS DUE TO LOW MEMORY
}
android.intent.action.BOOT_COMPLETED Takes time after your device starts, try waiting 3-4 minutes
Start your service again in your service class's onDestroy() method. This way when your application will be closed, then onDestroy() will be called and that will start your service again.
Some time Toast does not work inside of Service so please use Log to know whether your code is running or not.
I am creating a notification and I add "addAction" to my notification.
I want to when I click on the "addAction", the notification remove and run another one code.
How I can do this?
Intent intent = new Intent(context, Activity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
.........
.addAction(R.drawable.eye, "View", pi)
I want to run Activity.class in background, I mean to that this activity doenst open but the code in this activity run.
How I can do this?
If you want to run code in background, You have to create a service
ex
service code
package com.javatechig.serviceexample;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class HelloService extends Service {
private static final String TAG = "HelloService";
private boolean isRunning = false;
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
isRunning = true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
//Creating new thread for my service
//Always write your long running tasks in a separate thread, to avoid ANR
new Thread(new Runnable() {
#Override
public void run() {
//Your logic that service will perform will be placed here
//In this example we are just looping and waits for 1000 milliseconds in each loop.
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
if(isRunning){
Log.i(TAG, "Service running");
}
}
//Stop service once it finishes its task
stopSelf();
}
}).start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.javatechig.serviceexample" >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".HelloActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--Service declared in manifest -->
<service android:name=".HelloService"
android:exported="false"/>
</application>
</manifest>
To start the servcie , add below code to the activity
Intent intent = new Intent(this, HelloService.class);
startService(intent);
I am new to android.
My project is having one activity and one service. My service is having one broadcast receiver and activity is having broadcast sender which is in PeriodSender method .Dynamically when i am registering the receiver then at the start of the service it is not invoking but if i send some thing after few moment then it invokes.
But I want to register it in Manifest ,I have included the receiver details in Manifest but the receiver is not invoking . My receiver class name is MyReceiver21 and the intent action is MY_ACTION1. actually I want my broadcast receiver to be registered at the starting it self.
Following is my Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.experiment.Test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="3"
android:targetSdkVersion="3" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.experiment.Test.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyReceiver21" >
<intent-filter>
<action android:name="com.experiment.Test.MainActivity.MY_ACTION1" />
</intent-filter>
</receiver>
<service
android:name="Myservice21"
android:enabled="true" />
</application>
</manifest>
my activity code is
public class MainActivity extends Activity {
MediaPlayer OurSong;
Context SavedThis=this;
int i=0;
public Handler handler1 = new Handler();
public Handler handler2= new Handler();
Button Start;
Button Stop;
Button Button21;
Button StopButton;
public int GProgreess=0;
int Rc=0;
int BitCount=0;
int SeekPos=0;
int Period=500;
MyReceiver myReceiver;
final static String MY_ACTION1 = "MY_ACTION1";
public int Data=0;
public int beat=0;
int BreakVar=0;
Thread myThread ;
static public TextView text1,text2,text3,text4;
private SeekBar bar;
private TextView textProgress,textAction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StopButton=(Button)findViewById(R.id.buttonstop);
StopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
stopService(new Intent(SavedThis,Myservice21.class));
BitCount=0;
}/****End of on clk******/
});/*****End of set on clk listener*****/
Button21.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
Rc=0;
BitCount=13;
stopService(new Intent(SavedThis,Myservice25.class));
SystemClock.sleep(200);
startService(new Intent(SavedThis,Myservice21.class));
PeriodSender();
}/****End of on clk******/
});/*****End of set on clk listener*****/
}
public void PeriodSender()
{
Intent intent1 = new Intent();
intent1.setAction("MY_ACTION1");
intent1.putExtra("kz", Period);
sendBroadcast(intent1);
text3.setText(""+Period);
Toast.makeText(getApplicationContext(), "PeriodSent",Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
my service class
public class Myservice21 extends Service {
int BitCount=0;
int Rc=0;
int Period=500;
Intent intent = new Intent();
MyReceiver21 myReceiver21;
public Handler handler1 = new Handler();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public void onCreate()
{
intent.setAction(MY_ACTION);
myReceiver21 = new MyReceiver21();
IntentFilter intentFilter1 = new IntentFilter();
intentFilter1.addAction(com.experiment.Test.MainActivity.MY_ACTION1);
registerReceiver(myReceiver21, intentFilter1);
Intent intent1 = new Intent(Myservice21.this,MainActivity.class);
startService(intent1);
handler1.post(runnable1);
}
public class MyReceiver21 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
int data = intent.getIntExtra("kz", 0);
Period=data;
Toast.makeText(getApplicationContext(), "PeriodRceived21",Toast.LENGTH_SHORT).show();
}
}
public void onStart(Intent intent,int StartId)
{
Rc=0;
}
public void onDestroy()
{
}
}
can any one help me to register the receiver in manifest. Thanks in advance
You don't have to add the intent filter for your own broadcasts. Just register the service for that broadcasts with registerReceiver() when the service is started.
Note, that you have to start the service manually when your App starts, for instance in the MainActivity.onCreate():
startService(new Intent(this, Myservice21.class));
When the MainActivity has been created, it will start the service, which itself registers for BroadcastIntents and starts listening for them. This should work.
How would I get my app to listen for when DayDream stops. When the system stops dreaming it sends the ACTION_DREAMING_STOPPED string out. I have added a BroadcastReceiver in my OnResume and onCreate and neither are used when DayDream stops. So where should I put my listener? I do apologize if I am calling something by its wrong name, I haven't worked with DayDream before.
#Override
protected void onResume() {
mDreamingBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_DREAMING_STOPPED)) {
// Resume the fragment as soon as the dreaming has
// stopped
Intent intent1 = new Intent(MainActivity.this, MainWelcome.class);
startActivity(intent1);
}
}
};
super.onResume();
}
The BroadcastReceiver can be created in your onCreate.
Ensure you register the receiver with: registerReceiver(receiver, filter) and that you've got the intent-filter inside your AndroidManifest.xml.
Sample:
MainActivity.java
public class MainActivity extends Activity
{
private static final String TAG = MainActivity.class.toString();
private BroadcastReceiver receiver;
private IntentFilter filter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
Log.d(TAG, TAG + " received broacast intent: " + intent);
if (intent.getAction().equals(Intent.ACTION_DREAMING_STOPPED)) {
Log.d(TAG, "received dream stopped");
}
}
};
filter = new IntentFilter("android.intent.action.DREAMING_STOPPED");
super.registerReceiver(receiver, filter);
}
}
AndroidManifest.xml
<activity
android:name="com.daydreamtester.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.DREAMING_STOPPED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>