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

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.

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 should I start a new Activity, after the application is done fetching and passing the fetched data to it?

In my app, I use a Contacts database and display those contacts using a RecyclerView . When I click on a contact, I want to fetch its data from the tables in the DB, and load them in a new Activity, ContactCard. I have an AsyncTask() which fetches the PhoneNumber objects that match the selected contactId, but I will also need to retrieve the Address and Email objects from the other tables.
I would like to be able to start the activity after all the relevant data is fetched, and I tried doing this in the activity with the Contacts RecyclerView, but the application crashes as the data has not been fetched yet.
I can call the new activity using an intent, but how can I ensure data from different tables is fetched first, before I start the new activity (which effectively displays this data)?
Some of my code:
public class PhoneNumberRepository {
private WorksideDatabase worksideDatabase;
private List<PhoneNumber> returnedNumbers;
private Context mContext;
public PhoneNumberRepository(Context context) {
String DB_NAME = "workside_database";
worksideDatabase = Room.databaseBuilder(context, WorksideDatabase.class, DB_NAME).build();
mContext = context;
}
public List<PhoneNumber> fetchPhoneNumbers(final int id) {
new AsyncTask<Integer, Void, List<PhoneNumber>>() {
#Override
protected List<PhoneNumber> doInBackground(Integer... ids) {
returnedNumbers = worksideDatabase.phoneNumberDao().getPhoneNumbersById(id);
System.out.println(returnedNumbers);
for (PhoneNumber pn : returnedNumbers) {
System.out.println("Number: " + pn.getPhoneNumber());
}
return returnedNumbers;
}
// This runs in UI when background thread finishes
#Override
protected void onPostExecute(List<PhoneNumber> result) {
super.onPostExecute(result);
System.out.println("Entered onPostExecute of fetchPhoneNumbers");
// for (PhoneNumber pn : result) {
// Toast.makeText(mContext, pn + "", Toast.LENGTH_SHORT).show();
// }
}
}.execute();
return returnedNumbers;
}
public List<PhoneNumber> getPhoneNumbers(int id) {
return fetchPhoneNumbers(id);
}
}
ContactsFragment:
adapter.setOnItemClickListener(
contact -> {
Intent viewContact = new Intent(getActivity(), WorksideContactCard.class);
viewContact.putExtra(WORKSIDE_CONTACT, contact);
PhoneNumberRepository phoneNumberRepository =
new PhoneNumberRepository(getActivity().getApplicationContext());
List<PhoneNumber> phoneNumberList;
phoneNumberList = phoneNumberRepository.getPhoneNumbers(contact.getId());
ArrayList<PhoneNumber> arrlistPhoneNumbers =
new ArrayList<>(phoneNumberList);
viewContact.putParcelableArrayListExtra(
WORKSIDE_CONTACT_PHONE_NO, arrlistPhoneNumbers);
startActivity(viewContact);
}
You can do this when you click on an item start the asyntask like this
adapter.setOnItemClickListener(
contact -> {
PhoneNumberRepository phoneNumberRepository =
new PhoneNumberRepository(getActivity().getApplicationContext());
List<PhoneNumber> phoneNumberList;
phoneNumberRepository.getPhoneNumbers(contact.getId());
}
and change your PhoneNumberRepository to this class
public class PhoneNumberRepository {
private WorksideDatabase worksideDatabase;
private List<PhoneNumber> returnedNumbers;
private Context mContext;
public PhoneNumberRepository(Context context) {
String DB_NAME = "workside_database";
worksideDatabase = Room.databaseBuilder(context, WorksideDatabase.class, DB_NAME).build();
mContext = context;
}
public void fetchPhoneNumbers(final int id) {
new AsyncTask<Integer, Void, List<PhoneNumber>>() {
#Override
protected List<PhoneNumber> doInBackground(Integer... ids) {
returnedNumbers = worksideDatabase.phoneNumberDao().getPhoneNumbersById(id);
System.out.println(returnedNumbers);
for (PhoneNumber pn : returnedNumbers) {
System.out.println("Number: " + pn.getPhoneNumber());
}
return returnedNumbers;
}
// This runs in UI when background thread finishes
#Override
protected void onPostExecute(List<PhoneNumber> result) {
super.onPostExecute(result);
Intent viewContact = new Intent(context, WorksideContactCard.class);
ArrayList<PhoneNumber> arrlistPhoneNumbers =
new ArrayList<>(result);
viewContact.putParcelableArrayListExtra(
WORKSIDE_CONTACT_PHONE_NO, arrlistPhoneNumbers);
context.startActivity(viewContact);
System.out.println("Entered onPostExecute of fetchPhoneNumbers");
}
}.execute();
}
public void getPhoneNumbers(int id) {
return fetchPhoneNumbers(id);
}
}
store the contacts in a list in the doInBackground() method and start an intent to the new activity in the onPostExecute() method and with this intent pass the list of contacts as intent.extra() variables, retrieve and use them in the called activity.
Change your repository class to something like this
public class PhoneNumberRepository {
private WorksideDatabase worksideDatabase;
private List<PhoneNumber> returnedNumbers;
private Context mContext;
private boolean dataDownloaded;
public PhoneNumberRepository(Context context) {
String DB_NAME = "workside_database";
worksideDatabase = Room.databaseBuilder(context, WorksideDatabase.class, DB_NAME).build();
mContext = context;
}
public List<PhoneNumber> fetchPhoneNumbers(final int id) {
new AsyncTask<Integer, Void, List<PhoneNumber>>() {
#Override
protected List<PhoneNumber> doInBackground(Integer... ids) {
returnedNumbers = worksideDatabase.phoneNumberDao().getPhoneNumbersById(id);
System.out.println(returnedNumbers);
for (PhoneNumber pn : returnedNumbers) {
System.out.println("Number: " + pn.getPhoneNumber());
}
return returnedNumbers;
}
// This runs in UI when background thread finishes
#Override
protected void onPreExecute(List<PhoneNumber> result) {
//set flag to false when download starts
dataDownloaded = false;
}
// This runs in UI when background thread finishes
#Override
protected void onPostExecute(Object obj) {
super.onPostExecute(result);
//set flag to true once download completes, you can also check if response is null and update it accordingly
dataDownloaded = true;
System.out.println("Entered onPostExecute of fetchPhoneNumbers");
// for (PhoneNumber pn : result) {
// Toast.makeText(mContext, pn + "", Toast.LENGTH_SHORT).show();
// }
}
}.execute();
return returnedNumbers;
}
public List<PhoneNumber> getPhoneNumbers(int id) {
return fetchPhoneNumbers(id);
}
public boolean isDataDownloaded(int id) {
return dataDownloaded;
}
}
Use this function in onItemClick() whether your data is downloaded or not
if(phoneNumberRepository.isDataDownloaded()) {
//code to fetch data from phonenumberrepo and start activity
}

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

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.

android.content.Context.getPackageName()' on a null object reference, when trying to access a method in an activity through a java class

I am running a basic Face detection app in real time, and im counting the number of times it detects a face in the FaceDetectionProcessor.java class ( used this as reference --> https://github.com/firebase/quickstart-android/tree/master/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/java ) and at a particular count value it makes an object of the Activity using the FaceDetectionProcessor.java object to call a method to start a new activity, and there it crashes.
tried FaceDetectActivity.this, simply this, getApplicationContext(), even a global Context object which sets its value to "this" in the onCreate() of the FaceDetectActivity
public class FaceDetectActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback,CompoundButton.OnCheckedChangeListener{
private static final String FACE_DETECTION = "Face Detection";
private static final String TAG = "LivePreviewActivity";
private static final int PERMISSION_REQUESTS = 1;
private CameraSource cameraSource = null;
private CameraSourcePreview preview;
private GraphicOverlay graphicOverlay;
private String selectedModel = FACE_DETECTION;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.
.
.
.
}
private void createCameraSource(String model) {
// If there's no existing cameraSource, create one.
if (cameraSource == null) {
cameraSource = new CameraSource(this, graphicOverlay);
}
try {
switch (model) {
case FACE_DETECTION:
Log.i(TAG, "Using Face Detector Processor");
cameraSource.setMachineLearningFrameProcessor(new FaceDetectionProcessor());
break;
default:
Log.e(TAG, "Unknown model: " + model);
}
} catch (Exception e) {
Log.e(TAG, "can not create camera source: " + model);
}
}
public void alertAndMove(){
Intent i=new Intent(FaceDetectActivity.this,SelectingParty.class);
startActivity(i);
}
public class FaceDetectionProcessor extends VisionProcessorBase<List<FirebaseVisionFace>> {
int count=0;
private static final String TAG = "FaceDetectionProcessor";
private final FirebaseVisionFaceDetector detector;
public FaceDetectionProcessor() {
FirebaseVisionFaceDetectorOptions options =
new FirebaseVisionFaceDetectorOptions.Builder()
.setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
.enableTracking()
.build();
detector = FirebaseVision.getInstance().getVisionFaceDetector(options);
}
.
.
.
.
.
.
.
#Override
protected void onSuccess(
#NonNull List<FirebaseVisionFace> faces,
#NonNull FrameMetadata frameMetadata,
#NonNull GraphicOverlay graphicOverlay) {
graphicOverlay.clear();
for (int i = 0; i < faces.size(); ++i) {
FirebaseVisionFace face = faces.get(i);
FaceGraphic faceGraphic = new FaceGraphic(graphicOverlay);
graphicOverlay.add(faceGraphic);
faceGraphic.updateFace(face, frameMetadata.getCameraFacing());
Log.d(TAG, "onSuccess: Face detected and count= "+count);
count++;
if(count>=15)
new FaceDetectActivity().alertAndMove();
}
}
#Override
protected void onFailure(#NonNull Exception e) {
Log.e(TAG, "Face detection failed " + e);
}
}
when new FaceDetectActivity().alertAndMove() is called, the app crashes in alertAndMove() at the line Intent i=new Intent(FaceDetectActivity.this,......)
What's immensely frustrating about the situation, is that the same logic worked on the same code, on my friends laptop where I had initially tested the logic.
In the FaceDetectActivity I sent the Intent and context to FaceDetectionProcessor.java:
case FACE_DETECTION:
Log.i(TAG, "Using Face Detector Processor");
Intent i=new Intent( this,SelectingParty.class);
cameraSource.setMachineLearningFrameProcessor(new FaceDetectionProcessor(this,i));
break;
And in the constructor of the FaceDetectionProcessor.java I initialized the instance Context obj and Intent intent as follows:
public FaceDetectionProcessor(Context obj, Intent intent) {
this.obj=obj;
this.intent=intent;
.
.
.
Finally in the onSuccess method in FaceDetectionProcessor.java I did:
if(count>=15){
obj.startActivity(intent);
}
That's it ! I However still can't close the previous activities, any comments suggesting how I could achieve would be of great help !
P.S. I tried CLEAR_TASK, CLEAR_TOP, NEW_TASK, didn't work, but I could be missing something.

Refresh list from within Custom Array Adapter

I've taken a look at most of the questions discussing this but can't seem to find anything that fixes my problem. I have a Custom Array adapter passing data to a list and i need the list to refresh once I've deleted an item, I understand that notifyDataSetChanged() should be my solution but have yet to make it work
sorry for my messy code
but i'm still learning :)
any help would be appreciated, thanx :)
My Adapter:
public class CustomBasketAdapter extends ArrayAdapter<String>
{
private String TAG ="Vik";
public String stringEmail= "";
public String stringStore= "";
private String product = "";
private String quantity = "";
private String store = "";
//String[] stringEmail={"stefan.grobler#gmail.com"};
private final Activity context;
private final String[] storename;
private final String[] itemprice;
private final String[] itemname;
private final String[] productquantity;
private final String[] basketlinetotal;
//public CustomListAdapter(Activity context, String[] itemname,String[] itemprice, Integer[] imgid) {
public CustomBasketAdapter(Activity context, String[] storename,String[] itemprice, String[] productquantity, String[] itemname, String[] basketlinetotal ) {
super(context, R.layout.viewbasket_layout, storename);
// TODO Auto-generated constructor stub
this.context=context;
this.storename=storename;
this.itemprice=itemprice;
this.itemname=itemname;
this.productquantity=productquantity;
this.basketlinetotal=basketlinetotal;
Intent intent = ((Activity) context).getIntent();
if (null != intent)
{
stringEmail = intent.getStringExtra("EmailAddress");
stringStore = intent.getStringExtra("StoreDescription");
}
Toast toast = Toast.makeText(getContext(),stringEmail, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 10);
//toast.show();
}
public View getView(int position,View view,ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.viewbasket_layout, null,true);
final TextView txtstore = (TextView) rowView.findViewById(R.id.txtstorename);
final TextView txtproduct = (TextView) rowView.findViewById(R.id.txtproduct);
final TextView txtquantity = (TextView) rowView.findViewById(R.id.txtquantity);
TextView txtprice = (TextView) rowView.findViewById(R.id.txtprice);
TextView txttotal = (TextView) rowView.findViewById(R.id.txttotal);
Button btnclear = (Button) rowView.findViewById(R.id.btnclearitem);
txtstore.setText(storename[position]);
txtproduct.setText(itemname[position]);
txtquantity.setText(productquantity[position]);
txtprice.setText(itemprice[position]);
txttotal.setText(basketlinetotal[position]);
btnclear.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
product = txtproduct.getText().toString();
quantity = txtquantity.getText().toString();
store = txtstore.getText().toString();
DeleteFromBasket();
Toast toast = Toast.makeText(getContext(),"Item Cleared", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 10);
toast.show();
notifyDataSetChanged();
}
/*your onclick code*/
});
return rowView;
};
public void ChannelToService()
{
String SOAP_ACTION = "http://tempuri.org/ITHubServ/DeleteFromBasket";
String METHOD_NAME = "DeleteFromBasket";
String NAMESPACE = "http://tempuri.org/";
String URL = "http://www.buh34nart.co.za/THubServ.svc?wsdl";
String OrderLine = "";
try{
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
String basketline = stringEmail + "|" + store + "|" + product.replace("|", "") + "|" + quantity;
//OrderLine = OrderLine.substring(0,OrderLine.length() -1);
Request.addProperty("Line", basketline);
//Request.addProperty("UserPassword", txtPass.getText().toString());
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(Request);
HttpTransportSE transport= new HttpTransportSE(URL);
Object Response = null;
transport.call(SOAP_ACTION, soapEnvelope);
Response = soapEnvelope.getResponse();
// data = Response.toString().split("[\\x7C]");
//Log.i(TAG, "Result Order: " + Response);
//if(Response.toString().equals("1"))
//{
// runOnUiThread(new Runnable() {
// public void run() {
//Toast toast = Toast.makeText(LoginPage.this,"Incorrect Username/Password" +
//" Login Failed", Toast.LENGTH_LONG);
//toast.setGravity(Gravity.CENTER, 0, 10);
//toast.show();
//Not Registered or psw wrong or email wrong (forgot password)
// }
// });
//}
//else
//{
// if(Response.toString().equals("9"))
// {
// startActivity(new Intent("com.ctc.android.widget.TechnicalError"));
// // Probleem met system Technical
// }
// else
// {
//btnloginclick();
// }
// }
}
catch(Exception Ex) {}
}
public void DeleteFromBasket()
{
AsyncCallWS task = new AsyncCallWS();
task.execute();
}
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
ProgressDialog progDailog = new ProgressDialog(getContext());
#Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
ChannelToService();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
CustomBasketAdapter.this.clear();
CustomBasketAdapter.this.addAll();
CustomBasketAdapter.this.notifyDataSetChanged();
progDailog.dismiss();
}
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
super.onPreExecute();
progDailog.setMessage("Loading...");
progDailog.setIndeterminate(false);
progDailog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDailog.setCancelable(true);
progDailog.show();
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(TAG, "onProgressUpdate");
}
}
}
I think that your problem in that you aren't deleting the item in the string array. You should change
CustomBasketAdapter.this.clear();
CustomBasketAdapter.this.addAll();
CustomBasketAdapter.this.notifyDataSetChanged();
By
CustomBasketAdapter.this.remove(item);
CustomBasketAdapter.this.notifyDataSetChanged();
Nevermind I found the solution
what i've done is called the method that builds the list
from within the custom adapter
if(context instanceof ViewBasket){
((ViewBasket)context).GetBasketProducts();
}
because deleting the item only changed the data on the database which passes me the information i needed to request the information again

Categories