2

您好我正在尝试在用户投入一定时间后在后台运行的服务。在那段时间之后,出现一个 alartDialog 并且用户选择的铃声响起,直到他们取消它。不幸的是,我收到一个错误,导致我的应用程序崩溃。如果您需要更多信息,请询问:)

我的服务等级

import java.util.Timer;
import java.util.TimerTask;

import org.holoeverywhere.app.AlertDialog;
import org.holoeverywhere.preference.PreferenceManager;
import org.holoeverywhere.preference.SharedPreferences;

import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;

public class CountDownService extends Service {

@Override
public void onCreate() {

    super.onCreate();
}

int hour = 990;
int min = 990;
int sec = 990;
Context c;
AlertDialog alertDialog;
SharedPreferences getPrefs;
Vibrator v;
Ringtone r;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    String input = intent.getStringExtra("timeLeft");
    String[] strArray = input.split(",");
    c = this.getApplicationContext();
    getPrefs = PreferenceManager.getDefaultSharedPreferences(c);
    v = (Vibrator) c.getSystemService(Context.VIBRATOR_SERVICE);
    build();
    for (String t : strArray) {

        if (hour == 990) {
            hour = Integer.parseInt(t);
        } else {
            if (min == 990) {
                min = Integer.parseInt(t);
            }else{
                if (sec == 990) {
                    sec = Integer.parseInt(t);
                }
            }
        }


    }

    Timer timer = new Timer();
    TimerTask tt = new TimerTask() {
        @Override
        public void run() {
            sec--;
            updateTime();
        }


    };
    timer.schedule(tt, 0, 1000);

    return START_STICKY;
}

private void build() {
    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(c);

    // set title
    alertDialogBuilder.setTitle("Time's up!!!");

    // set dialog message
    alertDialogBuilder.setMessage("Press OK to stop alarm")
            .setCancelable(true)
            .setNeutralButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {

                    if (r != null) {

                        if (r.isPlaying()) {
                            r.stop();
                        }
                    }

                    alertDialog.cancel();


                    alertDialog.cancel();
                }
            });
    alertDialog = alertDialogBuilder.create();

}

@Override
public IBinder onBind(Intent arg0) {

    return null;
}
private void updateTime() {
    if (hour  <= 0 && min  <= 0 && sec  <= 0) {
        done();

    }
    if (sec  < 0) {
        min --;
        sec  = 59;
    }
    if (min  < 0) {
        hour --;
        min  = 59;
    }

}

private void done() {
    Uri uri;

        boolean notmuted = getPrefs.getBoolean("Muted", true);
        boolean viberate = getPrefs.getBoolean("Viberate", true);
        String strRingtonePreference = getPrefs.getString("app_ringtone",
                null);
        Log.v("Alarm", "a " + strRingtonePreference);

        if (viberate) {
            v.vibrate(1000);
        }
        if (notmuted) {
            if (strRingtonePreference != null) {
                uri = Uri.parse(strRingtonePreference);
                Log.v("Alarm", "was parsed");
            } else {
                Log.v("Alarm", "was not parsed");
                uri = null;
            }
            playSound(this.getApplicationContext(), uri);
        }







}


private void playSound(Context context, Uri alert) {

    r = RingtoneManager.getRingtone(context, alert);

    if (r != null) {
        r.play();
        Log.v("Alarm", "was not null");
    } 


    alertDialog.show();

}
}

我的日志

02-10 19:13:07.875: E/AndroidRuntime(23231): FATAL EXCEPTION: Timer-0
02-10 19:13:07.875: E/AndroidRuntime(23231): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
02-10 19:13:07.875: E/AndroidRuntime(23231):    at android.os.Handler.<init>(Handler.java:121)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at android.view.ViewRootImpl.<init>(ViewRootImpl.java:371)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at android.app.Dialog.show(Dialog.java:278)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at com.chair49.holotimer.CountDownService.playSound(CountDownService.java:169)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at com.chair49.holotimer.CountDownService.done(CountDownService.java:147)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at com.chair49.holotimer.CountDownService.updateTime(CountDownService.java:113)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at com.chair49.holotimer.CountDownService.access$0(CountDownService.java:111)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at com.chair49.holotimer.CountDownService$1.run(CountDownService.java:67)
02-10 19:13:07.875: E/AndroidRuntime(23231):    at java.util.Timer$TimerImpl.run(Timer.java:284)
4

2 回答 2

0

你不能从后台线程调用 UI 的东西。您可以使用runOnUiThread()

于 2013-02-11T02:38:57.320 回答
0

我终于明白了。我必须做的是开始一个新活动并从那里创建警报对话框和声音,然后结束活动。

于 2013-02-17T21:48:36.880 回答