Image view not changing/Shared prefs not updating (android) - android

My app utilizes a Image view that changes daily. It runs a receiver every 24 hours which should send a notification and change the shared preferences value (this being the image to display). The notification runs fine at the correct time so I know the receiver works correctly. When you launch the activity the image that needs to be changed is located, the app gets the shared preferences value and then sets the imageView to display that image. The default value is set to 0, and if the value is 0 it sets the image to a "something went wrong" style of image. How come the notification works but my image view doesn't change? It stays as the "something went wrong image"?
My code:
The Reciever:
val quotes = arrayOf(R.drawable.i1, R.drawable.i2, R.drawable.i3, R.drawable.i5, R.drawable.i6, R.drawable.i7, R.drawable.i8, R.drawable.i9, R.drawable.i10, R.drawable.i11, R.drawable.i12, R.drawable.i13, R.drawable.i14, R.drawable.i15, R.drawable.i16, R.drawable.i17, R.drawable.i18, R.drawable.i19, R.drawable.i20, R.drawable.i21, R.drawable.i22, R.drawable.i23, R.drawable.i24, R.drawable.i25)
val quote = quotes.random()
val prefquotes = context.getSharedPreferences("save", AppCompatActivity.MODE_PRIVATE).edit()
prefquotes.putInt("Quotes", quote)
prefquotes.apply()
Qinsperation:
val quote = sharedPreferences.getInt("Quote", 0)
setContentView(R.layout.qinsperational)
val imageView = findViewById<ImageView>(R.id.daily_image)
if (quote == 0) {
imageView.setImageResource(R.drawable.oh_no)
}else{
Log.d("Quote", "good")
imageView.setImageResource(quote)
}
There is no crashes or anything in the logs. All help is much appreciated as I can't figure this one out

Related

Palette API returning negative values?

So I have to use the palette API in this app I am building to dynamically change the status bar color and when I pass the value I get to the method to change the status bar color of the app crashes with a java.lang.IllegalArgumentException: Unknown color
I am formatting it correctly regardless by adding the requires "#" in front of the number and also passing it as a String but the app still crashes.
This is the code snippet I used to do it.
binding.viewpagerMain.registerOnPageChangeCallback(
object: ViewPager2.OnPageChangeCallback(){
override fun onPageSelected(position: Int) {
var headerImage : Int? = null
when(position){
0 -> headerImage = R.drawable.character
1 -> headerImage = R.drawable.planets
2 -> headerImage = R.drawable.films
3 -> headerImage = R.drawable.species
4 -> headerImage = R.drawable.vehicles
5 -> headerImage = R.drawable.starships
}
if (headerImage != null) {
imageview_main.setImageResource(headerImage)
val bitmap = BitmapFactory.decodeResource(resources, headerImage)
Palette.from(bitmap).generate {
#SuppressLint("ResourceAsColor")
val paletteColor: Int? = it?.getDarkVibrantColor(R.color.colorPrimaryDark)
Log.e("MainFragment", "#${paletteColor}")
(activity as MainActivity).updateStatusBarColor("#${paletteColor.toString()}")
}
}
}
}
)
This is the activity function that I run
open fun updateStatusBarColor(color: String?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val window: Window = window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.parseColor(color)
}
}
Added a log call to know what the output was, and I got values like which were negative
#2131034159
#-14678008
#-15191992
#-7325688
I don't why the values are negative or if they can be, I assumed they where hex values and passed them , but they still don't work.
Color are stored as 32-bit integers on Android, as explained in the Color ints documentation. If the most significant bit is 1, the value is interpreted negative because the integer is signed. However interpreting it as signed makes no sense in the context of colors. In fact, all values that can be taken by an integer are valid colors.
Here's two solutions for fixing your logging statment:
"#${(paletteColor.toLong() and 0xFFFFFFFF).toString(16)}". Increase the bit width of your color and apply 32-bit mask so the most significant bit is 0 and value appears as positive.
"#${paletteColor.toUInt().toString(16)}". Use an unsigned integer. (requires having experimental unsigned numbers compiler option in Kotlin)
I prefer the first one.
For actually changing the color, I don't know if you realized what you're here: you're getting a color int, converting it to a string, then parsing it back to the original int! Why add an unnecessary step? Just use the int returned from getDarkVibrantColor to update window.statusBarColor.

FileChannel.truncate(...) method truncates at wrong position

I am using the FileChannel.truncate() method to remove the last part of a file, from the text "metadata" until the end:
override fun truncate(file: File) {
val fileAsText = FileUtils.readFileToString(file, Charset.defaultCharset())
val metadataPosition = fileAsText.indexOf("metadata")
val channel = FileOutputStream(file, true).channel
channel.truncate(metadataPosition.toLong())
channel.close()
}
While debugging I can see that the variable metadataPosition has a certain value, which is correct when checking it in the fileAsText String. Note that the "metadata" text only appears once in the file. However, when the channel.truncate(metadataPosition.toLong()) line is executed, the truncation is performed in a previous position and the file is smaller than expected, losing some of the information.
I have no clue about the reason for this, what could it be?

How to set timers to repeat three functions (showing pic in imageview) every certain amount of time?

So currently I am making a Pokédex for my internship.
I've got it working for the biggest part but there's a couple of things I need to get fixed including the question asked above.
I have a function called Eeveelutions which has to run three other functions called showVaporeon, showJolteon & showFlareon. They have to run for like 3 seconds each and then just loop around until the person using the pokedex goes to the next or previous pokémon.
The thing I need help with is how would I set a timer, (if that's the best way to do it) to run those functions. So, showVaporeon for 3 seconds, then showJolteon for 3 seconds, then Flareon for 3 seconds and repeat.
I have searched loads of questions to find my solution but I can't find it yet and most of it is not in kotlin.
So, is there anyone who has got an easy example for me or a better solution (and example) then using a timer.
Searched forum for solutions,
messed around with timers,
messed around with threads but no solutions yet
fun showVaporeon(){
evoChart2.visibility = View.VISIBLE
Glide.with(this).load(imageBaseURL + "134" + ".png").into(evoChart2)
evolveOption2.text = "Vaporeon"
evolveOption2.text = ""
evoChart2.visibility = View.GONE
}
fun showJolteon(){
evoChart2.visibility = View.VISIBLE
Glide.with(this).load(imageBaseURL + "135" + ".png").into(evoChart2)
evolveOption2.text = "Jolteon"
evolveOption2.text = ""
evoChart2.visibility = View.GONE
}
fun showFlareon(){
evoChart2.visibility = View.VISIBLE
Glide.with(this).load(imageBaseURL + "136" + ".png").into(evoChart2)
evolveOption2.text = "Flareon"
evolveOption2.text = ""
evoChart2.visibility = View.GONE
}
So I would want evoChart2 (which is one of the three imageviews I have) to show Vaporeon for 3 seconds, then Jolteon for 3 seconds, then Flareon for 3 seconds, and then Vaporeon again for 3 seconds, Jolteon, Flareon etc.
Since you're wanting a loop, I'd suggest using a list to make it easier to iterate and add more pokemon in future.
Create a Pokemon data class if you don't have one already.
data class Pokemon(val name: String, val imageUrl: String)
Create however many instances of this class as you need and add them to a list.
val pokemonList: List<Pokemon> = listOf(vaporeon, jolteon, flareon)
We'll also need to store the index of the current pokemon we're displaying
var currentIndex = 0
Next we'll create a Runnable and schedule it to execute every three seconds, you may want to do this in onResume.
val service = Executors.newSingleThreadScheduledExecutor()
service.scheduleAtFixedRate({ displayPokemon() }, 0, 3, TimeUnit.SECONDS)
Now create the displayPokemon function that is going to be called every 3 seconds.
fun displayPokemon() {
}
Inside this function we need to know what the next pokemon we're displaying is, based on the current pokemon.
val next = currentIndex + 1
if (next >= pokemonList.size) {
// we're at the end, go back to 0
currentIndex = 0
} else {
currentIndex = next
}
val pokemon = pokemonList[currentIndex]
Now that we have the next pokemon to display we can use it to populate the view
evoChart2.visibility = View.VISIBLE
Glide.with(this).load(pokemon.imageUrl).into(evoChart2)
evolveOption2.text = pokemon.name
evolveOption2.text = ""
evoChart2.visibility = View.GONE
Finally, we don't want this to happen when the Activity/Fragment is in the background so we add the following code to onPause
service.shutdown()

AS3/AIR Load/Save Username progress

I am creating an Android application created using Flash AS3. The user will input his/her name(instance namenameField), click the previous (btnPrev) and next (btnNext) button and press save (btnPrev). After restarting the application, the last frame saved was loaded (with the name). However if I want to input 2nd user with different name and save it in different frame, will the 2nd user's save progress be retained (without deleting the progress of the 1st user?). The problem, when I type the previous user name progress and press load (btnLoad), his saved progress doesn't load. Please help.
I am a newbie in programming. Here is my code so far:
*import flash.events.MouseEvent;
var savedstuff:SharedObject = SharedObject.getLocal("myStuff");
btnSave.addEventListener(MouseEvent.CLICK, SaveData);
btnLoad.addEventListener(MouseEvent.CLICK, LoadData);
btnNext.addEventListener(MouseEvent.CLICK, pageNext);
btnPrev.addEventListener(MouseEvent.CLICK, pagePrev);
function pageNext (e:MouseEvent){
nextFrame();
}
function pagePrev (e:MouseEvent){
prevFrame();
}
function SaveData(MouseEvent){
savedstuff.data.username = nameField.text
savedstuff.flush();
}
function LoadData(MouseEvent){
if(savedstuff.size>0){
nameField.text = savedstuff.data.username}
gotoAndStop(savedstuff.data.saveData);
}
if(savedstuff.size>0){
nameField.text = savedstuff.data.username}*
If I understood it correctly you want to save and load savedstuff for two different users, right ?
Since you always saving everything with the name "myStuff" data will be overwritten every time you save. If you want that per user you might want to add the username to the SharedObject name:
var savedstuff:SharedObject;
function SaveData(e:MouseEvent)
{
var userName:String = nameField.text;
savedstuff = SharedObject.getLocal(userName + "myStuff");
savedstuff.data.username = userName;
savedstuff.flush();
}
function LoadData(e:MouseEvent)
{
var userName:String = nameField.text;
savedstuff = SharedObject.getLocal(userName + "myStuff");
if(savedstuff.size > 0)
{
nameField.text = savedstuff.data.username}
gotoAndStop(savedstuff.data.saveData);
}
}

How to fetch own best score using gameNetwork.request( "loadScores" )?

does someone use gameNetwork provided by Google Play? Im having a little problem with it, im trying to fetch personal best score and its not working well.
Here is the code that i use
function loadScoreCallback(event)
oldScore = event.data[5].formattedValue
end
gameNetwork.request( "loadScores",
{
leaderboard =
{
category = "thecategory id",
playerScope = "Global", -- Global, FriendsOnly
timeScope = "AllTime", -- AllTime, Week, Today
range = {1,5},
playerCentered = true,
},
listener = loadScoreCallback
})
I also tried something like
function loadScoreCallback(event)
oldScore = event.data
end
gameNetwork.request( "loadScores",
{
leaderboard =
{
playerID = playerName,
category = "CgkIptXi1qgCEAIQAw",
playerScope = "Global", -- Global, FriendsOnly
timeScope = "AllTime", -- AllTime, Week, Today
playerCentered = true,
},
listener = loadScoreCallback
})
Also didnt work :/
I had some trouble figuring this out, but I found a solution that works for me.
this is the listener that is called when the user submits a score.
local function onGameNetworkRequestResult( event )
if event.type == "setHighScore" then
local function tempScoresFct(event)
if event.data then
local playerRank = event.data[1].rank
local currentValue = event.data[1].value
if lb.tempScore <= event.data[1].value then
native.showAlert("Score submitted", "You score is lower or equal than your current score in the leaderboard("..currentValue.."), nothing changed. Your global, all time rank is:\n" .. playerRank .. "\nTo see how you are doing among your friends and in other time scales, click the button \"show leaderboard\".", {"Ok"})
else
native.showAlert("Score submitted", "Your score was successfully uploaded to the leaderboard. Your global, all time rank is:\n" .. playerRank .. "\nTo see how you are doing among your friends and in other time scales, click the button \"show leaderboard\".", {"Ok"})
end
end
end
gameNetwork.request( "loadScores",
{
leaderboard =
{
category = event.data.category,
playerScope = "Global", -- Global, FriendsOnly
timeScope = "AllTime", -- AllTime, Week, Today
range = {1,1}, --Just get one player
playerCentered = true, -- and this player is the player that is logged in
},
listener = tempScoresFct
})
end
end
and this ist the function that submits the score:
function lb.submitScoreFct(event)
if event.phase == "ended" then
if gameNetwork.request("isConnected") then
--show leaderboards
print("submitting score")
local myCategory
local categoryName
if event.target.category == 1 then
myCategory = "ategoryID" --palo alto
categoryName = "Palo Alto"
elseif event.target.category == 2 then
myCategory = "ategoryID" --groningen
categoryName = "Groningen"
elseif event.target.category == 3 then
myCategory = "ategoryID" --sp2
categoryName = "SP2"
end
--local score = mRand(100,1000)
local score = event.target.score
lb.tempScore = score -- i use this to verify if the uploaded score was higher or lower then the value that is already there
print("Added " .. score .. " to " .. categoryName)
gameNetwork.request( "setHighScore",
{
localPlayerScore = { category=myCategory, value=tonumber(score) },
listener = lb.onGameNetworkRequestResult
})
end
else
print("user needs to log in")
-- Tries to login the user, if there is a problem then it will try to resolve it. eg. Show the log in screen.
gameNetwork.request("login",
{
listener = loginListener,
userInitiated = true -- if that is false, than this process is silent ie dont pop up a log in if the user is not logged in
})
end
return true
end
Oh and one thing I figured out, is that this listener functions are fragile. If there is one error inside, they quit and sometimes dont give any error.
For example if you try to print(event.data.rank) (instedt of print(event.data[1].rank)) there is no error but the function ends at this point and the rest of the function is not executed...
Well so i found a better idea, since not everyone is online all the time i made my own saving system, and it fetches high score from there. But i still dont know why it doesnt work, well at least i solved it with this.

Categories

Resources