'Below are my two classes which I'm trying to pass data from my activity to my service. I've passed to other Activities no problem but I when look for my extras in my IntentService it always comes back null. Any ideas what I'm doing incorrectly?
public class TestActivity extends Activity {
private Button mbutton;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mbutton = (Button) this.findViewById(R.id.button1);
mbutton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View arg0) {
// TODO Auto-generated method stub
Log.d("TestActivity", "onClick: starting srvice");
Intent intent = new Intent(TestActivity.this/*getApplicationContext()*/, MyService.class);
/*TestActivity.this.getApplicationContext().*/
intent.putExtra(MyService.PARAM_IN_NAME, ((EditText)findViewById(R.id.editText1)).getText());
intent.putExtra(MyService.PARAM_IN_JOB, ((EditText)findViewById(R.id.editText2)).getText());
intent.putExtra(MyService.PARAM_IN_BDAY, ((EditText)findViewById(R.id.editText3)).getText());
startService(intent);
}
});
}
}
This is my Service class which I'm trying to extract my data from activity.
public class MyService extends IntentService {
public static final String PARAM_IN_NAME = "name";
public static final String PARAM_IN_JOB = "job";
public static final String PARAM_IN_BDAY = "bday";
private String mJob;
private String mBday;
private String mName;
// --------------CONSTRUCTORS--------------
public MyService() {
super("MyServiceThread");
}
public MyService(String name) {
super(name);
}
// -------------OVERRIDE-------------
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onDestroy(){
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
#Override
protected void onHandleIntent(Intent intent) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
mName = intent.getStringExtra(PARAM_IN_NAME);
mJob = intent.getStringExtra(PARAM_IN_JOB);
mBday = intent.getStringExtra(PARAM_IN_BDAY);
String result = "Name = " + mBday + " | Job = " + mJob + " | Bday = " + mBday;
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
}
}
This is also what I have for my Manifest file:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TestActivity"
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=".MyService" android:enabled="true" />
Use bundle for sending the data to the service.
From the activity.
Bundle bundle = new Bundle();
bundle.putCharSequence("extraData", data);
myIntent.putExtras(bundle);
Receives in service.
Bundle bundle = intent.getExtras();
data = (String) bundle.getCharSequence("extraData");
Your code is looking fine.
Try after adding toString() when you get text from the EditText like this:
intent.putExtra(MyService.PARAM_IN_NAME, ((EditText)findViewById(R.id.editText1)).getText().toString());
I hand my data over like this to the receiving end
Bundle bundle = this.getIntent().getExtras();
String scan = bundle.getString("scan");
((TextView)findViewById(R.id.username)).setText(scan);
Related
So I'm having trouble trying to pass the greater of two entered numbers from one app and then have the receiver broadcast it in another. Here's code from the sending app:
public class MainActivity extends AppCompatActivity {
private EditText etFirst;
private EditText etSecond;
private Button btSend;
private int num;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etFirst = (EditText) findViewById(R.id.etFirst);
etSecond =(EditText) findViewById(R.id.etSecond);
btSend = (Button) findViewById(R.id.btSend);
btSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int a = Integer.parseInt(etFirst.getText().toString());
int b = Integer.parseInt(etSecond.getText().toString());
if (a > b) {
num = a;
}
else {
num = b;
}
Intent intent = new Intent("com.numb.sending.intent");
intent.putExtra("com.numb.sending.intent.params", num);
sendBroadcast(intent);
}
});
}
}
Code from the receiving app:
public class MainActivity extends AppCompatActivity {
private Button btReceive;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btReceive = (Button) findViewById(R.id.btReceive);
btReceive.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MyReceiver.INTENT);
intent.putExtra(MyReceiver.PARAM);
sendBroadcast(intent);
}
});
}
}
My receiver:
public class MyReceiver extends BroadcastReceiver {
public static final String PARAM = "com.numb.sending.intent.params";
public static final String INTENT = "com.numb.sending.intent";
public MyReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(PARAM)) {
String value = intent.getStringExtra(PARAM);
Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
}
}
}
Any help?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.numb.sending">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.numb.sending.intent"/>
</intent-filter>
</receiver>
</application>
I have 2 Activity one is sending a broadcust and another receiving. But receiver never get called -
MainActivity
public class MainActivity extends AppCompatActivity {
public static String BROADCAST_ACTION = "com.aj.SHOWTOAST";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendBroadcast(View v) {
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
this.sendBroadcast(broadcast);
}
}
ToastDisplay
public class ToastDisplay extends AppCompatActivity {
public static String BROADCAST_ACTION = "com.aj.SHOWTOAST";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toast_display);
IntentFilter filter = new IntentFilter(BROADCAST_ACTION);
this.registerReceiver(new Receiver(), filter);
}
private class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
Log.d("TAG", "onReceive: SMS SENT!!");
Toast.makeText(getApplicationContext(), "SMS SENT!!", Toast.LENGTH_SHORT).show();
}
}
}
Manifest
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ToastDisplay">
<intent-filter>
<action android:name="com.aj.SHOWTOAST" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
You can put broad cast receiver in your by this way also.
public class SampleActivity extends AppCompatActivity {
public static final String DISPLAY_MESSAGE_ACTION = "com.google.android.gcm.demo.app.DISPLAY_MESSAGE";
// Receive Message through Broadcast Receiver...
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String receiver = intent.getStringExtra("receiver");
Toast.makeText(context, "" + receiver, Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mobile_verify);
}
#Override
protected void onResume() {
super.onResume();
//registering the receiver...
registerReceiver(mHandleMessageReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION));
}
#Override
protected void onPause() {
super.onPause();
//Unregistering the receiver...
unregisterReceiver(mHandleMessageReceiver);
}
}
Broadcast receiver can be called through the following intent. You can use this intent any where to call this broadcast receiver. For example there are two activity and in those two activities you are using this receiver and you calling this intent from some other class which handles server response or database result. Whichever activity is in front that activities receiver will be called.i.e., activity one is in front if you are calling this receiver intent means then receiver in the activity one will be triggered.
Intent intent = new Intent(SampleActivity.DISPLAY_MESSAGE_ACTION);
intent.putExtra("receiver", "testMessage");
sendBroadcast(intent);
If the broadcast is going to happen within the app then it is good to use LocalBroadCastManager
public class MainActivity extends AppCompatActivity {
public static String BROADCAST_ACTION = "com.aj.SHOWTOAST";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendBroadcast(View v) {
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(broadcast);
}
}
public class ToastDisplay extends AppCompatActivity {
public static String BROADCAST_ACTION = "com.aj.SHOWTOAST";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toast_display);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//your code here
}
};
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter(BROADCAST_ACTION)); }
}
You cant send boradcast one activity to another activity. So you have to do it like below.
First implement the Receiver as a separate class.
Receiver.java:
public class Receiver extends BroadcastReceiver {
public Receiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Hello", Toast.LENGTH_LONG).show();
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private static final String BROADCAST_ACTION = "com.aj.SHOWTOAST";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendBroadcast(View v) {
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
this.sendBroadcast(broadcast);
}
}
And manifest should be as below.
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".Receiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.aj.SHOWTOAST"/>
</intent-filter>
</receiver>
My problem is that onCreate() and onPause() in a closed activity gets called when they shouldn't.
I the Start activity i call:
Intent intent = new Intent(this, SelectTransportActivity.class);
startActivity(intent);
this.finish();
when i want to start the SelectTransport activity.
But when i want to start the Stop Activity from the SelectTransport activity and i call
Intent i = new Intent(this, StopActivity.class);
startActivity(i);
this.finish();
I can see in the debugger that the onCreate() in the Start activity is called before the Stop activity starts.
Similarly, when I finishes the Stop activity, the onPause() in the Start activity is called, after which the Start activity starts.
Why are the onCreate() and onPause() called in the Start activity from the other activities when they shouldn't and I have finished the activity?
The manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.greenenergy"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<!-- Launching -->
<uses-permission android:name="android.permission.BATTERY_STATS" />
<!-- All probes -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Location probe -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name=".GreenEnergyApplication">
<service android:name="edu.mit.media.funf.FunfManager" >
<meta-data
android:name="default"
android:value="#string/default_pipeline" />
</service>
<receiver
android:name="edu.mit.media.funf.Launcher"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.DOCK_EVENT" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<activity
android:name="com.example.greenenergy.StartupActivity"
android:screenOrientation="portrait"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.greenenergy.StartActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_start" >
</activity>
<activity
android:name="com.example.greenenergy.WaysActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_ways" >
</activity>
<activity
android:name="com.example.greenenergy.StopActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_stop">
</activity>
<activity
android:name="com.example.greenenergy.StatisticsActivity"
android:screenOrientation="portrait"
android:label="#string/title_activity_statistics">
</activity>
</application>
The Start activity:
public class StartActivity extends BaseActivity implements OnClickListener {
private Button bStart, bStats;
Controller controller;
GPSCollectorSingleton gpsCollectorSingleton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
autoDetect();
}
private void init() {
setContentView(R.layout.activity_main);
bStart = (Button) findViewById(R.id.bStart);
bStats = (Button) findViewById(R.id.bStatisticsStart);
bStart.setOnClickListener(this);
bStats.setOnClickListener(this);
controller = new Controller(); // Init controller
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
controller.createTable(); // Create table if not exist
gpsCollectorSingleton = GPSCollectorSingleton.getInstance(); // Init model
// Bind to the service, to create the connection with FunfManager
getApplicationContext().bindService(new Intent(this, FunfManager.class), funfManagerConn, BIND_AUTO_CREATE);
}
private void autoDetect() {
boolean auto = ((GreenEnergyApplication) getApplication()).getAutoPreference(getApplicationContext());
boolean started = ((GreenEnergyApplication) getApplication()).getStartPreference(getApplicationContext());
if (auto && !started) {
controller.enableAutoDetection(getApplicationContext(), gpsCollectorSingleton);
}
}
#Override
protected void onPause() {
super.onPause();
this.finish();
}
#Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.bStart:
startDataCollector();
break;
case R.id.bStatisticsStart:
intent = new Intent(this, StatisticsActivity.class);
startActivity(intent);
break;
}
}
private void startDataCollector() {
if (((GreenEnergyApplication) getApplication()).getStartPreference(getApplicationContext()) == false) {
controller.datahandlerObserver(getApplicationContext(), gpsCollectorSingleton); // Observer
((GreenEnergyApplication) getApplication()).setStartPreference(getApplicationContext(), true);
}
Intent intent = new Intent(this, WaysActivity.class);
startActivity(intent);
}
}
The SelectTransport activity:
public class SelectTransportActivity extends BaseActivity implements OnItemClickListener {
GridView gridview;
private static int DATABASE_ID_OFFSET = 2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ways);
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(this);
}
#Override
protected void onPause() {
super.onPause();
this.finish();
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
((GreenEnergyApplication)getApplication()).setTransportationPreference(getApplicationContext(), arg2+DATABASE_ID_OFFSET);
Log.i("WayActivity",
"ARG0: " + arg0.toString() + " Arg1: " + arg1.toString() + " "
+ " Arg2: " + arg2 + " Arg3: " + arg3);
Intent i = new Intent(this, StopActivity.class);
startActivity(i);
}
}
The Stop activity:
public class StopActivity extends StartActivity implements OnClickListener, Observer {
Button stopButton, statsButton;
TextView statusTextView;
int distance, time, transportTypeEstimate, transportType;
int sessionStartTime = 0;
int sessionStartDistance = 0;
GPSCollectorSingleton gpsCollectorSingleton;
LocationData location;
boolean transportEstimation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GPSCollectorSingleton gps = GPSCollectorSingleton.getInstance();
if (((GreenEnergyApplication) getApplication()).getStartPreference(getApplicationContext()) == false) {
Log.i("STOP - STOP", "hasspeed");
stopDataCollector();
}
setContentView(R.layout.activity_stop);
stopButton = (Button) findViewById(R.id.bStop);
statsButton = (Button) findViewById(R.id.bStatisticsStop);
statusTextView = (TextView) findViewById(R.id.tvStatus);
stopButton.setOnClickListener(this);
statsButton.setOnClickListener(this);
gpsCollectorSingleton = GPSCollectorSingleton.getInstance(); // Init model
gpsCollectorSingleton.addObserver(this); // Observe on models state
initTransportTypeDetection();
}
/**
* Initializes estimating of transport type or manually chosen transport type
*/
private void initTransportTypeDetection() {
transportType = ((GreenEnergyApplication) getApplication())
.getTransportationPreference(getApplicationContext());
transportTypeEstimate = transportType;
if (transportType == TransportationDefinerSingleton.TRANSPORT_UNKNOWN) { // Start transport type estimation
TransportationDefinerSingleton transport = TransportationDefinerSingleton.getInstance(); // Get model
transport.addObservable(gpsCollectorSingleton); // Add observer for estimating transport type
transportEstimation = true;
} else { // Transport type manually specified
setSessionStartDistanceAndTime();
transportEstimation = false;
}
}
private void setSessionStartDistanceAndTime() {
Controller controller = new Controller();
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
sessionStartDistance = controller.getDistanceFromID(transportType);
sessionStartTime = controller.getTimeFromID(transportType);
}
#Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.bStop:
stopDataCollector();
break;
case R.id.bStatisticsStop:
intent = new Intent(this, StatisticsActivity.class);
startActivityForResult(intent, -1);
break;
}
}
private void stopDataCollector() {
((GreenEnergyApplication) getApplication()).setTransportationPreference(getApplicationContext(),
TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
((GreenEnergyApplication) getApplication()).setStartPreference(getApplicationContext(), false);
gpsCollectorSingleton.deleteObservers(); // Delete all observers
Controller controller = new Controller();
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
// Get unknown data. From estimate of transport type or data collected while deciding transport type.
int distance = controller.getDistanceFromID(TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
int time = controller.getTimeFromID(TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
if (transportEstimation) { // Estimate
controller.updateTable(transportTypeEstimate, distance, time);
} else { // Manually chosen transport type
controller.updateTable(transportType, distance, time);
}
controller.resetTable(TransportationDefinerSingleton.TRANSPORT_UNKNOWN);
Intent intent = new Intent(this, StartActivity.class);
startActivity(intent);
this.finish();
}
#Override
public void update(Observable observable, Object data) {
Controller controller = new Controller();
Database database = new Database(getApplicationContext());
controller.controlDatabase(database);
transportTypeEstimate = getTransportType();
distance = controller.getDistanceFromID(transportType) - sessionStartDistance;
time = controller.getTimeFromID(transportType) - sessionStartTime;
location = (LocationData) data;
runOnUiThread(new Runnable() {
#Override
public void run() {
String transportName = getTransportName(transportTypeEstimate);
statusTextView.setText("Transport type: " + transportName + " Distance: " + distance + " Time: " + time
+ "\nTimeStamp: " + location.getTime() + "\nSpeed: " + location.getSpeed()
+ " Seconds since last: " + location.getSecondsSinceLastSample());
}
});
}
private int getTransportType() {
if (transportEstimation) {
TransportationDefinerSingleton transport = TransportationDefinerSingleton.getInstance();
Controller controller = new Controller();
controller.controlTransportationDefinerSingleton(transport);
transportTypeEstimate = controller.getTransportType();
}
return transportTypeEstimate;
}
private String getTransportName(int type) {
switch (type) {
case TransportationDefinerSingleton.TRANSPORT_UNKNOWN:
return "Unknown";
case TransportationDefinerSingleton.TRANSPORT_WALK:
return "Walking";
case TransportationDefinerSingleton.TRANSPORT_BIKE:
return "Bike";
case TransportationDefinerSingleton.TRANSPORT_CAR:
return "Car";
case TransportationDefinerSingleton.TRANSPORT_BUS:
return "Bus";
case TransportationDefinerSingleton.TRANSPORT_TRAIN:
return "Train";
case TransportationDefinerSingleton.TRANSPORT_MOTORCYCLE:
return "Motor Cycle";
case TransportationDefinerSingleton.TRANSPORT_CARPOOL:
return "Carpool";
}
return "";
}
}
The Base activity, which is the superclass for the other activities. It just sets up the option menu and other basic stuff.
public class BaseActivity extends Activity {
private Controller controller;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GPSCollectorSingleton gpsCollectorSingleton = GPSCollectorSingleton.getInstance(); // Init model
controller = new Controller();
controller.controlGPSCollectorSingleton(gpsCollectorSingleton); // Init controller
}
protected ServiceConnection funfManagerConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("OnServiceConnected", "MainActivity");
controller.onServiceConnected(service);
}
#Override
public void onServiceDisconnected(ComponentName name) {
controller.onServiceDisconnected();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
disableService();
closeActivity();
return true;
case R.id.action_clear:
Database database = new Database(getApplicationContext());
database.dropTable();
return true;
case R.id.action_toggle_auto:
if (item.isChecked()) {
item.setChecked(false);
((GreenEnergyApplication) getApplication()).setAutoPreference(getApplicationContext(), false);
} else {
item.setChecked(true);
((GreenEnergyApplication) getApplication()).setAutoPreference(getApplicationContext(), true);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
if (((GreenEnergyApplication) getApplication()).getAutoPreference(getApplicationContext()) == true) {
menu.findItem(R.id.action_toggle_auto).setChecked(true);
}
return true;
}
/**
* Disables the service and the pipeline
*/
private void disableService() {
controller.disablePipeline(); // Disable pipeline
boolean isBound = false;
isBound = getApplicationContext().bindService(new Intent(getApplicationContext(), FunfManager.class),
funfManagerConn, BIND_AUTO_CREATE);
if (isBound) {
getApplicationContext().unbindService(funfManagerConn); // Disable
// service
}
}
private void closeActivity() {
this.finish();
}
}
Let's start with the easy things: Your StopActivity extends StartActivity
public class StopActivity extends StartActivity {...
It should either extend BaseActivity or a call to super.onCreate() will run the code in StartActivity.onCreate().
I use AIDL interface IExtendedNetworkService to get USSD code. But application only work after reboot device. I tried bindservice after install app but it didn't work. So my problem is how way to bind service without reboot device . This is my code:
interface:
package com.android.internal.telephony;
interface IExtendedNetworkService {
void setMmiString(String number);
CharSequence getMmiRunningText();
CharSequence getUserMessage(CharSequence text);
void clearMmiString();
}
Service
public class CDUSSDService extends Service {
private String TAG = "THANG-NGUYEN";
private boolean mActive = false;
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_INSERT)) {
// activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
} else if (intent.getAction().equals(Intent.ACTION_DELETE)) {
mActive = false;
Log.d(TAG, "deactivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() {
public void clearMmiString() throws RemoteException {
Log.d(TAG, "called clear");
}
public void setMmiString(String number) throws RemoteException {
Log.d(TAG, "setMmiString:" + number);
}
public CharSequence getMmiRunningText() throws RemoteException {
if (mActive == true) {
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
if (mActive == false) {
// listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
return text;
}
// listener is active, so broadcast data and suppress it from
// default behavior
// build data to send with intent for activity, format URI as per
// RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(
getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(
getBaseContext().getString(R.string.uri_param_name),
text.toString()).build();
sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
public void onCreate() {
Log.i(TAG, "called onCreate");
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "called onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
// the insert/delete intents will be fired by activity to
// activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(
getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path),
PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
}
MainActivity:
public class MainActivity extends Activity {
private Button btnCheckUSSD;
private Context mContext;
private IExtendedNetworkService mService;
private EditText inputUSSD;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_main);
btnCheckUSSD = (Button) findViewById(R.id.btn_check);
inputUSSD = (EditText) findViewById(R.id.input_ussd);
btnCheckUSSD.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (!inputUSSD.getText().toString().isEmpty()) {
Intent service = new Intent(
"com.android.ussd.IExtendedNetworkService");
bindService(service, mConnecton, Context.BIND_AUTO_CREATE);
startActivity(new Intent("android.intent.action.CALL", Uri
.parse("tel:" + inputUSSD.getText().toString()
+ Uri.encode("#"))));
}
}
});
}
ServiceConnection mConnecton = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
mService = IExtendedNetworkService.Stub
.asInterface((IBinder) iBinder);
}
};
protected void onDestroy() {
super.onDestroy();
Log.d("THANG-NGUYEN", "onDestroy");
unbindService(mConnecton);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.example.checkussdcode"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="info.example.checkussdcode.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="info.example.checkussdcode.service.UssdCodeService"
android:process=":remote" >
<intent-filter>
<action android:name="com.android.ussd.IExtendedNetworkService" >
</action>
</intent-filter>
</service>
<receiver android:name="info.example.checkussdcode.RebootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I'm trying to start a service on android in order to performe some network-related tasks in background. I have written a basic network-manager for my app, which is a service. I basically used the tutorial from the android documentation. The basic structure goes as following:
public class MyNetworkManager extends Service {
// some code
private final IBinder mBinder = (IBinder) new MyBinder();
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
MyNetworkManager getService() {
return MyNetworkManager.this;
}
}
public void onCreate() {
// some network related stuff like setting up sockets etc.
}
public void onStart(Intent intent, int startid) {
while(true) {
// receive new connections etc
}
}
The calling app/activity is then:
public class AndroidNetworkManagerClient extends Activity {
private Button buttonSend;
private EditText inputText;
private TextView outputText;
private MyNetworkManager networkManager;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
networkManager = ((MyNetworkManager.MyBinder) binder).getService();
}
public void onServiceDisconnected(ComponentName className) {
networkManager = null;
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
inputText = (EditText) findViewById(R.id.textInput);
outputText = (TextView) findViewById(R.id.textOutput);
buttonSend = (Button)this.findViewById(R.id.buttonSend);
buttonSend.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (inputText.getText().length() != 0) {
outputText.append("Out: " + inputText.getText() + "\n");
networkManager.sendData("localhost", inputText.getText().toString());
}
}
});
bindService(new Intent(this, MyNetworkManager.class), mConnection, Context.BIND_AUTO_CREATE);
doSomeAppRelatedStuff();
}
bindService() seems to be called without any problems, but the variable "networkManager" is always null! I already tried to debug into the onCreate() method or onServiceConnected() but it seems, that these parts are not reached at all (at least no breakpoint was triggered).
The service is already registered in the AndroidManifest.xml:
package="some.random.name"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".AndroidNetworkManagerClient"
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=".MyNetworkManager"></service>
</application>
Anyone an idea?
Chances are, your Activity is getting into doSomeAppRelatedStuff() and trying to use networkManager before the binding is complete.
If doSomeAppRelatedStuff() absolutely must have the network manager to function, move your call to doSomeAppRelatedStuff() into onServiceConnected() so it won't actually start until the binding is complete. Note that if you do that, your onStart() and onResume() calls will probably (but not guaranteed!) happen before the binding is complete, so program accordingly.