我正在为我的手机编写一个android主屏幕小部件,当触摸该小部件时会打开一个URL。就是这样,URL是硬编码的,从理论上讲,我不必打开实际的应用程序。实际的应用仅显示世界问候消息,仅此而已。
不幸的是,我的HttpURLConnection
偶尔会超时。
我做什么:
在我的应用中,我有一个小部件,直到被触摸之前它什么也不做。触摸它时,将打开一个URL并根据所访问文档的内容更改颜色。
我有一个扩展AppWidgetProvider
的类,下面有完整的源代码。
我初始化RemoteViews
并调用setOnClickPendingIntent
。
点击后,我启动一个Thread
。
在线程内部,我创建了一个HttpURLConnection
和setConnectTimeout(10000)
来处理我的服务器是否关闭。
接下来,我通过调用getInputStream
进行连接,这将超时。显式调用connect
不会改变行为。
如何解决此问题:
如何使问题再次出现:
所以,我不知道问题的真正原因是什么。没有有用的例外等,因为连接只是超时。它似乎与打开应用程序时进行的初始化有关,但我不知道。有什么想法吗?
我的小部件类的代码:
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) {
}
}