I'm learning the ropes with Android development, so forgive me, and I'm struggling to do something pretty fundamental.
I'm trying to fetch an image from a remote URL and put it into an ImageView. The ImageView itself is within an app widget.
But the image never loads, and a ton of errors are returned.
I created the app widget code using Android Studio's context menu, so the building blocks are, I think, sound. I created an ImageView in the app widget's layout in place of the TextView that was there by default.
Here is all the relevant code:
layout/new_app_widget.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/widget_margin" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:contentDescription="#string/content" />
</RelativeLayout>
relevant bit from NewAppWidget.java:
public class NewAppWidget extends AppWidgetProvider {
...
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
String strURL = "http://example.com/YqLOSfr4.png";
try{
URL urlURL = new URL(strURL);
HttpURLConnection con = (HttpURLConnection)urlURL.openConnection();
InputStream is = con.getInputStream();
Bitmap bmp = BitmapFactory.decodeStream(is);
views.setImageViewBitmap(R.id.imageView, bmp);
} catch(Exception e) {
e.printStackTrace();
}
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mike.widgetapptest" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
android:debuggable="true"
<activity
android:name=".MyActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".NewAppWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/new_app_widget_info" />
</receiver>
</application>
</manifest>
Related
I'm sure I'm missing something simple here but onGetViewFactory is not calling while attempting to populate a StackWidget. I've gone over this multiple times and cannot find my error.
The RemoteViewsService is being attached in updateWidget:
public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int widgetId) {
// Create the RemoteViews to represent the widget layout.
Log.i(TAG, "updateWidget: Creating RemoteViews");
RemoteViews widgetViews = new RemoteViews(context.getPackageName(), R.layout.stack_widget_layout);
// Create an intent that points to our widget service.
Log.i(TAG, "updateWidget: Creating Intent");
Intent remoteIntent = new Intent(context, StackWidgetService.class);
// Attach that intent to the RemoteViews as our remote adapter.
Log.i(TAG, "updateWidget: Setting Adapter");
widgetViews.setRemoteAdapter(R.id.stack_view, remoteIntent);
// Set which view should be used as the empty view.
Log.i(TAG, "updateWidget: Setting empty view");
widgetViews.setEmptyView(R.id.stack_view, R.id.text_empty);
// Update the widget.
Log.i(TAG, "updateWidget: Updating widget");
appWidgetManager.updateAppWidget(widgetId, widgetViews);
}
The following should be called after calling appWidgetManager.updateAppWidget but is not:
#Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
// NOT CALLED
Log.i(TAG, "onGetViewFactory: Creating new view factory");
return new StackWidgetViewFactory(getApplicationContext());
}
As far as I can tell, my manifest is correct:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".stackwidget.StackWidgetProvider"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/stack_widget_info" />
</receiver>
<service android:name=".stackwidget.StackWidgetService"
android:exported="true"
android:permission="android.permission.BIND_REMOTEVIEWS"/>
</application>
And here is my stack_widget_info.xml, for safety:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="180dp"
android:updatePeriodMillis="1800000"
android:initialLayout="#layout/stack_widget_layout"
android:autoAdvanceViewId="#layout/stack_item"
android:widgetCategory="home_screen"
android:resizeMode="horizontal |vertical">
</appwidget-provider>
The issue was actually in my widget layout. Constraint layout was causing issues. It runs correctly when changing over to Linear layout.
I am making a puzzle application that can send my picture to my friend using server.
At this timing, server gives another player an image URL and app gets that image url and makes a bitmap object using that url...
First , I tried to make it using Universal ImageLoader
Bitmap bmp = imageLoader.loadImageSync(imageUri);
But I got android.os.NetworkOnMainThreadException error that happens when Network is directly related to main UI.
my onCreate() :
Prefix pre = new Prefix();
bitmap = pre.gcmBitmap(getIntent().getStringExtra("URL"));
method pre.gcmBitmap(String url) :
public Bitmap gcmBitmap(String url){
//Bitmap bmp = imageLoader.loadImageSync(imageUri);
ImageLoader imageLoader = ImageLoader.getInstance();
//imageLoader.loadImage;
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context).build();
imageLoader.init(config);
Bitmap bitmap = imageLoader.loadImageSync(url);
//Bitmap bmp = new Bitmap();
return bitmap;
}
So
For second, I tried to make it using AsyncTask,
But at that time, at the method 'onCreate()', this method doesn't wait to get that bitmap asynchronously and return null for bitmap so made my puzzle empty...
public void getBitmapFromUrl(String url){
ImageLoader imageLoader = ImageLoader.getInstance();
//imageLoader.loadImage;
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build();
imageLoader.init(config);
imageLoader.loadImage(url, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
bitmap = loadedImage;
subOnCreate(); // do the work that should be done after getting bitmap object
}
});
So I want to know if I can solve this and how I can do that?
I'm expecting that I have to use 'onPostExecute' paradigm isn't it?
Please help me guys
my Manifest is below : I have 'INTERNET' permission!
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<permission
android:name="com.example.min.photozzle.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.min.photozzle.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity android:name=".StoryGame_4x4" />
<activity android:name=".StoryGame_5x5" />
<activity android:name=".StoryGame_6x6" />
<activity android:name=".StoryMode" />
<activity android:name=".CustomMode" />
<activity android:name=".Title" />
<activity android:name=".Setting"/>
<activity android:name=".Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.min.photozzle" />
</intent-filter>
</receiver>
<service
android:name=".GCM.RegistrationIntentService"
android:exported="false" >
</service>
<service
android:name=".GCM.MyInstanceIDListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name=".GCM.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<meta-data
android:name="com.kakao.sdk.AppKey"
android:value="#string/kakao_app_key" />
<activity
android:name=".Test"
android:label="#string/title_activity_test"
android:theme="#style/AppTheme.NoActionBar" >
</activity>
</application>
I have an application and I have also created an app widget for it. The app widget is just a shortcut to launch application.
My manifestfile:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hansem.handbookmanual"
android:installLocation="internalOnly"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:exported="true"
android:theme="#style/AppTheme" >
<receiver android:name="com.example.HandbookAppWidgetProvider" android:label="abc">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="#xml/widget1_info" />
</receiver>
<activity
android:name="com.example.BrowserLauncherActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Widget1_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="72dp"
android:minHeight="72dp"
android:minResizeHeight="72dp"
android:resizeMode="vertical"
android:updatePeriodMillis="0"
android:initialLayout="#layout/widget1">
</appwidget-provider>
Widget1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/button_applaunch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:background="#drawable/ic_launcher"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
I have tried all the solution mentioned on Stackflow but noting helped. On restarting the device, the widget gets added, but normally by just installing the app on phone and launching it, the widget is not added.
AppWidgetProviderCode:
public class HandbookAppWidgetProvider extends AppWidgetProvider {
DateFormat df = new SimpleDateFormat("hh:mm:ss");
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
Log.i("ExampleWidget", "Updating widgets " + Arrays.asList(appWidgetIds));
// Perform this loop procedure for each App Widget that belongs to this
// provider
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context, BrowserLauncherActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget1);
views.setOnClickPendingIntent(R.id.button_applaunch, pendingIntent);
// To update a label
//views.setTextViewText(R.id.widget1label, df.format(new Date()));
// Tell the AppWidgetManager to perform an update on the current app
// widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
Please help
For me I have a button widget with a button that is just suppose to launch a helloworld activity when I click it. I've tried following many posts online including this one, and yet the problem still there. I press the button, nothing happens. I am working on version 2.3 of android. Can someone point out what I am doing wrong?
My widget:
public class IconWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// first param is app package name, second is package.class of the main activity
final ComponentName cn = new ComponentName("com.followup","com.followup.FollowUpActivity");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final PendingIntent myPI = PendingIntent.getActivity(context, 0, intent, 0);
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.icon_widget_layout);
views.setOnClickPendingIntent(R.id.image_in_widget, myPI);
final AppWidgetManager mgr = AppWidgetManager.getInstance(context); mgr.updateAppWidget(cn, views);
}
}
}
homescreeniconinfo.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="0"
android:initialLayout="#layout/icon_widget_layout" >
</appwidget-provider>
icon_widget_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button android:name="#+id/image_in_widget"
android:contentDescription="#string/iconDescription"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight=".50"
android:clickable="true"
/>
</LinearLayout>
mainifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.followup"
android:versionCode="1"
android:versionName="1.0" >
.
.
.
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
.
.
.
<!-- Home icon widget -->
<receiver android:name="IconWidgetProvider"
android:label="#string/app_name"
android:icon="#drawable/ic_launcher">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/homescreeniconinfo" />
</receiver>
<activity
android:name=".FollowUpActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Have you tried adding the event handler to your button?
Perhaps I'm confused here as it's been a while since I actually did some intense android programming, but from what I understand, this is what I've done to call an intent from another one in the past...
<Button android:name="#+id/image_in_widget"
android:contentDescription="#string/iconDescription"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight=".50"
android:clickable="true"
android:onClick="onClickFunction"
/>
Paying extra attention to
android:onClick="onClickFunction"
Where "onClickFunction" would be a written method somewhere in your code that gets called when the button is clicked
public void onClickFunction(View view){
//stuff to do on click
}
EDIT
This is ripped straight from the HelloWorld android tutorial which I have compiled and successfully run on my 2.3 Android Phone in the past
this is the xml
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="sendMessage" />
this is in the main .java file
/* called when the user clicks a button */
public void sendMessage(View view)
{
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText)findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
DisplayMessageActivity.class is the class that is essentially a new application (from your case I believe you want it to be a Hello World app)
so you would make an XML for that called application and change/rewrite the DisplayMessageActivity class to do whatever "HelloWorld"-ey stuff you want...
I'm trying to make a home screen. I've got the widget to display but I need to send some kind of notify to it so it will start. Perhaps I'm missing something in the AndroidManifest.xml?
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.Fredrik" android:versionCode="1" android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".HomeScreen" android:label="#string/app_name"
android:launchMode="singleInstance" android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
HomeScreen.java:
public class HomeScreen extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final AppWidgetManager widgets = AppWidgetManager
.getInstance(getApplicationContext());
List<AppWidgetProviderInfo> installedProviders = widgets
.getInstalledProviders();
for (AppWidgetProviderInfo ws : installedProviders) {
if (ws.label.startsWith("Music (Large)")) {
AppWidgetHost h = new AppWidgetHost(getApplicationContext(), 10);
int id = h.allocateAppWidgetId();
AppWidgetHostView v= h.createView(this, id, ws);
setContentView(v);
h.startListening();
break;
}
}
}
}
Does anyone have a clue?
According to this post, you cannot program widget insertion yourself: http://groups.google.com/group/android-developers/browse_thread/thread/e4a5b4a87afcf707?pli=1
You have to call an intend that will give the user the ability to pick.
I was still surprised to hear you managed to get it to display...