Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3990108
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T06:27:16+00:00 2026-05-20T06:27:16+00:00

Edit: here’s the source on PasteBin. I feel like I might need to just

  • 0

Edit: here’s the source on PasteBin. I feel like I might need to just redesign the entire Service.. 🙁

I’m the developer of RingPack. The basic idea is that there is a Service launched in the background that takes care of switching the ringtone out for the user. I’m having issues with losing my reference to an ArrayList within the Service. I think I may be misunderstanding how the lifecycle works. My intent was for it to be started whenever the user selects a pack from the Activity.

Intent i = new Intent(RingActivity.this, RingService.class);
i.putExtra(RingService.ACTION, RingService.PACK_SET);
i.putExtra(RingService.PASSED_PACK, currentPackId);
RingActivity.this.startService(i);

I tell the Service to set the Default Notification Tone to the first tone of the pack corresponding to “currentPackId”.

When the user wants to turn off RingPack, the disabling is done like so:

Intent i = new Intent(RingActivity.this, RingService.class);
RingActivity.this.stopService(i);

Toast.makeText(RingActivity.this.getBaseContext(), RingActivity.this.getString(R.string.ringPackDisabled), Toast.LENGTH_SHORT).show();

So the Service’s onCreate looks like so:

public void onCreate() {
db = new DbManager(this);
db.open();

vib = (Vibrator) getSystemService(VIBRATOR_SERVICE);

IntentFilter intentFilter = new IntentFilter(Intent.ACTION_TIME_TICK);
registerReceiver(tReceiver, intentFilter);
timeTick = 0;

//figure out the widget's status
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
widgetEnabled = prefs.getBoolean(WIDGET_ALIVE, false);

//save the ringtone for playing for the widget
Uri u = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
r = RingtoneManager.getRingtone(this.getBaseContext(), u);
playAfterSet = false;

super.onCreate();}

Then it passes it off to onStartCommand, which returns START_NOT_STICKY (since I will be creating and destroying the Service manually), who passes it off to handleStart().

@Override private void handleStart(Intent intent) {     
final Intent i = intent;
if (isSdOk()) {
    int action = i.getIntExtra(ACTION, -1);

    if (action != -1) {
        if (action == PACK_SET) {
            playAfterSet = true;

            Thread packSetThread = new Thread() {
                @Override
                public void run() {
                    int passedPackId = i.getIntExtra(PASSED_PACK, -1);
                    //we were passed the id
                    if (passedPackId != -1) {
                        checkPrefs();

                        if (!enabled)
                            initControl(passedPackId);
                        else
                            setPack(passedPackId);

                        packSetHandler.sendEmptyMessage(0);
                    }
                }
            };
            packSetThread.start();
        }
        else if (action == NEXT_TONE) {
            checkPrefs();
            swapTone();
        }
        else if (action == PLAY_TONE) {
            playCurrentTone();
        }
        else if (action == WIDGET_STATUS) {
            widgetEnabled = intent.getBooleanExtra(WIDGET_ALIVE, false);
            if (toneName != null)
                RingWidget.update(getBaseContext(), toneName);
        }
    }
}}

The isSdOk() method just checks if the SD card is mounted, since the ringtones are stored on it. initControl() just saves the user’s default ringtone, so that we can give it back when they disable us. The setPack() method looks like this:

private void setPack(int packId) {
//save the current pack id in the prefs for restarting
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(RingService.this.getBaseContext());
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(SAVED_PACKID, packId);
editor.commit();

//get the info we need to work with this pack
//it's path on the SD
//build the tones ArrayList to work from
grabPath(packId);
if (tones == null)
    tones = new ArrayList<Integer>();
else
    tones.clear();
mapTones(packId);
currIndex = 0;
setNotificationTone(tones.get(currIndex));}

The tones ArrayList is what I’ve been losing. This is where it is initialized. It holds the ids of all the enabled ringtones within a pack. The NullPointerException I’ve been seeing is in swapTone():

private void swapTone() {
//locked
if (lockPref)
    return;
//shuffle on
else if (shufflePref) {
    int randIndex = currIndex;

    while (randIndex == currIndex)
        randIndex = (int) Math.floor(Math.random() * tones.size());
    currIndex = randIndex;
}
//shuffle off
else {
    if (currIndex != (tones.size() - 1))
        currIndex++;
    else
        currIndex = 0;
}

setNotificationTone(tones.get(currIndex));}

They way I intended it work is for swapTone() to never be called if setPack() hasn’t already. Again, my users keep getting this error, but I can’t reproduce it myself. Any help would be greatly appreciated. I apologize for the code wall, but I am very confused. Perhaps I’m not using the concept of a Service correctly?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T06:27:17+00:00Added an answer on May 20, 2026 at 6:27 am

    Well, despite the “code wall”, your listings are incomplete (e.g., you say your problem is with tones but never show where it is defined). I am going to take a guess that it is a data member of your Service.

    In that case, it will be null if the service was stopped between PACK_SET and NEXT_TONE operations. This can easily occur, if Android stops the service because it has been running too long. Even with START_NOT_STICKY, if the next startService() call after Android stops the service is NEXT_TONE, not PACK_SET, you will have this problem.

    IOW, your data model (the chosen ring pack) is not stored in a persistent location, but rather is held in RAM (tones). You have two choices:

    1. Try to figure out a way that you do not need to be an always-running service, and load the tones out of a persistent store (e.g., database) as needed. This would be ideal, as you are chewing up a bunch of RAM while not delivering value for that RAM every microsecond. For example, you could use AlarmManager with an IntentService.

    2. Use startForeground() to make it less likely that Android will stop your service. The trade-off is that you will need to place a Notification on the screen, so the user knows you are constantly running. You might make that Notification lead the user to the activity where they can configure or shut down the service.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I feel like I'm missing something simple here (as usual). I'm trying to read
Edit: The code here still has some bugs in it, and it could do
edit: many thanks for all the answers. Here are the results after applying the
Edit: This question was written in 2008, which was like 3 internet ages ago.
EDIT What small things which are too easy to overlook do I need to
EDIT: Here is my updated code: #!/bin/sh files=`ls` if [ $# -ne 1 -o
Edit Here is the proper way to do it, and the documentation : import
Edit: Here is the new code: $(#normalcontent).hide(fast).load($this.attr(href) + #normalcontent,,function(){ $(this).slideDown(normal); $(this).find(img).each(function(){ if($(this).hasClass(large)) { var
How can I expand the whole TreeView in Silverlight? EDIT: Here is the XAML
Take a look here . It's a really neat project. I am just wondering

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.