I tried implementing the Activity Fence using the Google Awareness API. But changes in the user's activity are not getting detected. The headphone fence works as expected though.
ActivityFenceActivity
public class ActivityFenceActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks {
private static final String FENCE_RECEIVER_ACTION = "FENCE_RECEIVE";
private static final String FENCE_WALKING_KEY = "walkingKey";
private static final String FENCE_RUNNING_KEY = "runningKey";
private static final String TAG = ActivityFenceActivity.class.getSimpleName();
private GoogleApiClient googleApiClient;
private TextView activityTextView;
private BroadcastReceiver activityFenceReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent intent) {
Toast.makeText(context, "Recieved", Toast.LENGTH_SHORT).show();
FenceState fenceState = FenceState.extract(intent);
if (TextUtils.equals(fenceState.getFenceKey(), FENCE_WALKING_KEY)) {
switch (fenceState.getCurrentState()) {
case FenceState.TRUE:
activityTextView.setText("User is walking");
break;
case FenceState.FALSE:
activityTextView.setText("User is not walking");
break;
case FenceState.UNKNOWN:
activityTextView.setText("Activity state unknown");
break;
}
} else if (TextUtils.equals(fenceState.getFenceKey(), FENCE_RUNNING_KEY)) {
switch (fenceState.getCurrentState()) {
case FenceState.TRUE:
activityTextView.setText("User is running");
break;
case FenceState.FALSE:
activityTextView.setText("User is not running");
break;
case FenceState.UNKNOWN:
activityTextView.setText("Activity state unknown");
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_fence);
activityTextView = (TextView) findViewById(R.id.activityTextView);
googleApiClient = new GoogleApiClient.Builder(ActivityFenceActivity.this)
.addApi(Awareness.API)
.addConnectionCallbacks(this)
.build();
googleApiClient.connect();
findViewById(R.id.register_fence).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
registerActivityFence();
}
});
findViewById(R.id.unregister_fence).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
unregisterActivityFence();
}
});
}
#Override
public void onConnected(#Nullable final Bundle bundle) {
Log.d(TAG, "Google API connected");
}
#Override
public void onConnectionSuspended(final int i) {
Log.d(TAG, "Google API connection suspended");
}
#Override
protected void onStart() {
super.onStart();
registerReceiver(activityFenceReceiver, new IntentFilter(FENCE_RECEIVER_ACTION));
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(activityFenceReceiver);
unregisterActivityFence();
}
private void registerActivityFence() {
AwarenessFence walkingFence = DetectedActivityFence.during(DetectedActivityFence.WALKING);
AwarenessFence runningFence = DetectedActivityFence.during(DetectedActivityFence.RUNNING);
PendingIntent fencePendingIntent = PendingIntent.getBroadcast(this,
0,
new Intent(FENCE_RECEIVER_ACTION),
0);
Awareness.FenceApi.updateFences(googleApiClient, new FenceUpdateRequest.Builder()
.addFence(FENCE_WALKING_KEY, walkingFence, fencePendingIntent).build())
.setResultCallback(new ResultCallbacks<Status>() {
#Override
public void onSuccess(#NonNull final Status status) {
Toast.makeText(ActivityFenceActivity.this,
"Fence registered successfully",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(#NonNull final Status status) {
Toast.makeText(ActivityFenceActivity.this,
"Cannot register activity fence.",
Toast.LENGTH_SHORT).show();
}
});
Awareness.FenceApi.updateFences(googleApiClient, new FenceUpdateRequest.Builder()
.addFence(FENCE_RUNNING_KEY, runningFence, fencePendingIntent).build());
}
private void unregisterActivityFence() {
Awareness.FenceApi.updateFences(
googleApiClient,
new FenceUpdateRequest.Builder()
.removeFence(FENCE_WALKING_KEY)
.removeFence(FENCE_RUNNING_KEY)
.build()).setResultCallback(new ResultCallbacks<Status>() {
#Override
public void onSuccess(#NonNull Status status) {
Toast.makeText(ActivityFenceActivity.this,
"Fence unregistered successfully.",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(#NonNull Status status) {
Toast.makeText(ActivityFenceActivity.this,
"Cannot unregister headphone fence.",
Toast.LENGTH_SHORT).show();
}
});
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.subhrajyoti.awareness">
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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>
<meta-data
android:name="com.google.android.awareness.API_KEY"
android:value="AIzaSyBEmjlfC87xRUP2FnFynsDdY3QRuI1hIHs" />
</application>
</manifest>
If the headphone fence is working and the activity fence is not, maybe you simply forgot to add the permission in the manifest?
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
I tried to use Awareness API instead of geofencing, I think the problem is how you tested your code.
I'm pretty sure that Awareness uses phone's sensors, so when I use the GPS simulator to simulate a walk, it doesn't trigger anything, but if I use my real phone and walk, BroadcastReceiver is triggered.
However, I don't know how to simulate a "sensor walking" on the emulator!
Related
Hey guys I am working on an app which should connect to bluetooth devices. But at the moment I'm struggling with the problem that it doesn't find any bluetooth devices in my app but in the bluetooth settings it finds some. (my device runs android 6.x)
My code:
public class MainActivity extends AppCompatActivity {
private ProgressDialog progressDialogBluetoothDiscovery;
private ListView bluetoothDevices;
private ArrayList<String> bluetoothNearbyDevices;
private BluetoothAdapter mBluetoothAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
bluetoothDevices = (ListView) findViewById(R.id.bluetoothDevicesList);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(bluetoothBroadcast, filter);
bluetoothNearbyDevices = new ArrayList<>();
final FloatingActionButton searchDevices = (FloatingActionButton) findViewById(R.id.search_devices);
searchDevices.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
searchDevices();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(bluetoothBroadcast);
}
private void searchDevices() {
if (mBluetoothAdapter == null) {
Toast.makeText(MainActivity.this, getResources().getString(R.string.bluetooth_not_supported), Toast.LENGTH_LONG).show();
return;
} else {
if (!mBluetoothAdapter.isEnabled()) {
Snackbar.make(findViewById(R.id.coordinatorLayout), getResources().getString(R.string.bluetooth_not_enabled), Snackbar.LENGTH_LONG).setAction(getResources().getString(R.string.activate_bluetooth), new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, MainActivity.CONTEXT_INCLUDE_CODE);
}
}).show();
} else {
scanForDevices();
}
}
}
private void scanForDevices() {
mBluetoothAdapter.startDiscovery();
}
private final BroadcastReceiver bluetoothBroadcast = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
if (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) == BluetoothAdapter.STATE_ON) {
scanForDevices();
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
progressDialogBluetoothDiscovery = ProgressDialog.show(MainActivity.this, getResources().getString(R.string.bluetooth_discovery_title), getResources().getString(R.string.bluetooth_discovery_message), true);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
progressDialogBluetoothDiscovery.dismiss();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, bluetoothNearbyDevices);
bluetoothDevices.setAdapter(arrayAdapter);
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
Toast.makeText(MainActivity.this, deviceName, Toast.LENGTH_LONG).show();
bluetoothNearbyDevices.add(deviceName);
}
}
};
}
And my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package">
<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>
</application>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
</manifest>
So do you have any Idea why it doesn't find any device in my app?
What version of Android are you running this on? If it is Android 6.x, I believe you need to add the ACCESS_COURSE_LOCATION permission to your manifest.
Below is how run time Permissions work Android 6.0 Marshmallow i.e:
> API level 23
For example:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
switch (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION)) {
case PackageManager.PERMISSION_DENIED:
((TextView) new AlertDialog.Builder(this)
.setTitle("Runtime Permissions up ahead")
.setMessage("To find nearby bluetooth devices please click Allow on the runtime permissions popup." )
.setNeutralButton("Okay", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(DeviceListActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_ACCESS_COARSE_LOCATION);
}
}
})
.show()
.findViewById(android.R.id.message))
.setMovementMethod(LinkMovementMethod.getInstance());
break;
case PackageManager.PERMISSION_GRANTED:
break;
}
}
I'm trying to use Data Items to send a few strings through to my wear, but my wear never seems to receive any signal, because onDataChanged() is never called. I even set a time stamp to ensure the data is always different whenever it is sent.
Is there a specific way I have to install the app onto both devices to get it to work? I'm just clicking run and selecting my phone, then switching modules and doing the same for my wear device.
Here is the code from my main activity on my phone:
public class HomeActivity extends Activity{
public static String TAG = "HomeActivity";
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.home_view);
Button mButton = (Button) findViewById(R.id.send_button);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendData();
}
});
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
}).addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}).addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
}
private void sendData(){
if (mGoogleApiClient!=null){
return;
}
final PutDataMapRequest putRequest = PutDataMapRequest.create("/SAMPLE");
final DataMap map = putRequest.getDataMap();
map.putInt("color", Color.RED);
map.putLong("date", new Date().getTime());
Wearable.DataApi.putDataItem(mGoogleApiClient, putRequest.asPutDataRequest());
}
}
And here is the code on my wearable:
public class LayoutFaceService extends CanvasWatchFaceService implements DataApi.DataListener{
#Override
public void onCreate(){
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected");
Wearable.DataApi.addListener(mGoogleApiClient, LayoutFaceService.this);
}
#Override
public void onConnectionSuspended(int i) {
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
})
.build();
mGoogleApiClient.connect();
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_DELETED) {
Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
} else if (event.getType() == DataEvent.TYPE_CHANGED) {
Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
}
}
}
And my wear manifest :
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault" >
<service
android:name=".LayoutFaceService"
android:label="#string/my_digital_name"
android:permission="android.permission.BIND_WALLPAPER" >
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/watch_face" />
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="#drawable/preview_digital" />
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="#drawable/preview_digital_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
In sendData(), your conditional seems to be incorrect; mGoogleApiClient != null is true so you exit right there. Address that and see whether you can get any further; there might be other issues but that is the first obvious one. If that didn't completely fix your issue, then make sure you also include the manifest on your phone in your post.
I have been working on a project where I need a button on a mobile to start up an activity on the watch. I have been going through the data layer sample in the sdk but can not get it working. I set up a wearable listener service class, but it is not picking up any messages. The service is added to the manifest but it is still not working. I do have other services too and I am thinking I might have too many services.
On the Wear watch, does an activity have to be running in order for it to start another activity? I want the watch to run nothing until it receives a message, is this possible?
Also, what should my edit configuration settings for wear module be? (eg, do not launch activity, launch default or launch from activity) I just want the wearable to boot up when a message is received.
If anybody can point me in the right direction, it would be hugely appreciated.
Thanks.
Moblie
Accessing the Wearable Data Layer
MainActivity.java
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
Log.d("GoogleApi", "onConnected: " + bundle);
}
#Override
public void onConnectionSuspended(int i) {
Log.d("GoogleApi", "onConnectionSuspended: " + i);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("GoogleApi", "onConnectionFailed: " + connectionResult);
}
GetConnectedNodes
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
for (Node node : getConnectedNodesResult.getNodes()) {
sendMessage(node.getId());
}
}
});
SendMessage
public static final String START_ACTIVITY_PATH = "/start/MainActivity";
private void sendMessage(String node) {
Wearable.MessageApi.sendMessage(mGoogleApiClient , node , START_ACTIVITY_PATH , new byte[0]).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e("GoogleApi", "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
}
}
});
}
Wear
Implement a Message Listener
WearDataLayerListenerService.java
public class WearDataLayerListenerService extends WearableListenerService {
public static final String START_ACTIVITY_PATH = "/start/MainActivity";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
if(messageEvent.getPath().equals(START_ACTIVITY_PATH)){
Intent intent = new Intent(this , MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}}
Add Listener Service to Manifest
<service
android:name=".WearDataLayerListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
How can i start new Activity on Accelererometer (On Shake): when i shake my phone the app crashes
- the accelerometer run also in background
public class Shaker_Service extends Service implements SensorEventListener{
private static final String TAG = "MyService";
private SensorManager sensorManager;
AppPreferences appPrefs;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service CREATED", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service STOP", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service START", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
// add listener. The listener will be HelloAndroid (this) class
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent event) {
// check sensor type
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
// assign directions
float x=event.values[0];
float y=event.values[1];
float z=event.values[2];
if (x>10){
startActivity(newIntent("com.examles.MESSAGE"));
}
}
}
}
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.examples"
android:versionCode="1"
android:versionName="1.0">
<activity android:name=".Message_Note"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="com.examples.MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".Shaker_Service" />
</application>
</manifest>
Message_Note.java :
public class Message_Note extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.message);
}
}
image of error (LogCat)
https://mega.co.nz/#!SUpTAbAC!WC9y_Xlh5GEW9AY9_5WbpXwkYA4Xk-o9WgaXvN6jpLk
Try using:
Intent intent = new Intent(this, theActivityYouWantToStart.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
This is the correct way to start an Activity from inside a service.
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>