Convert Switch state to Boolean - android-studio

I'm trying to get the value of a switch (on/off) and tell the data to another class.
I'm not using a switch statement, I have a physical switch which the user can check or uncheck.
I need to get the value of this switch in order to use the data in another class.
Here's what I've tried to use:
Switch vibeBlocker = (Switch) findViewById(R.id.hideVibeSwitch);
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Boolean vibeHider = Boolean.valueOf(vibeBlocker);
}
I receive an error on the line Boolean vibeHider = Boolean.valueOf(vibeBlocker);. I'm not sure how to get the value of my switch and convert it to a boolean. I know I can use methods like .toString(); and such, but is there something similar for booleans?
I need to transfer the value of the switch between two classes, and I think this will work. If anyone knows the correct statement here, or a better way to do this, please let me know.
Thanks!
Nathan

I was declaring the Switch and finding it by Id, which didn't work for me. Instead, I had to use a SharedPreferenceManager to put the boolean into my bundle:
#Override
public void onSaveInstanceState(#NonNull Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
SharedPreferences mSharedPreferencesManager = PreferenceManager.getDefaultSharedPreferences(this);
vibeBlock = mSharedPreferencesManager.getBoolean("vibration_checkbox", false);
savedInstanceState.putBoolean("myBoolean", vibeBlock);
}
That worked to put the boolean into the bundle. Here's how I pulled it out in the MainActivity:
#Override
public void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
hideVibe = savedInstanceState.getBoolean("myBoolean");
}
I also added this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
(Creation code)
SharedPreferences mSharedPreferencesManager = PreferenceManager.getDefaultSharedPreferences(this);
hideVibe = mSharedPreferencesManager.getBoolean("vibration_checkbox", false);
if (hideVibe) {
switchConv.setVisibility(View.GONE);
} else if (!hideVibe) {
switchConv.setVisibility(View.VISIBLE);
}
}
And this as well:
#Override
protected void onResume() {
super.onResume();
SharedPreferences mSharedPreferencesManager = PreferenceManager.getDefaultSharedPreferences(this);
hideVibe = mSharedPreferencesManager.getBoolean("vibration_checkbox", false);
if (hideVibe) {
switchConv.setVisibility(View.GONE);
} else if (!hideVibe) {
switchConv.setVisibility(View.VISIBLE);
}
}
And that did the trick :)

Related

Android Studio RecyclerView Adapter loop getItemViewType()

My recyclerview's adapter continuously calls getItemViewType() and seems to be no sign to stop.
I also print log in onBindViewHolder(), onCreateViewHolder(), and viewHolder's bind function, but only getItemViewType get called infinitely.
How can I solve this problem?
My Fragment:
I added log in each function, and didn't see any function be called continuously.
public class Fragment{
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (presenter == null) {
presenter = new Presenter(this);
}
initViewModel();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
setRecyclerView();
//this will modify adapter
loadData();
return rootView;
}
void initViewModel(){
messageViewModel = new ViewModelProvider(this).get(messageViewModel.class);
final Observer<ArrayList<WallPost>> wallPostObserver = wallPostList -> {
//this will modify adapter
updateRecyclerView(wallPostList);
};
messageViewModel.getWallPostsLiveData().observe(this, wallPostObserver);
}
public void setRecyclerView() {
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
adapter = new Adapter(getContext(), new ArrayList<>(), Repository.getInstance().getMemberData().getValue(), getType());
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(scrollListener);
}
}
My Adapter getItemViewType(int position) function:
Adapter getItemCount() be called continuously same as getItemViewType(int position).
#Override
public int getItemViewType(int position) {
if (wallPostList.size() == 0) {
return VIEW1;
}else if(position >= wallPostList.size()){
return VIEW7;
}
WallPost wallPost = wallPostList.get(position);
Log.d("Adapter","position:"+position);
if(wallPost.getStatus().equals(POST_STATUS_REVOKE)){
return VIEW8;
}
switch (wallPost.getType()) {
case azz:
return VIEW5;
case axx:
return VIEW6;
case ayy:
default:
if(wallPost.getMsgItemList().size() > 0){
return VIEW4;
}else if(StringUtils.checkHasLink(wallPost.getContent())){
return VIEW3;
}else {
return VIEW2;
}
}
}
Update: cause problem's code
I found the problem cause this, I solve this problem by add a flag in my customize view to restrict not repeat onMeansure, but I don't know why this will make adapter repeat call getItemViewType(int position) and getItemCount().
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(type.equals(SINGLE)){
info.post(()->{
halfWidth = (info.getMeasuredWidth()- arrowImageView.getMeasuredWidth())/2;
name.setMaxWidth(halfWidth-image.getMeasuredWidth());
tvNoticeTime.setMaxWidth(halfWidth-image.getMeasuredWidth());
});
}
else if(type.equals(MULTI)){
info.post(()->{
name.setMaxWidth(info.getMeasuredWidth()-image.getMeasuredWidth() - (int)PixelUtil.convertDpToPixel(8,context));
});
}
else{
int dis = (int)PixelUtil.convertDpToPixel(8,context);
info.post(()->{
name.setMaxWidth(info.getMeasuredWidth()-image.getMeasuredWidth()-dis-
infoImageView.getMeasuredWidth()-dis);
});
}
}
The problem you are facing is that you update your RecyclerView based on the wallPostObserver that looks for changes in the wallPostList. There could be a problem regaring this because if the List changes there is a chnage in the recycler View and the getItemViewType method is called. If you made it so that the recyclerView is only updated once the user chooes to or in fix intervals you wouldn't have the problem. You could fix that by creating a Method that triggers if the List changes (without using an Observer) there you could define the max update interval and make is so that you dont always throw away your entire list.

Recognizing multiple keyphrases in CMUSphinx for Android [duplicate]

I've installed the PocketSphinx demo and it works fine under Ubuntu and Eclipse, but despite trying I can't work out how I would add recognition of multiple words.
All I want is for the code to recognize single words, which I can then switch() within the code, e.g. "up", "down", "left", "right". I don't want to recognize sentences, just single words.
Any help on this would be grateful. I have spotted other users' having similar problems but nobody knows the answer so far.
One thing which is baffling me is why do we need to use the "wakeup" constant at all?
private static final String KWS_SEARCH = "wakeup";
private static final String KEYPHRASE = "oh mighty computer";
.
.
.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
What has wakeup got to do with anything?
I have made some progress (?) : Using addGrammarSearch I am able to use a .gram file to list my words, e.g. up,down,left,right,forwards,backwards, which seems to work well if all I say are those particular words. However, any other words will cause the system to match what is said to the "nearest" word from those stated. Ideally I don't want recognition to occur if words spoken are not in the .gram file...
Thanks to Nikolay's tip (see his answer above), I have developed the following code which works fine, and does not recognize words unless they're on the list. You can copy and paste this directly over the main class in the PocketSphinxDemo code:
public class PocketSphinxActivity extends Activity implements RecognitionListener
{
private static final String DIGITS_SEARCH = "digits";
private SpeechRecognizer recognizer;
#Override
public void onCreate(Bundle state)
{
super.onCreate(state);
setContentView(R.layout.main);
((TextView) findViewById(R.id.caption_text)).setText("Preparing the recognizer");
try
{
Assets assets = new Assets(PocketSphinxActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
}
catch (IOException e)
{
// oops
}
((TextView) findViewById(R.id.caption_text)).setText("Say up, down, left, right, forwards, backwards");
reset();
}
#Override
public void onPartialResult(Hypothesis hypothesis)
{
}
#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()
{
}
#Override
public void onEndOfSpeech()
{
reset();
}
private 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);
File digitsGrammar = new File(modelsDir, "grammar/digits.gram");
recognizer.addKeywordSearch(DIGITS_SEARCH, digitsGrammar);
}
private void reset()
{
recognizer.stop();
recognizer.startListening(DIGITS_SEARCH);
}
}
Your digits.gram file should be something like:
up /1e-1/
down /1e-1/
left /1e-1/
right /1e-1/
forwards /1e-1/
backwards /1e-1/
You should experiment with the thresholds within the double slashes // for performance, where 1e-1 represents 0.1 (I think). I think the maximum is 1.0.
And it's 5.30pm so I can stop working now. Result.
you can use addKeywordSearch which uses to file with keyphrases. One phrase per line with threshold for each phrase in //, for example
up /1.0/
down /1.0/
left /1.0/
right /1.0/
forwards /1e-1/
Threshold must be selected to avoid false alarms.
Working on updating Antinous amendment to the PocketSphinx demo to allow it to run on Android Studio. This is what I have so far,
//Note: change MainActivity to PocketSphinxActivity for demo use...
public class MainActivity extends Activity implements RecognitionListener {
private static final String DIGITS_SEARCH = "digits";
private SpeechRecognizer recognizer;
/* Used to handle permission request */
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.main);
((TextView) findViewById(R.id.caption_text))
.setText("Preparing the recognizer");
// Check if user has given permission to record audio
int permissionCheck = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_REQUEST_RECORD_AUDIO);
return;
}
new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(MainActivity.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 {
reset();
}
}
}.execute();
((TextView) findViewById(R.id.caption_text)).setText("Say one, two, three, four, five, six...");
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null) {
return;
} else if (hypothesis != null) {
if (recognizer != null) {
//recognizer.rapidSphinxPartialResult(hypothesis.getHypstr());
String text = hypothesis.getHypstr();
if (text.equals(DIGITS_SEARCH)) {
recognizer.cancel();
performAction();
recognizer.startListening(DIGITS_SEARCH);
}else{
//Toast.makeText(getApplicationContext(),"Partial result = " +text,Toast.LENGTH_SHORT).show();
}
}
}
}
#Override
public void onResult(Hypothesis hypothesis) {
((TextView) findViewById(R.id.result_text)).setText("");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), "Hypothesis" +text, Toast.LENGTH_SHORT).show();
}else if(hypothesis == null){
makeText(getApplicationContext(), "hypothesis = null", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onDestroy() {
super.onDestroy();
recognizer.cancel();
recognizer.shutdown();
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onEndOfSpeech() {
reset();
}
#Override
public void onTimeout() {
}
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
// .setRawLogDir(assetsDir).setKeywordThreshold(1e-20f)
.getRecognizer();
recognizer.addListener(this);
File digitsGrammar = new File(assetsDir, "digits.gram");
recognizer.addKeywordSearch(DIGITS_SEARCH, digitsGrammar);
}
private void reset(){
recognizer.stop();
recognizer.startListening(DIGITS_SEARCH);
}
#Override
public void onError(Exception error) {
((TextView) findViewById(R.id.caption_text)).setText(error.getMessage());
}
public void performAction() {
// do here whatever you want
makeText(getApplicationContext(), "performAction done... ", Toast.LENGTH_SHORT).show();
}
}
Caveat emptor: this is a work in progress. Check back later. Suggestions would be appreciated.

Counting number of times android app goes into background

I'm developing an app which counts number of times the app goes to the background. It also retains the values when the orientation is changed. Though I have it working of all use cases, I have one use case which does not work.
Case : When I press the home button, change the phone's orientation and reopen the app, It does open in landscape mode but, the background count does not increase.
I have tried setting values in all the life cycle methods. It doesn't work. Hope somebody can help me with this.
`
public class MainActivity extends AppCompatActivity {
private int clickCount =0, backgroundCount = 0;
TextView tvClickCountValue, tvBackgroundCountValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if( savedInstanceState != null){
clickCount = savedInstanceState.getInt("COUNT");
backgroundCount = savedInstanceState.getInt("BGCOUNT");
}
setContentView(R.layout.activity_main);
tvClickCountValue = (TextView) this.findViewById(R.id.tvClickCountValue);
tvBackgroundCountValue = (TextView) this.findViewById(R.id.tvBackgroundCountValue);
setView(MainActivity.this);
}
public void onClick(View v){
clickCount += 1;
tvClickCountValue.setText(Integer.toString(clickCount));
}
public void setView(Context ctx){
tvClickCountValue.setText(Integer.toString(clickCount));
tvBackgroundCountValue.setText(Integer.toString(backgroundCount));
}
#Override
protected void onStop() {
super.onStop();
backgroundCount += 1;
}
#Override
protected void onResume() {
super.onResume();
tvClickCountValue.setText(Integer.toString(clickCount));
tvBackgroundCountValue.setText(Integer.toString(backgroundCount));
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("COUNT", clickCount);
outState.putInt("BGCOUNT", backgroundCount);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
clickCount = savedInstanceState.getInt("COUNT");
backgroundCount = savedInstanceState.getInt("BGCOUNT");
}
}
This article contains useful information: https://developer.android.com/guide/topics/resources/runtime-changes.html especially in the section about Handling The Change.
Try handling it on onConfigurationChanged() of you have disabled Activity restarts on orientation changes. Otherwise, probably through this article you will find which case applies to your scenario.
By reading the problem description, I am assuming that if you don't rotate the device the application works as intended.
you need to persist the count in the SharedPreferences. each time you reopen the app read the last value from the SharedPreferences. And increment and save to SharedPreferences each time the app is hidden.
Then you can count the with #kiran code:
public class BaseActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
public static boolean isAppInFg = false;
public static boolean isScrInFg = false;
public static boolean isChangeScrFg = false;
#Override
protected void onStart() {
if (!isAppInFg) {
isAppInFg = true;
isChangeScrFg = false;
onAppStart();
}
else {
isChangeScrFg = true;
}
isScrInFg = true;
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
if (!isScrInFg || !isChangeScrFg) {
isAppInFg = false;
onAppPause();
}
isScrInFg = false;
}
public void onAppStart() {
// app in the foreground
// show the count here.
}
public void onAppPause() {
// app in the background
// start counting here.
}
}

If Statement Not Executed in AutocompleteTextView

I'm new to Android Studio and currently working on my first app. Thanks to numerous examples on here i have managed to catch up on the basics very quickly. I now have a problem with my autocompletetextview, i want to get the text selected then use it in a if statement to determine what is shown on the "results" textview. The if statement works fine but only for the "else" part and i can't figure out where i went wrong.
I have commented out the onItemClickListener because the "testfoodph" method does the same.
Here is the activity code:
public class phTester extends AppCompatActivity {
Intent intent = getIntent();
AutoCompleteTextView text;
MultiAutoCompleteTextView text1;
TextView results;
String foodies;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ph_tester);
String[] foods = getResources().getStringArray(R.array.foodlist);
text=(AutoCompleteTextView)findViewById(R.id.autoCompleteTextView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,foods);
text.setAdapter(adapter);
text.setThreshold(1);
results=(TextView)findViewById(R.id.phResults);
foodies = text.getText().toString();
text.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//if (foodies.equalsIgnoreCase("Mango")) {
//results.setText(getString(R.string.phAlk));
}
//else {
//results.setText(getString(R.string.Error));
//}
//}
});
}
public void TestFoodPH(View view) {
if (foodies.equalsIgnoreCase("Mango")) {
results.setText(getString(R.string.phAlk));
}
else {
results.setText(getString(R.string.Error));
}
}

How to update ListView from completely unrelated class

I've read through a lot of questions on how to update a ListView. They all pretty much say adapter.notifyDataSetChanged() (if in a seperate thread with runOnUiThread).
My problem starts a bit earlier: How do I even get the Adapter I need or for that matter an Activity to call runOnUiThread?
Here is a very simplified version of my current code:
I have a class for the Data, which can be updated from anywhere at any time. The update method needs to start a new Thread, which is why I can't simply wait for a return value.
class Data {
private static double[] data = new double[7]
public static void update(final Context context) {
new Thread(new Runnable() {
#Override
public void run() {
//do lots of complicated stuff
}
}).start();
}
public double[] getData {
return data;
}
I have an Activity (not the main Activity) that, among other stuff, contains the ListView
public class ListViewActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ListView);
ListView listView = (ListView) findViewById(R.id.MyListView);
listView.setAdapter(new CustomListViewAdapter(this));
}
I then use a custom Adapter to set up the ListView how I want it.
class CustomListViewAdapter extends BaseAdapter {
private final LayoutInflater layoutInflater;
public CustomListViewAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
if (view == null) {
view = layoutInflater.inflate(R.layout.listView_row_layout, parent, false);
viewHolder.value = (TextView) view.findViewById(R.id.listViewDataTextField);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
double data = Data.getData()[position];
viewHolder.value.setText(data+"");
return view;
}
private class ViewHolder {
TextView value;
}
Now I want to update the ListView with as soon as the Thread in the update() method has finished getting the new data. Getting the data can take several seconds, so it's impossible to predict, what activity will be active by that time. If my ListViewActivity is active, I want the ListView to change to the new data immediately.
So how do I update that ListView, from a different class, which is not an Activity, inside another thread? I don't suppose putting the adapter in a static field is a good idea, since that ListViewActivity is probably created and destroyed all the time? But what other options do I have?
Define a callback interface. Make your update method take an instance of this callback as an argument and call back to it when updating has finished.
public interface UpdateCallback {
public void onUpdateFinished();
}
public void update(final Context context, final UpdateCallback callback) {
new Thread(new Runnable() {
#Override
public void run() {
// do lots of complicated stuff
callback.onUpdateFinished();
}
}).start();
}
Then in your Activity you can notify that the adapter data has changed:
Data.update(this, new UpdateCallback() {
public void onUpdateFinished() {
adapter.notifyDatasetChanged();
}
});
extendIt looks like your major problem can be formulated shortly as "How do I even get the Adapter", so I'll try to address that. Let us try to use an old good Java singleton to solve the problem. The idea is to create a global config and pre-create adapters for all views that you need to update:
public class GlobalConfig {
private static GlobalConfig config = null;
private CustomBaseAdapterOne adapter1 = null;
private CustomBaseAdapterTwo adapter2 = null;
public GlobalConfig getAdapterOne() {return adapter1;}
public GlobalConfig getAdapterTwo() {return adapter2;}
public static synchronized GlobalConfig getInstance() {
if (config == null) {
config = new GlobalConfig();
config.adapter1 = new CustomBaseAdapterOne();
config.adapter2 = new CustomBaseAdapterTwo();
}
return config;
}
}
Your ListViewActivity will need to extend DataSetObserver class and register an observer when it starts. You CustomListAdapter would need to register the observer when it starts and it will also need to be able to get initialized with init params (Context in your case) through a function (e.g. setContext), not through a constructor, so in your ListViewActivity you'll need to do something like below:
GlobalConfig cfg = GlobalConfig.getInstance();
CustomerAdapterOne ad = cfg.getAdapterOne();
ad.setContext(this);
ad.registerDataSetObserver(this);
From a separate thread that needs to update the ListView, you'll run:
GlobalConfig cfg = GlobalConfig.getInstance();
try {
cfg.getAdapterOne().notifyDataSetChanged();
}
catch{... }
I think, it's a good idea to have try/catch here because I don't know what will happen if ListView has already died at the time when you need to notify.
To summarize: you'll need to pre-create one adapter for each view that needs to be updated and make it globally available for everyone who needs it.

Resources