Я пишу виджет домашнего экрана 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) {
}
}