HttpURLConnection тайм-аут для виджета без открытия приложения - PullRequest
0 голосов
/ 04 октября 2018

Я пишу виджет домашнего экрана Android для своего телефона, который при касании открывает URL-адрес.Вот и все, URL-адрес жестко запрограммирован, и теоретически мне никогда не нужно открывать реальное приложение.Фактическое приложение показывает только привет сообщение мира и ничего более.

К сожалению, мой HttpURLConnection иногда делает тайм-аут.

Что я делаю:
В моемПриложение У меня есть виджет, который ничего не делает, пока не коснулся.При касании он открывает URL и меняет цвет в соответствии с содержимым документа, к которому был осуществлен доступ.
У меня есть класс, расширяющий AppWidgetProvider, полный исходный код ниже.
Я инициализирую RemoteViews и вызываю setOnClickPendingIntent.
При нажатии я запускаю Thread.
Внутри потока я создаю HttpURLConnection и setConnectTimeout(10000) для обработки, если мой сервер не работает.
Далее я подключаюсь, вызывая getInputStream, чтотайм-аут.Вызов connect явно не меняет поведение.

Как решить проблему:

  • Либо откройте приложение
  • Илиподключите USB-кабель, подключенный к моему ПК разработчика.Это не запускает приложение, но, вероятно, подключает мой телефон к Android Studio для отладки.

Как заставить проблему появиться снова:

  • Любойудалить и переустановить приложение, даже не открывая его.Разместите виджет на главном экране, коснитесь его и просмотрите время ожидания.
  • Или подождите.Я не знаю, как долго, между неделями и месяцами.Через некоторое время проблема вернется.Это очень затрудняло воспроизведение и отладку, особенно потому, что это было исправлено после того, как я подключил свой USB для чтения отладочных сообщений.

Итак, я понятия не имею, какова реальная причина проблемы.Нет никаких полезных исключений и т. Д., Потому что время соединения просто истекло.Кажется, что-то связано с инициализацией, которая выполняется при открытии приложения, но я не знаю.Есть идеи по этому поводу?

Код класса моего виджета:

package [censored for privacy];

import [all the classes]

public class UnlockWidget extends AppWidgetProvider {

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
    super.onUpdate(context, appWidgetManager, appWidgetIds);
    for(int i = 0; i < appWidgetIds.length; ++i)
    {
        RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.unlock_widget);
        remoteView.setOnClickPendingIntent(R.id.layout, getPendingSelfIntent(context, MyOnClick));
        appWidgetManager.updateAppWidget(appWidgetIds[i], remoteView);
    }
}

public void onReceive(Context context, Intent intent)
{
    if (MyOnClick.equals(intent.getAction()))
    {
        final Context myContext = context;
        new Thread(new Runnable() {
            public void run() {

                RemoteViews views = new RemoteViews(myContext.getPackageName(), R.layout.unlock_widget);
                views.setInt(R.id.layout, "setBackgroundColor",
                        Color.argb(128, 0, 0, 255));
                views.setTextViewText(R.id.clicktext, "...");
                AppWidgetManager.getInstance(myContext).updateAppWidget(new ComponentName(
                        myContext, UnlockWidget.class), views);

                String result = new String();
                try
                {

                    boolean redo;
                    do
                    {
                        redo = false;
                        URL url = new URL("https://[censored for privacy]");
                        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                        urlConnection.setConnectTimeout(10000);
                        try {
                            Scanner s = new Scanner(new BufferedInputStream(urlConnection.getInputStream())).useDelimiter("\\A");
                            result = s.hasNext() ? s.next() : "fail";
                        } catch (java.net.SocketTimeoutException e) {
                            redo = true;
                        } finally {
                            urlConnection.disconnect();
                        }
                    }
                    while(redo);
                }
                catch(Exception e)
                {
                    result = e.toString();
                    e.printStackTrace();
                }

                if(result.startsWith("ok"))
                {
                    result = new String();
                    views.setInt(R.id.layout, "setBackgroundColor",
                            Color.argb(6, 0, 0, 0));
                    try {
                        Ringtone r = RingtoneManager.getRingtone(myContext, RingtoneManager.getDefaultUri(
                                RingtoneManager.TYPE_NOTIFICATION));
                        r.play();
                        Vibrator v = (Vibrator) myContext.getSystemService(Context.VIBRATOR_SERVICE);
                        v.vibrate(2000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                else
                {
                    views.setInt(R.id.layout, "setBackgroundColor",
                            Color.argb(64, 255, 0, 0));
                }

                views.setTextViewText(R.id.clicktext, result);
                AppWidgetManager.getInstance(myContext).updateAppWidget(new ComponentName(
                        myContext, UnlockWidget.class), views);

            }
        }).start();
    }
    else
        super.onReceive(context, intent);

};

private static final String MyOnClick = "myOnClickTag";

protected PendingIntent getPendingSelfIntent(Context context, String action)
{
    Intent intent = new Intent(context, getClass());
    intent.setAction(action);
    return PendingIntent.getBroadcast(context, 0, intent, 0);
}

@Override
public void onEnabled(Context context) {
}

@Override
public void onDisabled(Context context) {
}

}

...