Android Studio Ble Gatt connection writing data to a custom service characteristic - java

I am trying to write some custom data to a BLE device with a custom service on it. I have followed this tutorial: https://www.youtube.com/watch?v=vUbFB1Qypg8&feature=emb_logo which is from android.
I can see my custom service with data on it. Also via another application (NRF connect) I can write data to this custom service. Therefore, I know its possible to write data to the service.
The issue I have is other examples of how to write data to the custom service use BluetoothGatt whereas, this code seems to use BluetoothLeService instead. This is an issue as the documentation does not seem to have a read API for the BluetoothLeService. So I can not use something like mBluetoothGatt.readCharacteristic(mReadCharacteristic);
How can I go about creating a function to write a value (integer) to the characterisitic.
My UUID for the service is: "f3641400-00b0-4240-ba50-05ca45bf8abc"
My UUID for the characteristic is: "f3641401-00b0-4240-ba50-05ca45bf8abc"
For reference my code is below:
public class DeviceControlActivity extends Activity {
private final static String TAG =
DeviceControlActivity.class.getSimpleName();
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private TextView mConnectionState;
private TextView mDataField;
private EditText Command_string;
private BluetoothGatt mGatt;
private Button btn_gatt_connect;
private Button btn_live,btn_command;
private String mDeviceName;
private String mDeviceAddress;
private String User_data;
private ExpandableListView mGattServicesList;
private BluetoothLeService mBluetoothLeService;
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
private String Switch_case ="Connect";
private boolean Write_ble_command = true;
// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
// Automatically connects to the device upon successful start-up initialization.
mBluetoothLeService.connect(mDeviceAddress);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
// Handles various events fired by the Service.
// ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
// ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read
// or notification operations.
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the user interface.
displayGattServices(mBluetoothLeService.getSupportedGattServices());
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
// If a given GATT characteristic is selected, check for supported features. This sample
// demonstrates 'Read' and 'Notify' features. See
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete
// list of supported characteristic features.
private final ExpandableListView.OnChildClickListener servicesListClickListner =
new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
if (mGattCharacteristics != null) {
final BluetoothGattCharacteristic characteristic =
mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
// If there is an active notification on a characteristic, clear
// it first so it doesn't update the data field on the user interface.
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(
mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(
characteristic, true);
}
return true;
}
return false;
}
};
private void Gatt_Connect()
{
switch(Switch_case) {
case "Connect":
btn_gatt_connect.setText("Disconnect");//Presently connected allow to disconnect
mBluetoothLeService.connect(mDeviceAddress);
Switch_case = "Disconnect";
break;
case "Disconnect":
btn_gatt_connect.setText("Connect");//Presently disconnected allow to connect
mBluetoothLeService.disconnect();
Switch_case = "Connect";
break;
}
}
private void Live_data(){
//Ensure you are disconnected
btn_gatt_connect.setText("Connect");//Presently disconnected allow to connect
mBluetoothLeService.disconnect();//Might only run if connected
Switch_case = "Connect";
Intent myIntent = new Intent(DeviceControlActivity.this, MainActivity.class);
Bundle bundle = new Bundle();
bundle.putString("User_data", User_data);//Pass through the user's email address to the main activity for display
myIntent.putExtras(bundle);
DeviceControlActivity.this.startActivity(myIntent);//Run the main activity}
}
private void clearUI() {
mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
mDataField.setText(R.string.no_data);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gatt_services_characteristics);
//Get the extras passed in
Bundle bundle = getIntent().getExtras();
mDeviceName = bundle.getString("Device_Name");
mDeviceAddress = bundle.getString("Device_Address");
User_data = bundle.getString("User_data");
// Sets up UI references.
((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
Command_string = (EditText)findViewById(R.id.Command_string);
btn_gatt_connect = (Button)findViewById(R.id.btn_gatt_connect);
btn_live = (Button) findViewById(R.id.btn_live);
btn_command = (Button) findViewById(R.id.btn_command);
btn_gatt_connect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Gatt_Connect();
}
});
btn_gatt_connect.setText("Disconnect");//Presently disconnected allow to connect
btn_live.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Live_data();
}
});
btn_command.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Send_Command();//Sends the command in the text box to the nordic board
}
});
mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
mConnectionState = (TextView) findViewById(R.id.connection_state);
mDataField = (TextView) findViewById(R.id.data_value);
//setTitle(mDeviceAddress);//Change the title to Scanner as the device is no longer being read
Intent gattServiceIntent = new Intent(DeviceControlActivity.this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
final boolean result = mBluetoothLeService.connect(mDeviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
}
protected void Send_Command()
{
Write_ble_command = true;//Write command issued on display gatt service
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_services, menu);
if (mConnected) {
menu.findItem(R.id.menu_connect).setVisible(false);
menu.findItem(R.id.menu_disconnect).setVisible(true);
} else {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
mBluetoothLeService.connect(mDeviceAddress);
return true;
case R.id.menu_disconnect:
mBluetoothLeService.disconnect();
return true;
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mConnectionState.setText(resourceId);
}
});
}
private void displayData(String data) {
if (data != null) {
mDataField.setText(data);
}
}
// Demonstrates how to iterate through the supported GATT Services/Characteristics.
// In this sample, we populate the data structure that is bound to the ExpandableListView
// on the UI.
private void displayGattServices(List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
String uuid = null;
String unknownServiceString = getResources().getString(R.string.unknown_service);
String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
= new ArrayList<ArrayList<HashMap<String, String>>>();
mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
currentServiceData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
new ArrayList<HashMap<String, String>>();
List<BluetoothGattCharacteristic> gattCharacteristics =
gattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas =
new ArrayList<BluetoothGattCharacteristic>();
// Loops through available Characteristics.
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this,
gattServiceData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 },
gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 }
);
mGattServicesList.setAdapter(gattServiceAdapter);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
}

I fixed my issue by creating a function inside of the Bluetoothle service. This is where the bluetooth gatt connection is. The function is like so.
public void writeCharacteristic(int Data) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
byte[] value = intToByteArray(Data);
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("f3641400-00b0-4240-ba50-05ca45bf8abc"));
if(mCustomService == null){
Log.w(TAG, "Custom BLE Service not found");
return;
}
/*get the read characteristic from the service*/
BluetoothGattCharacteristic characteristic = mCustomService.getCharacteristic(UUID.fromString("f3641401-00b0-4240-ba50-05ca45bf8abc"));
characteristic.setValue(value);
mBluetoothGatt.writeCharacteristic(characteristic);
}
It just needs a data (Int value passing into it). Then this is received by my Bluetooth board and, can see its data on a terminal being sent correctly.

Related

How to properly pass context to AsyncTask and then to another class?

I'm working on app that will use biometric as an option to login. Before I use the actual biometric prompt I need to check one thing from server - I use AsyncTask to do it. So, to sum up - I invoke AsyncTask from Parent Activity (login.java), and then AsyncTask uses biometricUtils.java class, that makes biometric prompt. The point is, I keep passing null instead of context to biometricUtils.java:
Attempt to invoke virtual method 'java.util.concurrent.Executor android.content.Context.getMainExecutor()' on a null object reference at biometricUtils.<init>(biometricUtils.java:34)
I have no idea to pass the context correctly.
Here's my code:
login.java
public class login extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
Bundle bundle = getIntent().getExtras();
final boolean flag = false;
final String androidID = bundle.getString("androidID");
final Activity thisActivity = this;
final Context context = getApplicationContext();
// login using biometrics
Button btnBiometricLogin = findViewById(R.id.btnBiometricLogin);
btnBiometricLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkAndroidID async = new checkAndroidID(context);
async.getParentActivity(thisActivity);
async.setFlag(flag);
async.execute(androidID);
}
});
}
}
checkAndroidID.java
public class checkAndroidID extends AsyncTask <String, Void, String> {
openHTTP openHTTP = new openHTTP();
requestHTTP requests = new requestHTTP();
Activity parentActivity;
private WeakReference<Context> contextRef;
Boolean flag;
public checkAndroidID(Context context){
contextRef = new WeakReference<>(context);
}
public void getParentActivity(Activity parentActivity){
this.parentActivity = parentActivity;
}
public void setFlag (Boolean flag){
this.flag = flag;
}
#Override
protected String doInBackground(String... strings) {
try {
HttpURLConnection httpConn = openHTTP.prepareConnection("url");
String json = "{ \"androidID\": \"" + strings[0] + "\" }";
requests.sendData(json, httpConn);
return requests.receiveData(httpConn);
} catch (Exception e){
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
String[] result = s.split(";");
Context ctx = contextRef.get();
if (result[0].equals("TRUE")) flag = true;
if (!flag) Toast.makeText(parentActivity, "Biometric authentication is now unavailable." +
" Please login using username and password", Toast.LENGTH_SHORT).show();
else {
biometricUtils biometrics = new biometricUtils(ctx);
biometrics.getParentActivity(parentActivity);
biometrics.getUsername(result[1]);
biometrics.inovkeBiometricPrompt();
}
super.onPostExecute(s);
}
}
and biometricUtlis.java
public class biometricUtils {
Activity parentActivity;
String username;
Context context;
public void getParentActivity(Activity parentActivity){
this.parentActivity = parentActivity;
}
public void getUsername(String s){
this.username = s;
}
public biometricUtils(Context context){
this.context = context;
}
// creating a variable for our Executor
Executor executor = ContextCompat.getMainExecutor(context); // LINE 34
// this will give us result of AUTHENTICATION
final BiometricPrompt biometricPrompt = new BiometricPrompt((FragmentActivity) parentActivity, executor, new BiometricPrompt.AuthenticationCallback() {
#Override
public void onAuthenticationError(int errorCode, #NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
}
// THIS METHOD IS CALLED WHEN AUTHENTICATION IS SUCCESS
#Override
public void onAuthenticationSucceeded(#NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
Intent intent = new Intent(parentActivity.getApplicationContext(), tmp.class);
intent.putExtra("username", username);
parentActivity.startActivity(intent);
}
#Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
}
});
// creating a variable for our promptInfo
// BIOMETRIC DIALOG
final BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder().setTitle("Biometrical login")
.setDescription("Place your fingerprint on scanner to proceed").setNegativeButtonText("Cancel").build();
public void inovkeBiometricPrompt() {
biometricPrompt.authenticate(promptInfo);
}
}

How to fix null return from registerReceiver() in Fragment and same code was working in Activity

Problem is in the Fragment which consume the USB service and cannot register the service returning when debugging always null.
I have USB Service which is working totally fine in Activity, then I changed the code to work in fragment so i can use ViewPager ..
Now the problem that USB service is always return null and I have applied same code but it seems fragment needs other work than Activity which i still didn't catch and here's.
here's the fragment code after adding the service class and mention it in manifest.
public class RealTimeFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
TextView tvTimeStamp, tvPm25, tvPm10, tvTemp, tvHumid, tvCo2, tvTvoc, tvNoise, tvPa;
RoundCornerProgressBar pbPm25, pbPm10, pbTemp, pbHumid, pbCo2, pbTvoc, pbNoise, pbPa;
ImageView ivVent ;
public static final String TAG = "MainActivity";
private UsbService usbService;
private RealTimeFragment.MyHandler mHandler;
static String myJson = "";
static int dbCount = 0;
static ControlViewModel controlViewModel;
static View mView;
private final ServiceConnection usbConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
usbService = ((UsbService.UsbBinder) arg1).getService();
usbService.setHandler(mHandler);
usbService.changeBaudRate(9600);
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
usbService = null;
}
};
/*
* Notifications from UsbService will be received here.
*/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action!=null) {
switch (action) {
case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_NO_USB: // NO USB CONNECTED
Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
break;
}
}
}
};
public RealTimeFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static RealTimeFragment newInstance(int sectionNumber) {
RealTimeFragment fragment = new RealTimeFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.realtime_layout_fragment, container, false);
tvTimeStamp = rootView.findViewById(R.id.tv_serial_output);
tvPm25 = rootView.findViewById(R.id.tv_pm25);
pbPm25 = rootView.findViewById(R.id.pb_pm25);
tvPm10 = rootView.findViewById(R.id.tv_pm10);
pbPm10 = rootView.findViewById(R.id.pb_pm10);
tvTemp = rootView.findViewById(R.id.tv_temp);
pbTemp = rootView.findViewById(R.id.pb_temp);
tvHumid = rootView.findViewById(R.id.tv_humid);
pbHumid = rootView.findViewById(R.id.pb_humid);
tvCo2 = rootView.findViewById(R.id.tv_co2);
pbCo2 = rootView.findViewById(R.id.pb_co2);
tvTvoc = rootView.findViewById(R.id.tv_tvoc);
pbTvoc = rootView.findViewById(R.id.pb_tvoc);
tvNoise = rootView.findViewById(R.id.tv_noise);
pbNoise = rootView.findViewById(R.id.pb_noise);
tvPa = rootView.findViewById(R.id.tv_pressure);
pbPa = rootView.findViewById(R.id.pb_pressure);
ivVent = rootView.findViewById(R.id.iv_vent);
mHandler = new RealTimeFragment.MyHandler(getActivity());
//assert getArguments() != null;
//textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
this.mView = rootView;
setFilters(); // Start listening notifications from UsbService
startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
return rootView;
}
#Override
public void onResume() {
super.onResume();
// setFilters(); // Start listening notifications from UsbService
// startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
}
#Override
public void onPause() {
super.onPause();
usbService.unregisterReceiver(mUsbReceiver);
usbService.unbindService(usbConnection);
}
private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
if (!UsbService.SERVICE_CONNECTED) {
Intent startService = new Intent(getContext(), service);
if (extras != null && !extras.isEmpty()) {
Set<String> keys = extras.keySet();
for (String key : keys) {
String extra = extras.getString(key);
startService.putExtra(key, extra);
}
}
usbService.startService(startService);
}
Intent bindingIntent = new Intent(getContext(), service);
usbService.bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void setFilters() {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
filter.addAction(UsbService.ACTION_NO_USB);
filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
Log.e("startService",mUsbReceiver.toString());
usbService.registerReceiver(mUsbReceiver, filter);
// LocalBroadcastManager.getInstance(usbService).registerReceiver(mUsbReceiver, filter);
}
/*
* This handler will be passed to UsbService. Data received from serial port is displayed through this handler
*/
private static class MyHandler extends Handler {
private final WeakReference<Activity> mActivity;
private MyHandler(Activity activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UsbService.MESSAGE_FROM_SERIAL_PORT:
String buffer = (String) msg.obj;
myJson += buffer;
if (buffer.indexOf('}') >= 0) {
try {
Data responseBegin = new Gson().fromJson(myJson, Data.class);
SystemControl systemControl = new SystemControl(responseBegin.getStaticFilter() == 1 ? true:false, responseBegin.getAutoVent() == 1 ? true:false, responseBegin.getFanSpeed());
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
controlViewModel.getSystemControl().postValue(systemControl);
updateUI(responseBegin);
myJson = "";
} catch (Exception e) {
myJson = "";
}
}
break;
case UsbService.CTS_CHANGE:
Toast.makeText(mActivity.get(), "CTS_CHANGE", Toast.LENGTH_LONG).show();
break;
case UsbService.DSR_CHANGE:
Toast.makeText(mActivity.get(), "DSR_CHANGE", Toast.LENGTH_LONG).show();
break;
case UsbService.SYNC_READ:
String buffer2 = (String) msg.obj;
myJson += buffer2;
if (buffer2.indexOf('}') >= 0) {
try {
Data responseBegin = new Gson().fromJson(myJson, Data.class);
SystemControl systemControl = new SystemControl(responseBegin.getStaticFilter() == 1 ? true:false, responseBegin.getAutoVent() == 1 ? true:false, responseBegin.getFanSpeed());
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer. controlViewModel.getSystemControl().postValue(systemControl);
updateUI(responseBegin);
myJson = "";
} catch (Exception e) {
myJson = "";
}
}
break;
}
}
}
}
This is because you're calling:
usbService.registerReceiver(mUsbReceiver, filter);
before starting the service, which you have done in the following line:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
setFilters(); // Start listening notifications from UsbService
startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
return rootView;
}
So, you just need to flip the code to solve the problem:
startService(UsbService.class, usbConnection, null);
setFilters();

Having issue in custom adapter listview

import org.alljoyn.bus.sample.chat.ChatApplication;
import org.alljoyn.bus.sample.chat.Observable;
import org.alljoyn.bus.sample.chat.Observer;
import org.alljoyn.bus.sample.chat.DialogBuilder;
import java.lang.reflect.Array;
// ... more imports
public class UseActivity extends Activity implements Observer {
private static final String TAG = "chat.UseActivity";
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.use);
ListView hlv = (ListView) findViewById(R.id.useHistoryList);
hlv.setAdapter(mHistoryList);
EditText messageBox = (EditText)findViewById(R.id.useMessage);
messageBox.setSingleLine();
messageBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
message = view.getText().toString();
Log.i(TAG, "useMessage.onEditorAction(): got message " + message + ")");
mHistoryList.add(message);
mChatApplication.newLocalUserMessage(message);
view.setText("");
}
return true;
}
});
Button mAlertButton = (Button)findViewById(R.id.alert);
mAlertButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = "www.google.com" ;
mHistoryList.add(message);
mChatApplication.newLocalUserMessage(message);
}
});
mJoinButton = (Button)findViewById(R.id.useJoin);
mJoinButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_JOIN_ID);
}
});
mLeaveButton = (Button)findViewById(R.id.useLeave);
mLeaveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_LEAVE_ID);
}
});
mChannelName = (TextView)findViewById(R.id.useChannelName);
mChannelStatus = (TextView)findViewById(R.id.useChannelStatus);
/*
* Keep a pointer to the Android Application class around. We use this
* as the Model for our MVC-based application. Whenever we are started
* we need to "check in" with the application so it can ensure that our
* required services are running.
*/
mChatApplication = (ChatApplication)getApplication();
mChatApplication.checkin();
/*
* Call down into the model to get its current state. Since the model
* outlives its Activities, this may actually be a lot of state and not
* just empty.
*/
updateChannelState();
updateHistory();
/*
* Now that we're all ready to go, we are ready to accept notifications
* from other components.
*/
mChatApplication.addObserver(this);
}
public void onDestroy() {
Log.i(TAG, "onDestroy()");
mChatApplication = (ChatApplication)getApplication();
mChatApplication.deleteObserver(this);
super.onDestroy();
}
public static final int DIALOG_JOIN_ID = 0;
public static final int DIALOG_LEAVE_ID = 1;
public static final int DIALOG_ALLJOYN_ERROR_ID = 2;
protected Dialog onCreateDialog(int id) {
Log.i(TAG, "onCreateDialog()");
Dialog result = null;
switch(id) {
case DIALOG_JOIN_ID:
{
DialogBuilder builder = new DialogBuilder();
result = builder.createUseJoinDialog(this, mChatApplication);
}
break;
case DIALOG_LEAVE_ID:
{
DialogBuilder builder = new DialogBuilder();
result = builder.createUseLeaveDialog(this, mChatApplication);
}
break;
case DIALOG_ALLJOYN_ERROR_ID:
{
DialogBuilder builder = new DialogBuilder();
result = builder.createAllJoynErrorDialog(this, mChatApplication);
}
break;
}
return result;
}
public synchronized void update(Observable o, Object arg) {
Log.i(TAG, "update(" + arg + ")");
String qualifier = (String)arg;
if (qualifier.equals(ChatApplication.APPLICATION_QUIT_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_APPLICATION_QUIT_EVENT);
mHandler.sendMessage(message);
}
if (qualifier.equals(ChatApplication.HISTORY_CHANGED_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_HISTORY_CHANGED_EVENT);
mHandler.sendMessage(message);
}
if (qualifier.equals(ChatApplication.USE_CHANNEL_STATE_CHANGED_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_CHANNEL_STATE_CHANGED_EVENT);
mHandler.sendMessage(message);
}
if (qualifier.equals(ChatApplication.ALLJOYN_ERROR_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_ALLJOYN_ERROR_EVENT);
mHandler.sendMessage(message);
}
}
private void updateHistory() {
Log.i(TAG, "updateHistory()");
List <String> messages = mChatApplication.getHistory();
mHistoryList = new SimpleAdapter (this, messages);
for (String message : messages) {
mHistoryList.add(message);
}
mHistoryList.notifyDataSetChanged();
}
private void updateChannelState() {
Log.i(TAG, "updateHistory()");
AllJoynService.UseChannelState channelState = mChatApplication.useGetChannelState();
String name = mChatApplication.useGetChannelName();
if (name == null) {
name = "Not set";
}
mChannelName.setText(name);
switch (channelState) {
case IDLE:
mChannelStatus.setText("Idle");
mJoinButton.setEnabled(true);
mLeaveButton.setEnabled(false);
break;
case JOINED:
mChannelStatus.setText("Joined");
mJoinButton.setEnabled(false);
mLeaveButton.setEnabled(true);
break;
}
}
/**
* An AllJoyn error has happened. Since this activity pops up first we
* handle the general errors. We also handle our own errors.
*/
private void alljoynError() {
if (mChatApplication.getErrorModule() == ChatApplication.Module.GENERAL ||
mChatApplication.getErrorModule() == ChatApplication.Module.USE) {
showDialog(DIALOG_ALLJOYN_ERROR_ID);
}
}
private static final int HANDLE_APPLICATION_QUIT_EVENT = 0;
private static final int HANDLE_HISTORY_CHANGED_EVENT = 1;
private static final int HANDLE_CHANNEL_STATE_CHANGED_EVENT = 2;
private static final int HANDLE_ALLJOYN_ERROR_EVENT = 3;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLE_APPLICATION_QUIT_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_APPLICATION_QUIT_EVENT");
finish();
}
break;
case HANDLE_HISTORY_CHANGED_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_HISTORY_CHANGED_EVENT");
updateHistory();
break;
}
case HANDLE_CHANNEL_STATE_CHANGED_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_CHANNEL_STATE_CHANGED_EVENT");
updateChannelState();
break;
}
case HANDLE_ALLJOYN_ERROR_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_ALLJOYN_ERROR_EVENT");
alljoynError();
break;
}
default:
break;
}
}
};
private ChatApplication mChatApplication = null;
String message;
private SimpleAdapter mHistoryList;
private Button mJoinButton;
private Button mLeaveButton;
private TextView mChannelName;
private TextView mChannelStatus;
}
I'm having some troubles getting my custom listView adapter to work. I am having issue in getting the message values dynamically into the custom adapter. I have got the values dynamically but when I used that in my code, the app crashes or it displays nothing.
import android.text.util.Linkify;
// ... more imports
public class SimpleAdapter extends ArrayAdapter<String> {
private final Context context;
private final List<String> values;
public SimpleAdapter(Context context, List <String> values) {
super(context, -1, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.view, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.text);
textView.setText(values.get(position));
Linkify.addLinks(textView,Linkify.WEB_URLS);
return rowView;
}
}

how to solve android service has leaked error

I have an activity that calls a service on its onCreate , however when I try yo run the project I keep getting an error saying the service has leaked and longer bound on the activity that called/registered it .
"Activity com.xera.deviceinsight.home.DataUsageActivity has leaked ServiceConnection com.xera.deviceinsight.home.DataUsageActivity$3#42676a48 that was originally bound here" I am assuming this might have something to do with the lifecycle of the activity . I have both the activity and the service in question below
myActivity
public class DataUsageActivity extends AppCompatActivity implements MonitorService.ServiceCallback
{
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TinyDB settings = new TinyDB(this);
if (settings.getBoolean(AppPreferences.HAS_LOGGED_IN))
{
this.bindService(
new Intent(this, MonitorService.class),
serviceConnection,
Context.BIND_AUTO_CREATE);
return;
}
}
public void sendResults(int resultCode, Bundle b)
{
// adapter.notifyDataSetChanged();
}
private ServiceConnection serviceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName className, IBinder service)
{
MonitorService.LocalBinder binder = (MonitorService.LocalBinder)service;
backgroundService = binder.getService();
backgroundService.setCallback(DataUsageActivity.this);
backgroundService.start();
}
#Override
public void onServiceDisconnected(ComponentName className)
{
backgroundService = null;
}
};
#Override
public void onResume()
{
super.onResume();
if(backgroundService != null)
{
backgroundService.setCallback(this);
}
}
#Override
public void onPause()
{
super.onPause();
if(backgroundService != null)
{
backgroundService.setCallback(null);
}
}
}
**myService**
public class MonitorService extends Service
{
private boolean initialized = false;
private final IBinder mBinder = new LocalBinder();
private ServiceCallback callback = null;
private Timer timer = null;
private final Handler mHandler = new Handler();
private String foreground = null;
private ArrayList<HashMap<String,Object>> processList;
private ArrayList<String> packages;
private Date split = null;
// private Date startTime = null;
public int timeCheckVariable = 0 ;
public static int SERVICE_PERIOD = 5000; // TODO: customize (this is for scan every 5 seconds)
private final ProcessList pl = new ProcessList(this)
{
#Override
protected boolean isFilteredByName(String pack)
{
// TODO: filter processes by names, return true to skip the process
// always return false (by default) to monitor all processes
return false;
}
};
public interface ServiceCallback
{
void sendResults(int resultCode, Bundle b);
}
public class LocalBinder extends Binder
{
MonitorService getService()
{
// Return this instance of the service so clients can call public methods
return MonitorService.this;
}
}
#Override
public void onCreate()
{
super.onCreate();
initialized = true;
processList = ((DeviceInsightApp)getApplication()).getProcessList();
packages = ((DeviceInsightApp)getApplication()).getPackages();
}
#Override
public IBinder onBind(Intent intent)
{
if(initialized)
{
return mBinder;
}
return null;
}
public void setCallback(ServiceCallback callback)
{
this.callback = callback;
}
// private boolean addToStatistics(String target , Long startTime)
private boolean addToStatistics(String target )
{
boolean changed = false;
Date now = new Date();
if(!TextUtils.isEmpty(target))
{
if(!target.equals(foreground))
{
int i;
// timeCheckVariable = i ;
if(foreground != null && split != null)
{
// TODO: calculate time difference from current moment
// to the moment when previous foreground process was activated
i = packages.indexOf(foreground);
timeCheckVariable = i ;
long delta = (now.getTime() - split.getTime()) / 1000;
Long time = (Long)processList.get(i).get(ProcessList.COLUMN_PROCESS_TIME);
if(time != null)
{
// TODO: add the delta to statistics of 'foreground'
time += delta;
}
else
{
time = new Long(delta);
}
processList.get(i).put(ProcessList.COLUMN_PROCESS_TIME, time);
//String applicationName = (String)processList.get(i).get(ProcessList.COLUMN_PROCESS_NAME);
// DatabaseHandler db = new DatabaseHandler(this);
// int x = time.intValue( );
// db.addAppRecord(new AppUsageClass(applicationName , x));
// db.getApplicationCount();
// List<AppUsageClass> appUsageClass = db.getAllApplications();
// db.getApplicationCount();
// for (AppUsageClass cn : appUsageClass) {
//String log = "Id: " + cn.getID() + " ,ApplicationName : " + cn.getName() + " ,TimeSpent: " + cn.getTimeSpent();
// Log.d("Name: ", log);
//}
}
//update count of process activation for new 'target'
i = packages.indexOf(target);
Integer count = (Integer)processList.get(i).get(ProcessList.COLUMN_PROCESS_COUNT);
if(count != null) count++;
else
{
count = new Integer(1);
}
processList.get(i).put(ProcessList.COLUMN_PROCESS_COUNT, count);
foreground = target;
split = now;
changed = true;
}
}
//Long checkTimeNow = (Long)processList.get(timeCheckVariable).get(ProcessList.COLUMN_PROCESS_TIME);
return changed;
}
public void start()
{
if(timer == null)
{
timer = new Timer();
timer.schedule(new MonitoringTimerTask(), 500, SERVICE_PERIOD);
}
// TODO: startForeground(srvcid, createNotification(null));
}
public void stop()
{
timer.cancel();
timer.purge();
timer = null;
}
private class MonitoringTimerTask extends TimerTask
{
#Override
public void run()
{
fillProcessList();
ActivityManager activityManager = (ActivityManager)MonitorService.this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = activityManager.getRunningTasks(1);
String current = taskInfo.get(0).topActivity.getPackageName(); // gets the application which is in the foreground
int i = packages.indexOf(current);
Long timecheck = (Long)processList.get(i).get(ProcessList.COLUMN_PROCESS_TIME);
if(addToStatistics(current)&& callback != null)
{
final Bundle b = new Bundle();
// TODO: pass necessary info to UI via bundle
mHandler.post(new Runnable()
{
public void run()
{
callback.sendResults(1, b);
}
});
}
}
}
private void fillProcessList()
{
pl.fillProcessList(processList, packages);
}
The problem is that you don't unbind from you service in .onPause() or in .onDestroy(), so if you Activity is destroyed, connection still last, so there is leaked connection. If you want you service to run all the time, you should start it by .startService() and then bind to it. In .onStop() or .onDestroy() unbind from that service

Call a "void" method that have values from another activity

Hi I'm quite new to Java, I wonder how to call a void method from another activity, when I already moved to new activity. For example, I want to call
onCreate(Bundle state)
from PocketSphinxActivty.java
in my new activity SMSReaderMain.java
I already tried
PocketSphinxActivity ps = new PocketSphinxActivity();
ps.onCreate(null);
It gives no error, but when SMSReaderMain.java activity start it suddenly force close and not responding in the actual device.
I also try to change into ps.onCreate(this) or ps.onCreate(SMSReaderMain.this) but it gives
The method setupRecognizer(File) in the type PocketSphinxActivity is not applicable for the arguments
(SMSReaderMain)
Here's the complete code, and I want to call almost all of method there in my new activity SMSReaderMain.java
PocketSphinxActivity.java
package edu.cmu.pocketsphinx.demo;
public class PocketSphinxActivity extends Activity implements
RecognitionListener {
//keyword yang digunakan dalem program untuk set ke even2 tertentu
private static final String KWS_SEARCH = "wakeup";
private static final String FORECAST_SEARCH = "forecast";
private static final String DIGITS_SEARCH = "drive mode";
private static final String MENU_SEARCH = "menu";
private static final String KEYPHRASE = "ok";
private SpeechRecognizer recognizer;
private HashMap<String, Integer> captions;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
// Buat nyiapin User Interface
captions = new HashMap<String, Integer>();
captions.put(KWS_SEARCH, R.string.kws_caption);
captions.put(MENU_SEARCH, R.string.menu_caption);
//captions.put(DIGITS_SEARCH, R.string.digits_caption);
captions.put(FORECAST_SEARCH, R.string.forecast_caption);
setContentView(R.layout.main);
((TextView) findViewById(R.id.caption_text))
.setText("Preparing the recognizer");
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(PocketSphinxActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) findViewById(R.id.caption_text))
.setText("Failed to init recognizer " + result);
} else {
switchSearch(KWS_SEARCH);
}
}
}.execute();
}
//nyocokin keyword dan pindah2 menu
#Override
public void onPartialResult(Hypothesis hypothesis) {
String text = hypothesis.getHypstr();
try {
Intent i= null;
if (text.equals(KEYPHRASE)) {
switchSearch(MENU_SEARCH);
}
if (text.equals(DIGITS_SEARCH)) {
//panggil class SMSReaderMain
recognizer.stop();
i = new Intent(getApplicationContext(),SMSReaderMain.class);
startActivity(i);
}
if (text.equals(FORECAST_SEARCH)) {
switchSearch(FORECAST_SEARCH);
}
//else
//((TextView) findViewById(R.id.result_text)).setText(text);
} catch (Exception e) {
e.printStackTrace();
}
}
//nge pop up keyword yang sesuai kita ucapin sama library yg udah ada
#Override
public void onResult(Hypothesis hypothesis) {
((TextView) findViewById(R.id.result_text)).setText("");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBeginningOfSpeech() {
}
//kembali ke menu utama
/*#Override
public void onEndOfSpeech() {
if (DIGITS_SEARCH.equals(recognizer.getSearchName())
|| FORECAST_SEARCH.equals(recognizer.getSearchName()))
switchSearch(KWS_SEARCH);
}**/
//nampilin caption yg di mau sesuai dengan keyword
public void switchSearch(String searchName) {
recognizer.stop();
recognizer.startListening(searchName);
String caption = getResources().getString(captions.get(searchName));
((TextView) findViewById(R.id.caption_text)).setText(caption);
}
//inisiasi recognizer di awal
public void setupRecognizer(File assetsDir) {
File modelsDir = new File(assetsDir, "models");
recognizer = defaultSetup()
.setAcousticModel(new File(modelsDir, "hmm/en-us-semi"))
.setDictionary(new File(modelsDir, "dict/cmu07a.dic"))
.setRawLogDir(assetsDir).setKeywordThreshold(1e-20f)
.getRecognizer();
recognizer.addListener(this);
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
// Create grammar-based searches.
File menuGrammar = new File(modelsDir, "grammar/mulai.gram");
recognizer.addGrammarSearch(MENU_SEARCH, menuGrammar);
//File digitsGrammar = new File(modelsDir, "grammar/digits.gram");
//recognizer.addGrammarSearch(DIGITS_SEARCH, digitsGrammar);
// Create language model search.
File languageModel = new File(modelsDir, "lm/weather.dmp");
recognizer.addNgramSearch(FORECAST_SEARCH, languageModel);
}
#Override
public void onEndOfSpeech() {
// TODO Auto-generated method stub
}
}
SMSReaderMAin.java
public class SMSReaderMain extends Activity {
private final int CHECK_CODE = 0x1;
private final int LONG_DURATION = 5000;
private final int SHORT_DURATION = 1200;
private Speaker speaker;
private ToggleButton toggle;
private OnCheckedChangeListener toggleListener;
private TextView smsText;
private TextView smsSender;
private BroadcastReceiver smsReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//PocketSphinxActivity ps = new PocketSphinxActivity();
//ps.setupRecognizer(null);
//ps.onPartialResult(null);
//ps.onResult(null);
//ps.switchSearch(null);
setContentView(R.layout.main_sms);
//recognizer.startListening(searchName);
toggle = (ToggleButton)findViewById(R.id.speechToggle);
smsText = (TextView)findViewById(R.id.sms_text);
smsSender = (TextView)findViewById(R.id.sms_sender);
toggleListener = new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton view, boolean isChecked) {
if(isChecked){
speaker.allow(true);
speaker.speak(getString(R.string.start_speaking));
}else{
speaker.speak(getString(R.string.stop_speaking));
speaker.allow(false);
}
}
};
toggle.setOnCheckedChangeListener(toggleListener);
checkTTS();
initializeSMSReceiver();
registerSMSReceiver();
}
private void checkTTS(){
Intent check = new Intent();
check.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(check, CHECK_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == CHECK_CODE){
if(resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS){
speaker = new Speaker(this);
}else {
Intent install = new Intent();
install.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(install);
}
}
}
private void initializeSMSReceiver(){
smsReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if(bundle!=null){
Object[] pdus = (Object[])bundle.get("pdus");
for(int i=0;i<pdus.length;i++){
byte[] pdu = (byte[])pdus[i];
SmsMessage message = SmsMessage.createFromPdu(pdu);
String text = message.getDisplayMessageBody();
String sender = getContactName(message.getOriginatingAddress());
speaker.pause(LONG_DURATION);
speaker.speak("You have a new message from" + sender + "!");
speaker.pause(SHORT_DURATION);
speaker.speak(text);
smsSender.setText("Message from " + sender);
smsText.setText(text);
}
}
}
};
}
private void registerSMSReceiver() {
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsReceiver, intentFilter);
}
private String getContactName(String phone){
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
String projection[] = new String[]{ContactsContract.Data.DISPLAY_NAME};
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
if(cursor.moveToFirst()){
return cursor.getString(0);
}else {
return "unknown number";
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(smsReceiver);
speaker.destroy();
}
}
This is a really wrong approach to the way of programming in Android. Activities are one of the main core components in an Android application that is managed directly by the OS, which means that the system creates them and are managed by the OS. The onCreate method is part of the lifecycle and it is automatically called by the system. Here you have the activity's lifecycle.
The way of starting a new activity is:
Intent intent = new Intent(mContext, MyActivity.class);
startActivity(intent);
As the activity is instanciated by the system, you cannot call directly to methods on it. The way of communicating between activities is by providing bundle objects in the intent, so in the new Activity you can get the data from:
getIntent().getExtras()
You can also provide backward information by using startActivityForResult instead of startActivity, receiving a result in onActivityResult.
You have the info you need here.
Activity corresponds to something you are going to display on screen. If you are not going to display anything, don't create activities.
In this example you do not need PocketsphinxActivity at all. You can move all the methods of PocketsphinxActivity into your SMSReaderMain activity.
If you want to separate speech recognition code into separate class you can create a separate PocketsphinxRecognizer class but inherit it from Object, not from the Activity.

Categories