Retrieve data from Android data store directly to variable
In the shared preference the developer can read the stored value directly and store it in a variable like this
val score = sharedPref.getInt("highScore"), 0)
Toast.makeText(requireContext(), score.toString(), Toast.LENGTH_SHORT).show() // The score variable can be accessed here
But in the data store it is not possible because it is inside the coroutine scope (inside Fragment)
viewLifecycleOwner.lifecycleScope.launch {
val score = preferenceHelper.read("highScore")
}
Toast.makeText(requireContext(), score.toString(), Toast.LENGTH_SHORT).show() // The score variable cannot be accessed here
One of the solutions presented in the documentation is to use runBlocking, but it should be avoided as much as possible
val score = runBlocking { preferenceHelper.read("highScore") }
Toast.makeText(requireContext(), score.toString(), Toast.LENGTH_SHORT).show() // The score variable can be accessed here
My question is is there a better way than using runBlocking or should I keep using the shared preference ? :)
1 answer
-
answered 2022-05-04 09:57
Jakoss
You can easily make your toast inside the coroutine you've created for the fragment. So your example is pretty much ok, just move the toast invocation inside the launch block and you'll be good to go.
To answer directly the question - there is no better way of running suspend function synchronously. And, if the shared preferences are working you - you can stick to them just fine. But keep in mind that those are reading value on main thread, so it will be pretty much the same as reading from
dataStore
inrunBlocking
do you know?
how many words do you know
See also questions close to this topic
-
Updating a Single Column In Room Database
That's the function I'm using for updat
private fun updateSettingsDatabase(settingsDao: SettingsDao) { lifecycleScope.launch { settingsDao.update(SettingsEntity( 1, nightMode=nightModeResult, )) } } @Query("SELECT * FROM `settings-table`") fun fetchCurrentSettings(): Flow<List<SettingsEntity>>
I specified
nightMode=
because I thought that this way I'm only updating this colummn, but it turns out that it resets every column, how do I update a single column, while keeping the values the rest of the columns? -
Using EdittextPreference for Goto search
sorry for my poor English. I want to use EditTextPreference in my bottom nav like the pic below, ![screenshot][1]
I have recycleview xml in my project with in many sub cardview layouts(which is scrollable) and I want to create item in the bottom nav which is called "Goto". When the "Goto" item is clicked i want it to pop-up like the screenshot. And when user enters a number(according to the cardviews i.e if the number of cardview is 40 user must enter 1-40) I want to search the cardview by its ID. Thank you and I hope u got it, If u have any questions let me know [1]: https://i.stack.imgur.com/grK8P.jpg
My xml format look like this. As you see in the blow since the cardviews are huge in number it is not cool to scroll all the way down that is why i need Goto item in the bottom nav to search it by its ID when the user click number in the EditTextPreference as u see in the screenshot. i.e The screenshot is not from my app
<LinearLayout> <LinearLayout> <androidx.cardview.widget.CardView> <RealtiveLayout> <Textview/> <RealtiveLayout> </androidx.cardview.widget.CardView> </LinearLayout> <LinearLayout> <androidx.cardview.widget.CardView> <RealtiveLayout> <Textview/> <RealtiveLayout> </androidx.cardview.widget.CardView> </LinearLayout> <LinearLayout> <androidx.cardview.widget.CardView> <RealtiveLayout> <Textview/> <RealtiveLayout> </androidx.cardview.widget.CardView> </LinearLayout> <LinearLayout> <androidx.cardview.widget.CardView> <RealtiveLayout> <Textview/> <RealtiveLayout> </androidx.cardview.widget.CardView> </LinearLayout> .. .. .. .. many more..
-
IOS Launcher in android studio
I'm trying to change the whole Android OS installed app icons into IOS icons, please help me with the proper code or library for android kotlin
-
Kotlin Coroutines Unit Testing
Im trying to test this suspend function:
suspend fun <T> getResult(call: suspend () -> Response<T>): Resource<T> { val response = call() val body = response.body() val code = response.code() if (response.isSuccessful) { Log.d(Cybrid.instance.tag, "Data: ${response.code()} - ${response.body()}") return Resource.success(body!!, code) } else if (response.code() == HTTP_UNAUTHORIZED || response.code() == HTTP_FORBIDDEN) { Cybrid.instance.let { cybrid -> cybrid.listener.let { cybrid.invalidToken = true it?.onTokenExpired() } } Log.e(Cybrid.instance.tag, "Error - Something wrong with TOKEN : ${response.code()} ${response.message()}") return Resource.error(response.message(), code=response.code()) } else { Log.e(Cybrid.instance.tag, "Error - Other: ${response.code()} ${response.message()} :: ${response.raw()}") return Resource.error(message = response.message(), data= response.body(), code= response.code()) } }
With this Unit Test Case, all it cover except line 13 , I dont know how to cover the line!!!
@ExperimentalCoroutinesApi @Test fun get400ErrorServerTest() = runBlocking { Cybrid.instance.setBearer("Bearer") val pricesService = AppModule.getClient().createService(PricesApi::class.java) val result = getResult { pricesService.listPrices() } Assert.assertNotNull(result) Assert.assertEquals(result.code, 400) Assert.assertNull(result.data) }
The coverage report says:
Some idea to get coverage for line 13 ??? Thnanks
-
Android ZoneDateTime.withHour always sets hour to 8
So I am tring to schedule alarm at a particular time on current day using AlarmManager. To do that I am using ZoneDateTime to get current time and then updating it to the hour at which I need to set the alarm. But for some reason time.withHour is giving me 8pm or 8am no matter what hour I am passing to it. Am I doing something wrong here?
var time = ZonedDateTime.now() //getting current time at my timezone time = time.withHour(22).withMinute(8).withSecond(0) print(time) //getting 8am/8pm at my timezone val timeMilis = time.toInstant().toEpochMilli()
-
How to save the selection of a spinner in a dialog box
I have a dialog box with a spinner in it (taken from a third party add-on called PowerSpinnerView).
So far, I have managed to code the spinner so that it saves the last known selection whenever I open up the dialog box again containing said spinner.
Albeit, I'm trying to get shared preferences to save the index of the selection and then retrieve it in my activity's onCreate, so that I can attribute a corresponding action to it when the app starts up. I'm having difficulties, in so much that the pp is now crashing with an error code with reference to the spinner (referenced as powerSpinnerView throughout my activity) being a 'null object reference'.
Can anybody please advise on where I might be going wrong? If you require additional details, then please let me know - more than happy to provide. Hopefully what I said makes sense!
Code snippet from spinner in Dialog box:
@Override public void onClick(View view) { final Dialog dialog = new Dialog(MainActivity.this); dialog.setContentView(R.layout.activity_options_menu); dialog.setCanceledOnTouchOutside(false); dialog.setCancelable(true); WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); lp.copyFrom(dialog.getWindow().getAttributes()); lp.width = WindowManager.LayoutParams.WRAP_CONTENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; View back = dialog.findViewById(R.id.arrow); PowerSpinnerView powerSpinnerView = (PowerSpinnerView) dialog.findViewById(R.id.spItems); ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); powerSpinnerView.setOnSpinnerItemSelectedListener(new OnSpinnerItemSelectedListener<String>() { @Override public void onItemSelected(int oldIndex, @Nullable String oldItem, int newIndex, String newItem) { if (newIndex == 0) { // save inputted spinner position to sharedpreferences int userChoice = powerSpinnerView.getSelectedIndex(); sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); SharedPreferences.Editor prefEditor = sharedPreferences.edit(); prefEditor.putInt("userChoiceSpinner", userChoice); prefEditor.apply(); Toast.makeText(getApplicationContext(),"CURRENCY CHANGED TO USD",Toast.LENGTH_SHORT).show();
Code snippet from OnCreate:
final Dialog dialog = new Dialog(MainActivity.this); PowerSpinnerView powerSpinnerView = (PowerSpinnerView) dialog.findViewById(R.id.spItems); // Retrieve spinner position from sharedpreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); int spinnerValue = sharedPreferences.getInt("userChoiceSpinner", -1); if (spinnerValue != -1){ // set the value of the spinner powerSpinnerView.selectItemByIndex(spinnerValue); Toast.makeText(getApplicationContext(),"SUCCESS!",Toast.LENGTH_SHORT).show(); }
-
android SharedPreferences order/sort by field
i am retrieving all SharedPreferences inside my app like this:
getCollection() async { SharedPreferences prefs = await SharedPreferences.getInstance(); if (prefs.getInt("collectionCount") == null) { clearCollection(); } else { collectionCount = prefs.getInt("collectionCount")!; url = prefs.getStringList("collectionUrl")!.reversed.toList(); method = prefs.getStringList("collectionMethod")!.reversed.toList(); headers = prefs.getStringList("collectionHeaders")!.reversed.toList(); body = prefs.getStringList("collectionBody")!.reversed.toList(); name = prefs.getStringList("collectionName")!.reversed.toList(); syntax = prefs.getStringList("collectionSyntax")!.reversed.toList(); } }
Is there a way to order the output by the name (collectionName) field in alphabetic order?
-
Whenever i try to implement Dark mode in my Settings, i get this crash (Android Studio, java)
I get the linear layout error only when i try to implement dark mode from PreferenceSwitchCompat
Java:
enter code here public static class SettingsFragment extends PreferenceFragmentCompat { SwitchPreferenceCompat themeSwitch; SharedPreferences sharedPreferences; public static final String MyPREFERENCES = "nightModePrefs"; public static final String KEY_ISNIGHTMODE = "isNightMode"; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.root_preferences, rootKey); LinearLayout linearLayout; SearchView searchView; searchView = getActivity().findViewById(R.id.searchView); linearLayout = getActivity().findViewById(R.id.layoutImg); linearLayout.setVisibility(View.GONE); Preference accountPreference = findPreference("account"); sharedPreferences = getActivity().getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE); themeSwitch = findPreference("switchTheme"); checkNightModeActivated(); themeSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if(themeSwitch.isChecked()){ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); saveNightModeState(true); getActivity().recreate(); } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); saveNightModeState(false); getActivity().recreate(); } return true; } }); accountPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { searchView.setVisibility(View.GONE); linearLayout.setVisibility(View.VISIBLE); getActivity().getSupportFragmentManager() .beginTransaction() .replace(R.id.settings, new AccountFragment()) .commit(); return true; } }); } private void saveNightModeState(boolean b) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean(KEY_ISNIGHTMODE, b); editor.apply(); } private void checkNightModeActivated(){ if(sharedPreferences.getBoolean(KEY_ISNIGHTMODE, false)){ themeSwitch.setChecked(true); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); } else { themeSwitch.setChecked(false); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } } }
Here is the xml of settings activity:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="0dp"> <androidx.appcompat.widget.SearchView android:id="@+id/searchView" android:layout_width="match_parent" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_height="wrap_content" app:goIcon="@drawable/ic_search"/> <LinearLayout android:id="@+id/layoutImg" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:scaleType="centerCrop" android:id="@+id/coverIv2" android:src="@color/appColor" android:layout_marginTop="0dp" android:layout_width="match_parent" android:layout_height="120dp" /> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/avatarIv2" android:layout_width="90dp" android:layout_height="90dp" android:layout_gravity="center" android:layout_marginTop="-40dp" android:scaleType="centerCrop" android:src="@drawable/ic_default_image_white" /> <Button android:layout_width="150dp" android:layout_height="wrap_content" style="@style/Base.Widget.AppCompat.Button.Colored" android:id="@+id/uploadProfileImage" android:text="Upload Images" android:layout_marginTop="10dp" android:layout_gravity="center"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Tap on the options below to edit." android:textAlignment="center" android:textColor="@color/textColor" android:textSize="16sp" android:fontFamily="@font/abeezee"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="All info. (except email, username) are optional" android:textSize="14sp" android:textAlignment="center" android:textColor="@color/textColor" android:fontFamily="@font/abeezee"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Connect with people easier :)" android:textColor="@color/textColor" android:textAlignment="center" android:textSize="14sp" android:fontFamily="@font/abeezee"/> </LinearLayout> <FrameLayout android:layout_marginTop="10dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:id="@+id/settings" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </LinearLayout> </ScrollView> </LinearLayout>
the layout and image etc are hiddent in settings fragment, but seen in the account fragment. everything was working fine untill i tried to add funcionality to the switch preference. There is not much info about preferences on the internet and not a single good youtube guide. And i am new to this. Thanks in advance.
Here is preferences xml:
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> <Preference app:key="account" app:title="Account" app:summary="Edit Profile" app:icon="@drawable/ic_profile_black" app:fragment="AccountFragment"/> <Preference app:key="privacy" app:title="Privacy and Security" app:summary="Change privacy settings" app:fragment="PrivacyFragment" app:icon="@drawable/ic_password"/> <Preference app:title="Notifications" app:summary="On-Off, Sound, Vibration" app:icon="@drawable/ic_notifi" app:fragment="NotificationFragment"/> <Preference app:title="Help and Support" app:summary="How to, FAQ, Contact us" app:icon="@drawable/ic_help" app:fragment="HelpFragment"/> <Preference app:title="About" app:summary="InDistant, Dev, Donate" app:icon="@drawable/ic_baseline_info_24" app:fragment="InfoFragment"/> <ListPreference app:key="language" app:entries="@array/items_name" app:entryValues="@array/items_value" app:defaultValue="true" app:title="Language" app:icon="@drawable/ic_baseline_language_24" app:summary="Change language"/> <SwitchPreferenceCompat app:key="switchTheme" app:title="Dark Theme" app:summary="Change Theme" app:icon="@drawable/ic_baseline_dark_mode_24"/> </PreferenceScreen>
and here is the error: 2022-05-05 16:31:21.753 23660-23660/com.example.indistant E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.indistant, PID: 23660 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.indistant/com.example.indistant.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.LinearLayout.setVisibility(int)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5456) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5362) at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:58) at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5415) at android.app.ActivityThread.access$3300(ActivityThread.java:237) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2076) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.LinearLayout.setVisibility(int)' on a null object reference at com.example.indistant.SettingsActivity$SettingsFragment.onCreatePreferences(SettingsActivity.java:234) at androidx.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:160) at androidx.fragment.app.Fragment.performCreate(Fragment.java:2981) at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:474) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:257) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1374) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2841) at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:2773) at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:251) at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:252) at com.example.indistant.SettingsActivity.onCreate(SettingsActivity.java:132) at android.app.Activity.performCreate(Activity.java:8000) at android.app.Activity.performCreate(Activity.java:7984) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5456) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5362) at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:58) at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5415) at android.app.ActivityThread.access$3300(ActivityThread.java:237) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2076) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 2022-05-05 16:31:21.780 23660-23697/com.example.indistant V/FA: Activity paused, time: 30539981
-
Flutter persist data locally with Json
I am building an app where user is able to store favorites on their device locally. Currently I am running in the following error:
"Exception has occurred. JsonUnsupportedObjectError (Converting object to an encodable object failed: Instance of 'DetailPage1')"
in this line, storing the data:
Future<Future<File>> _writeEntriesToStorage(List<LogEntry> entries) async { final dir = await paths.getApplicationDocumentsDirectory(); final file = File('${dir.path}/entries.json'); **return file.writeAsString( json.encode(entries.map((e) => e.toJson()).toList()), );** }
This is my function:
@JsonSerializable() class LogEntry { const LogEntry({ required this.mechanismId, required this.timestamp, required this.navigation, }); final int? mechanismId; final DateTime timestamp; final Widget? navigation; factory LogEntry.fromJson(Map<String, dynamic> json) => _$LogEntryFromJson(json); Map<String, dynamic> toJson() => _$LogEntryToJson(this); }
I guess it is caused by the Widget navigation (the rooting of the respective item) but I am stuck solving the problem.
-
Angular App: Amplify DataStore fails to synch with the AppSynch cloud
Hi am facing an issue with aws datastore, the data is created locally but it not posted on the AMAZON_DYNAMODB.
const awsmobile = { "aws_project_region": "ap-southeast-2", "aws_appsync_graphqlEndpoint": "https://yxxxxxx.appsync-api.ap-southeast-2.amazonaws.com/graphql", "aws_appsync_region": "ap-southeast-2", "aws_appsync_authenticationType": "API_KEY", "aws_appsync_apiKey": "da2-hxxxxx", "aws_cognito_identity_pool_id": "ap-southeast-2:xxxxx-a00xxx", "aws_cognito_region": "ap-southeast-2", "aws_user_pools_id": "ap-southeast-2_xxxxUno9", "aws_user_pools_web_client_id": "49xxxxxx", "oauth": {}, "aws_cognito_username_attributes": [], "aws_cognito_social_providers": [], "aws_cognito_signup_attributes": [ "EMAIL" ], "aws_cognito_mfa_configuration": "OFF", "aws_cognito_mfa_types": [ "SMS" ], "aws_cognito_password_protection_settings": { "passwordPolicyMinLength": 8, "passwordPolicyCharacters": [] }, "aws_cognito_verification_mechanisms": [ "EMAIL" ], "aws_user_files_s3_bucket": "sasaxxxxxxxxxxxxxxx", "aws_user_files_s3_bucket_region": "ap-southeast-2" };
export default awsmobile;
above is my aws-export files.
I have tried to unstall all the dependencies, but to no avail. and the worst part no error is generated when posting and retrieving data.