• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

iOS

They are pretty smart looking... I think the style is far better than some of the options on our play store...

Having said that.. I managed to find apple clones lol

Attachments

  • Screenshot_20201107_191805_com.teslacoilsw.launcher.jpg
    Screenshot_20201107_191805_com.teslacoilsw.launcher.jpg
    205.3 KB · Views: 103
  • Screenshot_20201107_191814_com.teslacoilsw.launcher.jpg
    Screenshot_20201107_191814_com.teslacoilsw.launcher.jpg
    203 KB · Views: 84

PeriodicWorkRequest (work v1.0.1) is spawning 20 times every 15m in stead of just once, not sure why

In the follow code excerpts, I am utilizing a BroadcastReceiver to start up a Service on device boot and/or package reload. This NotificationService is calling my Worker via PeriodicWorkRequest every fifteen minutes. Everything initially works as it is supposed to, until the NotificationWorker is executed. It seems that, at the point where the Worker is invoked, it runs twenty times instead of just once. I believe that is twenty times exactly, as well. After all of it is said and done, it waits for ~15 minutes, as it should, and then exhibits the same behavior when it again invokes the Worker. Ideally this Worker should only be run once every 15m, especially being as some of the computation that it will be doing is rather expensive.

I have spent days now, googling for more information (I've partially been hampered in this due to using Work v1.0.1, instead of the more recent, androidx v2.4.0, but I'm not ready to upgrade everything that would be broken in my project with that change) and doing my best to debug this issue. Unfortunately, the debugging has been rather slow and unproductive, due to the fact that I can rarely get my Log.?() messages to even show up, let alone to give me any hints as to where this behavior is coming from. This behavior (Log messages not showing up) has been a problem in BootServiceStart, NotificationWorker, and NotificationService, and I've got no idea why.

Here is the applicable code for the issue; please note that if you follow the dpaste links you will find the general areas of the problematic code highlighted in order to ease diagnosis a bit (dpasted code will only be available for 6 more days):

BootServiceStart - also here on dpaste
Code:
    package com.example.sprite.half_lifetimer;
  
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Build;
    import android.util.Log;
  
    public class BootServiceStart extends BroadcastReceiver {
        public void onReceive(Context context, Intent arg1) {
            Intent intent = new Intent(context , NotificationService.class);
  
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent);
            } else {
                context.startService(intent);
            }
  
            if (GlobalMisc.Debugging) {
                Log.i("Halflife.BootServiceStart", "Attempted to start NotificationService");
            }
        }
    }

NotificationService - also here on dpaste
Code:
    package com.example.sprite.half_lifetimer;
  
    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;;
    import android.app.Service;
    import android.content.Intent;
    import android.os.Build;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.support.v4.app.NotificationCompat;
    import android.util.Log;
    import androidx.work.PeriodicWorkRequest;
    import androidx.work.WorkManager;
  
    import java.time.LocalDateTime;
    import java.util.HashMap;
    import java.util.concurrent.TimeUnit;
  
    public class NotificationService extends Service {
        public static HashMap<Integer, Boolean> firedNotifications = new HashMap<>();
        public static LocalDateTime lastNotificationLoopLDT = null;
  
        @Nullable
        public IBinder onBind(Intent intent) {
            return null;
        }
  
        /**
         * Method handles creation of a NotificationChannel and database
         * initialization (for this particular subset of the code), then passing
         * control off to notificationLoop().
         */
        public void onCreate() {
            startForeground(31337, buildForegroundNotification());
  
            if (GlobalMisc.Debugging) {
                Log.i("Halflife.NotificationService.onCreate", "Started NotificationService");
            }
  
            // Create the NotificationChannel, but only on API 26+ because
            // the NotificationChannel class is new and not in the support library
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel chan = new NotificationChannel(
                        "taper-n-clearing-talk", "taper-n-clearing",
                        NotificationManager.IMPORTANCE_NONE);
                chan.setDescription("Notifications for Taper dosages and Substance clearance");
  
                // Register the channel with the system; you can't change the importance
                // or other notification behaviors after this
                NotificationManager notificationManager = getSystemService(NotificationManager.class);
                notificationManager.createNotificationChannel(chan);
            }
  
            //get the database ready
            try {
                Permanence.Misc.init(/*NotificationService.this*/ getApplicationContext());
            } catch (Exception ex) {
                Log.e("Halflife.notificationLoop", "Unable to init database: " +
                        ex.toString());
            }
  
            if (GlobalMisc.Debugging) {
                Log.i("Halflife.onCreate", "all valid tapers: " +
                        Permanence.Tapers.loadAllValidTapers(getApplicationContext()).toString());
  
            }
  
            //notificationLoop();
            PeriodicWorkRequest notificationsRequest =
                    new PeriodicWorkRequest.Builder(NotificationWorker.class, 15, TimeUnit.MINUTES)
                            .build();
            WorkManager.getInstance()
                    .enqueue(notificationsRequest);
        }
  
        private Notification buildForegroundNotification() {
            NotificationCompat.Builder b=new NotificationCompat.Builder(this);
  
            b.setOngoing(true)
                    .setContentTitle("HLT Foreground Service")
                    .setContentText("Giving Half-life Timer foreground priority")
                    .setChannelId("taper-n-clearing-talk")
                    .setSmallIcon(getApplicationContext().getResources().getIdentifier(
                            "plus_medical_blue","drawable",
                            getApplicationContext().getPackageName()));
  
            return(b.build());
        }
    }

NotificationWorker - also here on dpaste
Code:
    package com.example.sprite.half_lifetimer;
  
    import android.app.PendingIntent;
    import android.app.TaskStackBuilder;
    import android.content.Context;
    import android.content.Intent;
    import android.support.annotation.NonNull;
    import android.support.v4.app.NotificationCompat;
    import android.support.v4.app.NotificationManagerCompat;
    import android.util.Log;
  
    import androidx.work.Worker;
    import androidx.work.WorkerParameters;
  
    import java.time.Duration;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
  
    public class NotificationWorker extends Worker {
        private boolean notificationDebugging = false;
  
        public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters params) {
            super(context, params);
        }
  
        @Override
        public Result doWork() {
            LocalDateTime nextScheduledDosage;
            long adminDurationMinutes;
  
            if (!notificationDebugging) {
                if (GlobalMisc.NotificationsEnabled) {
                    //taper notification loop
                    for (Taper taper : Permanence.Tapers.loadAllValidTapers(getApplicationContext())) {
                        //this will handle if any tapers have been added since inception
                        if (!NotificationService.firedNotifications.containsKey(taper.getId())) {
                            NotificationService.firedNotifications.put(taper.getId(), false);
                        }
  
                        //if this is a constrained taper, but we're outside of the window, just
                        //go on to the next taper
                        if (taper.isConstrained() && !taper.inConstraintHours()) {
                            Log.i("Halflife.notificationLoop",
                                    "skipping " + taper.toString() +
                                            " (outside of hourly constraints)");
  
                            continue;
                        }
  
                        if (!NotificationService.firedNotifications.get(taper.getId())) {
                            try {
                                nextScheduledDosage = taper.findNextScheduledDosageLDT();
                                if (!taper.isConstrained()) {
                                    Log.i("Halflife.notificationLoop",
                                            "working with unconstrained taper");
  
                                    adminDurationMinutes = Duration.ofDays(1).dividedBy(
                                            taper.getAdminsPerDay()).toMinutes();
                                } else {
                                    Log.i("Halflife.notificationLoop",
                                            "working with constrained taper");
  
                                    //not sure if this is necessary or not, but might as well
                                    //throw it in since the goddamned code is too complex for me
                                    //to follow right now down below
                                    LocalTime nextDosageTime =
                                            nextScheduledDosage.toLocalTime();
                                    if (nextDosageTime.isBefore(taper.getStartHour()) ||
                                            nextDosageTime.isAfter(taper.getEndHour())) {
                                        Log.i("notificationLoop",
                                                "skipping " + taper.toString() +
                                                        " (outside of constraint hours)");
  
                                        continue;
                                    }
  
                                    //this part, of course, is necessary
                                    adminDurationMinutes =
                                            Duration.between(taper.getStartHour(),
                                                    taper.getEndHour()).dividedBy(
                                                    taper.getAdminsPerDay())
                                                    .toMinutes();
                                }
  
                                if (GlobalMisc.Debugging) {
                                    Log.i("Halflife.notificationLoop", "Checking taper: " +
                                            taper.getName());
                                    Log.i("Halflife.notificationLoop", "nextScheduledDosage " +
                                            "contains: " + nextScheduledDosage.toString());
                                }
  
                                if (((NotificationService.lastNotificationLoopLDT != null) &&
                                        nextScheduledDosage.isAfter(
                                                NotificationService.lastNotificationLoopLDT) &&
                                        nextScheduledDosage.isBefore(
                                                LocalDateTime.now().plusMinutes(
                                                        (adminDurationMinutes / 5)))) ||
                                        (nextScheduledDosage.isAfter(
                                                LocalDateTime.now().minusMinutes(1)) &&
                                                nextScheduledDosage.isBefore(
                                                        LocalDateTime.now().plusMinutes(
                                                                (adminDurationMinutes / 5))))) {
                                    fireTaperNotification(taper);
  
                                    //set firedNotifications to reflect that we sent this
                                    //notification
                                    NotificationService.firedNotifications.replace(taper.getId(), true);
                                } else if (GlobalMisc.Debugging) {
                                    Log.i("Halflife.notificationLoop",
                                            "not displaying notification as per " +
                                                    "datetime constraints");
                                }
                            } catch (Exception ex) {
                                Log.e("Halflife.notificationLoop",
                                        "Issue finding next scheduled dosage: " +
                                                ex.toString());
  
                                return Result.failure();
                            }
                        }
                    }
                } else {
                    GlobalMisc.debugMsg("NotificationWorker:doWork",
                            "Would have just gone into substance taper notification loop");
                }
  
                if (GlobalMisc.NotificationsEnabled) {
                    //substance clearing notification loop
                    //LocalDateTime fiveMinAgo = LocalDateTime.now().minusMinutes(5);
                    for (Substance sub : Permanence.Subs.loadUnarchivedSubstances(
                            getApplicationContext())) {
                        if (GlobalMisc.Debugging) {
                            Log.i("Halflife.notificationLoop",
                                    "Checking sub clearance: " + sub.getCommon_name());
                        }
  
                        //has this substance cleared within the last 5 minutes?
                        LocalDateTime clearedAt = sub.getFullEliminationLDT();
                        if (clearedAt != null) {
                            if (NotificationService.lastNotificationLoopLDT != null) {
                                if (clearedAt.isAfter(NotificationService.lastNotificationLoopLDT) &&
                                        clearedAt.isBefore(LocalDateTime.now())) {
                                    //fire the notification
                                    try {
                                        fireSubClearedNotification(sub);
                                    } catch (Exception ex) {
                                        Log.i("Halflife.doWork", ex.toString());
  
                                        return Result.failure();
                                    }
                                }
                            }
                        }
                    }
                } else {
                    GlobalMisc.debugMsg("NotificationWorker:doWork",
                            "Would have just gone into substance clearing notification loop");
                }
            } else {
                Log.i("Halflife.notificationLoop", "In notification debugging " +
                        "mode");
  
                try {
                    fireTaperNotification(null);
                } catch (Exception ex) {
                    Log.i("Halflife.doWork", ex.toString());
  
                    return Result.failure();
                }
            }
  
            NotificationService.lastNotificationLoopLDT = LocalDateTime.now();
  
            return Result.success();
        }
  
        /**
         * Method handles the actual building of the notification regarding
         * the applicable taper, and shows it unless our handy HashMap
         * 'firedNotifications' shows that there is already a notification
         * present for this particular taper.
         *
         * @param taper the taper to display notification for
         */
        private void fireTaperNotification(Taper taper) throws Exception {
            Context ctxt = getApplicationContext();
            float currentDosageScheduled = taper.findCurrentScheduledDosageAmount();
  
            //here's the legitimate meat 'n potatoes for firing a notification
            try {
                //if we've already blown the dosage required for the next administration, just skip this
                //one
                if (currentDosageScheduled <= 0) {
                    Log.d("fireTaperNotification", "More dosage taken than needs to be " +
                            "for the current taper step; skipping this taper administration.");
  
                    return;
                }
  
                Intent intent = new Intent(ctxt, AdminData.class);
                intent.putExtra("SUB_NDX",
                        GlobalMisc.getSubListPositionBySid(taper.getSid()));
                intent.putExtra("NOTIFICATION_BASED", true);
                TaskStackBuilder stackBuilder = TaskStackBuilder.create(ctxt);
                stackBuilder.addParentStack(SubData.class);
                stackBuilder.addNextIntentWithParentStack(intent);
  
                Intent delIntent = new Intent(ctxt, NotificationDismissalReceiver.class);
                delIntent.putExtra("TAPER", true);
                delIntent.putExtra("SUB_ID", taper.getSid());
  
  
                PendingIntent pendingIntent =
                        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
                PendingIntent pendingDelIntent = PendingIntent.getBroadcast(ctxt, 0,
                        delIntent, PendingIntent.FLAG_UPDATE_CURRENT);
  
                LocalDateTime latestUsageLDT;
                LocalDateTime todaysOpeningConstraintLDT;
                boolean beforeOpeningConstraint = false;
                latestUsageLDT = Converters.toLocalDateTime(
                        Permanence.Admins.getLatestUsageTimestampBySid(taper.getSid()));
                if (taper.isConstrained()) {
                    todaysOpeningConstraintLDT =
                            LocalDateTime.now().withHour(taper.getStartHour().getHour())
                                    .withMinute(taper.getStartHour().getMinute())
                                    .withSecond(0);
  
                    if (latestUsageLDT.plus(taper.getTotalConstraintDuration()).isBefore(
                            todaysOpeningConstraintLDT)) {
                        beforeOpeningConstraint = true;
                    }
                }
  
                NotificationCompat.Builder builder = new NotificationCompat.Builder(
                        ctxt, "halflife")
                        .setContentTitle("Half-life Timer Taper " + taper.getName())
                        //note that the above line, right after "Due since: " +, will
                        //end up displaying the epoch start date for a taper on a
                        //substance that has no administrations whatsoever
                        .setSmallIcon(ctxt.getResources().getIdentifier("plus_medical_blue",
                                "drawable", ctxt.getPackageName()))
                        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                        .setContentIntent(pendingIntent)
                        .setDeleteIntent(pendingDelIntent)
                        .setAutoCancel(true);
  
                long rawTimestamp = Permanence.Admins.getLatestUsageTimestampBySid(taper.getSid());
  
                GlobalMisc.debugMsg("fireTaperNotification",
                        "Permanence.Admins.getLatestUsageTimestampBySid returns: " +
                                rawTimestamp);
  
                if (Converters.toLocalDateTime(rawTimestamp).isBefore(
                        LocalDateTime.of(1980, 1, 1, 0, 0, 0))) {
                    builder.setContentText("Due: " +
                            String.format("%.2f", currentDosageScheduled) +
                            Permanence.Subs.getUnitsBySID(taper.getSid()) + "/" +
                            Permanence.Subs.loadSubstanceById(
                                    taper.getSid()).getCommon_name() + "\n" +
                            "Due now");
                } else if (beforeOpeningConstraint) {
                    builder.setContentText("Due:" +
                            currentDosageScheduled +
                            Permanence.Subs.getUnitsBySID(taper.getSid()) + " of " +
                            Permanence.Subs.loadSubstanceById(
                                    taper.getSid()).getCommon_name() + "\n" +
                            "Due since: " +
                            LocalDateTime.now().withHour(taper.getStartHour().getHour())
                               .withMinute(taper.getStartHour().getMinute())
                               .withSecond(0));
                } else {
                    builder.setContentText("Due:" +
                            currentDosageScheduled +
                            Permanence.Subs.getUnitsBySID(taper.getSid()) + " of " +
                            Permanence.Subs.loadSubstanceById(
                                    taper.getSid()).getCommon_name() + "\n" +
                            "Due since: " +
                            Converters.toLocalDateTime(
                                    Permanence.Admins.getLatestUsageTimestampBySid(
                                            taper.getSid())).plus(
                                    Duration.ofDays(1).dividedBy(
                                            taper.getAdminsPerDay())));
                }
  
                NotificationManagerCompat notificationManager =
                        NotificationManagerCompat.from(ctxt);
  
                notificationManager.notify(1, builder.build());
  
                if (GlobalMisc.Debugging || notificationDebugging) {
                    Log.i("Halflife.fireNotification",
                            "attempted to send taper notification");
                }
            } catch (Exception ex) {
                Log.e("Halflife.fireNotification",
                        "Something broke in taper notification: " + ex.toString());
  
                throw new Exception("taper notification broke");
            }
        }
  
        private void fireSubClearedNotification(Substance sub) throws Exception {
            Context ctxt = getApplicationContext();
  
            try {
                Intent intent = new Intent(ctxt,
                        SubsRankedByLastUsage.class);
  
                PendingIntent pendingIntent = PendingIntent.getActivity(
                        ctxt, 1, intent,
                        PendingIntent.FLAG_UPDATE_CURRENT);
  
                NotificationCompat.Builder builder = new NotificationCompat.Builder(
                        ctxt, "halflife")
                        .setContentTitle("Half-life Timer Cleared: " + sub.getCommon_name())
                        .setContentText(sub.getCommon_name() + " cleared at " +
                                sub.getFullEliminationLDT().toString())
                        .setSmallIcon(ctxt.getResources().getIdentifier("plus_medical_blue",
                                "drawable", ctxt.getPackageName()))
                        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                        .setContentIntent(pendingIntent)
                        .setAutoCancel(true);
  
                NotificationManagerCompat notificationManager =
                        NotificationManagerCompat.from(ctxt);
  
                notificationManager.notify(1, builder.build());
  
                if (GlobalMisc.Debugging || notificationDebugging) {
                    Log.i("Halflife.fireNotification",
                            "attempted to send sub clearednotification");
                }
            } catch (Exception ex) {
                Log.e("Halflife.fireNotification",
                        "Something broke in sub cleared notification: " + ex.toString());
  
                throw new Exception("sub cleared notification broke");
            }
        }
    }

I would be very grateful to anybody who might be able to offer any insight on why this behavior is happening, tips on how to avoid this behavior, where to find API & other documentation on the older, deprecated JetPack work v1.0.1 library, or what I can do in Android Studio to better diagnose this issue, as attempts for debugging with what I know how to do have proven futile.

Thank you very much for your time and help on this matter!

DOES ANYONE HAVE THE FIRMWARE IN HEX FORMAT FOR THE ALCATEL IDEAL XCITE/CAMEOX 5044R

Use Sugar_QCT its Alcatels in house repair tool. Also, if you use a Linux os you can take a file with the prefix of .bin or .img and rename it to .hex then you will have the naming convention you desire, but I would use the other tool.
You can also get help including links to tool and other goodies by asking on telegram at this location:
A-Team General Discussion
Anything Alcatel, AIO ToolKit, Android, CricketRom
https://t.me/Android_General_Chat

Safe Mode made things worse

You can also tick Never ask again, or similar. This would also only happen if you had a 3rd party contacts or dialer app installed. It is probable that this is the source of your issues, You should definitely go to apps, look at Contacts and Dialer. Remove the ones that can be removed. Reboot to be sure.
Nope, the phone will not allow me to suppress this notification (other notifications, yes, not this one). I don't have a third party dialer, and it started at a time when I didn't have a third party Contacts app either. This is entirely Google: Google's Phone app, Google Play Services wanting me to give it permissions, a Pixel phone. I suspect I'm unusual in that I own a Pixel but don't use Assistant, so disallow Play Services permissions that others would grant it. It may also be that only Google's phone app interacts this way with Google Play Services. At least it's easier to ignore than when it first started, when it would beep during calls, but it does add to my impression of Google as a dishonest and self-serving corporation (though to be fair all corporations are self-serving and that usually leads them to dishonesty of some degree or other).

Notepad Huawei p9 lite to PC ?????

Hey, I felt like answering this part of the question, although it's best for notes backup.

"I learned that on EMUI versions lower than 5.1, which is mine, since it only goes to 5.0.3, do not have the sync function, ergo making it unable to sync to huawei cloud and therfore not being able to export Notepad notes. (I noticed Notepad notes can be downloaded as a zip through huawei cloud. Although there is no way for me to upload Notepad notes from my phone)."


All of the above is true, including the exporting of notes to a ZIP. But on my EMUI 5.0 device, I recently found a way to finally get to sync them to the Huawei Cloud, which enables us to use the note-exporting feature. Here's how to do it:
  1. Find an updated version of Huawei File Manager, known as the Files app on this system; I think with package name "com.huawei.hidisk". Then install it onto that old Huawei phone.
    • Aesthetically, the 10.4 version looked the best to me for the system. But you may update to the latest possible version, if it still works with Android 7.0.
    • I got my copy of the file from APKMirror, which I find safe because the owning organization has a separate site that writes app reviews. You can use other sources if you prefer.
  2. Open your Notepad app and its sidebar, and tap your profile picture to configure your Huawei Cloud. This is where the updated Files app shows that it's updating its configuration. If it says the feature is unavailable in your region again, you might need to find a newer update for the app, as in Step 1.
  3. If there are any other prompts, complete them and get to the Cloud configuration screen, then enable syncing of your notes this time. You should accept a prompt that all the notes in your Notepad app right now will be merged into your Huawei Cloud.
  4. Check your Huawei Cloud, perhaps on the web, to confirm that your notes and tags (categories in the newer versions) have been synchronized successfully.
    • If you're having a problem syncing some of your notes, you may try the workaround I've written later in this post.
  5. Once you see all your notes synchronized, you may now try to export your notes from the "Retrieve your data from Cloud" option.

I made a Huawei ID recently, and I experienced the Notepad being unable to sync before learning all of this. When I tried synchronizing there the first time, I got an email saying that I'm "logging in to an older version of HUAWEI Cloud." Through an AppGallery link, they showed me that I could update my Huawei Cloud app, but that same link said it's not available in my region. I eventually wondered what system app corresponded to the Huawei Cloud feature, and after looking through my Recents it was assigned to the Files app. That's when I got the idea that maybe I could try updating it and see what happens.

Lastly, I'm also one of those power users that want to test how well this syncing actually works. The syncing process works well, BUT you need to trigger it manually when you add notes or categories from other devices or the web. You can either:
  • Write a new, non-blank note.
  • Toggle the 'Favorite' status of one of your synced notes.
I think it's probably better to get a new Huawei phone than do this all the time.

Anyway, hope this helped someone finally migrate their notes out of their old Huawei phone.

Life on Steroids - overview

The body makes steroids naturally to support such functions as fighting stress and promoting growth and development.

But some people use steroid pills, gels, creams, or injections because they think steroids can improve their sports performance or the way they look.

Anabolic steroids are artificially produced hormones that are the same as, or similar to, androgens, the male-type sex hormones in the body. There are more than 100 variations of anabolic steroids. The most powerful androgen is testosterone (pronounced: tess-TOSS-tuh-rone). Although testosterone is mainly a mature male hormone, girls' bodies produce smaller amounts. Testosterone helps build muscle and promotes the masculine traits that guys develop during puberty, such as deepening of the voice and growth of body hair. Testosterone levels can also affect how aggressive a person is.

Help My phone will not boot stuck on START screen

ok so looks like according @MrJavi 's link, there really is no solution.....at least in that thread.

so just to be sure, you can't get into recovery mode? if you can, then you can try a factory reset.

if not then you can try flashing a firmware update:
https://forum.xda-developers.com/Mi-9/how-to/firmware-xiaomi-mi-9-t3955313
https://flashxiaomi.com/download-install-miui-rom-for-xiaomi-mi-9-all-miui-firmwares/

i do not have your phone, so i'm not very familiar with the process, unfortunately

That's right, I can't get into recovery mode. I'll look into the other links you sent.

Thank you for your help

Any Google Supported Solution for Remote Control of an Android Tablet?

Team viewer works wonderfully!, I used to access my laptop from my former S5..unlock the display remotely using different network, play music, access files..editing and so on.
The only downside was that in every session it would freeze the connection..and the laptop would became unresponsive until I manually reboot it.
The funny thing that my phone didn't freeze at all even its ram is very poor..

Other than that very helpful..

Apps Android Kotlin Billing Library 3

Hello to everyone... I am new here :)

I am trying to create a simple InApp subscription purchase as one file (all within MainActivity.kt)

Just one SKU SUB for 1 month period. Thats it

What do you think about nesting almost all the code withing one button? :)
On click ->
-Starts the BillingClientConnection
-Checks if Subscriptions Feature supported
-Then makes querySkuDetailsAsync for details about only 1 subscription
... and on received result to start the purchase flow?


I am now kinda stuck at receiving result from querySkuDetailsAsync


when (billingResult.responseCode) {

BillingClient.BillingResponseCode.OK -> {

if (skuDetailsList.orEmpty().isNotEmpty()) {

Toast.makeText(applicationContext, "Cool!", Toast.LENGTH_LONG).show()

}
else
{
Toast.makeText(applicationContext, "Not cool!", Toast.LENGTH_LONG).show()

//////////// I AM HERE NOW///////////////
// Toast shows "Not cool!"
////////////////////////////////////////////////////

}
}
}


Whole code: https://pastebin.com/eGLKjAzH



What I did until now:

-I have created developer account and merchant account.

-I have compiled the code by using "Generate Signed Bundle/Apk" where I created the new Key

-I have created the new listing for a test app in Internal test, uploaded file, and status is:

"Available to internal testers "

-I have added my test email in list with testers

-I have added my email in the list with License testers and set option "Licensed"


-I got url for downloading test app... which at the moment shows

" We're sorry, the requested URL was not found on this server. "

but ok, i guess that it is as stated... that it can take up to 48h for first time published app to become available to testers...


Probably thats why I dont receive anything in the query... Even though I am using the signed app with the same uploaded key... but... Offline version of app. I couldnt test how it works when downloaded :)



So.. While I am waiting for app to become available for download I would like to research more about the whole InApp Testing and in general InApp purchase...

So.. If it is not a broblem, to ask few more questions:

Can I use my custom key when compile app for purpose of internal test? Or I have to use public key?

Can I use my custom key when compile final app for purpose of publishing in production? Or I have to use public key?

Fatal Exception: java.lang.IllegalArgumentException width and height must be > 0 on Chromecast imple

I am trying to implement Chromecast functionality using casty sdk.

Ref: https://github.com/DroidsOnRoids/Casty

But always getting

Fatal Exception: java.lang.IllegalArgumentException width and height must be > 0

android.view.View.draw (View.java:21594)

Below is my code

//Oncreate()
casty = Casty.create(this)
.withMiniController();

casty.setOnConnectChangeListener(new Casty.OnConnectChangeListener() {
@override
public void onConnected() {
Util.showToast(getApplicationContext(), "Connected");
casty.getPlayer().loadMediaAndPlay(createSampleMediaData()...);
}

@override
public void onDisconnected() {
Util.showToast(getApplicationContext(), "Disconnected");
}
});

//Menu
@override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
casty.addMediaRouteMenuItem(menu);
getMenuInflater().inflate(R.menu.browse, menu);
return true;
}

So how can we solve it any idea? Did anyone face it?

Contacts disappearing and mixed up

I wouldn't thought of that..that's a lovely way of fixing when forgetting deletion of pesquy data..nice advice..I always practice the deleting before uninstalling(except I've forgotten once or twice)..but have never reinstalled to delete what was left behind..except for the Busybox.

Very clever!

I would love to take credit for it, but I actually learned that technique from my time here on Android Forums!

Suddenly almost always no signal with Xperia Z5

Hello, I think I might have found the solution. In my case, I realized that the "second Gsm antenna" which is located on back top of the phone moves when I press it with my finger. If I am not mistaken, it has some parts that have to touch the main board so I used a very small piece of double sided mounting tape (between the glass back of the phone and the gsm antenna) hoping that it will stick the antenna to the main board. I am testing the phone for the last 5 hours. It seems that it works.
antenna-gsm-secondary-official-xperia-Z5.jpg

Filter

Back
Top Bottom