I tried to create clickable widget on android. I was looking for solution on this site and I found it, but finally this widget is working only on the emulator - not on real phone. This is my code:
AppWidgetProvider:
public static String WIDGET_BUTTON = "apps.test.widget.WIDGET_BUTTON";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.main);
Intent clickIntent = new Intent(WIDGET_BUTTON);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.imageView1, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (WIDGET_BUTTON.equals(intent.getAction())) {
Toast.makeText(context, "asdfsdgdasfg", Toast.LENGTH_SHORT).show();
}
}
Manifest:
<application
android:allowBackup="true"
android:icon="#drawable/image"
android:label="#string/app_name" >
<receiver
android:name=".Widget"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="apps.test.widget.WIDGET_BUTTON"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/test_widget_provider" />
</receiver>
</application>
Toast is showing up on the emulator but not on phone.
Ok, nevermind.
I had to reset the phone to factory settings. I don't know what was wrong.
This is a common issue,had it a few times with my phone , if the app is installed on sdcard instead of internal storage ,the widget does not appear on the list,
you can simply go to Settings->apps->find the app and then select the option to move it to internal storage from your android itself.
[http://www.technipages.com/fix-android-app-widgets-not-appearing-on-widget-list][1]
There is another way to declare in the manifest as android:externalstorage(syntax isnt correct) which works as well (I cant find the link though to the answer and I have not tried it)
Related
Update: Solved it, solution below
I'm trying to write a widget that starts a service, which then will do some stuff not implemented yet. So far my service is only that:
public class SmartWifiService extends Service {
private static final String WIDGET_CLICK = "de.regenhardt.smartwifiwidget.WIDGET_CLICK";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.e("DEBUG", "Service started");
Toast.makeText(getApplicationContext(), "Widget clicked", Toast.LENGTH_SHORT).show();
stopSelf();
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
So everything it does is send a Toast and stop itself after that.
Unfortunately, it doesn't come to that. My Provider looks like that:
public class SmartWifiWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.e("DEBUG", "onUpdate called");
super.onUpdate(context, appWidgetManager, appWidgetIds);
Intent clickIntent = new Intent(context, SmartWifiWidgetProvider.class);
clickIntent.setAction("de.regenhardt.smartwifiwidget.WIDGET_CLICK");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(),
0, clickIntent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.layout, pendingIntent);
//for (int ID:appWidgetIds) {
// views.setOnClickPendingIntent(ID, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
//}
#Override
public void onReceive(Context context, Intent intent) {
Log.e("DEBUG", "received");
super.onReceive(context, intent);
if(intent.getAction().equals("de.regenhardt.smartwifiwidget.WIDGET_CLICK")){
Log.e("DEBUG", "Click action fits");
Intent i = new Intent(context.getApplicationContext(), SmartWifiService.class);
context.startService(i);
}
}
}
I went through several answered questions here, changed stuff, added stuff, and so far nothing really worked, and I still have no idea why.
When I click the Widget there is no animation, but I'm pretty sure my widget itself is clickable:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/layout"
android:clickable="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/wifi"
android:clickable="true"
android:id="+id/widgetImage"/>
</LinearLayout>
Also tried it with ImageButton, no change in effect.
I hope you guys can help me, I have been sitting in this little thing for days and my head is spinning (not literally).
Greetings,
Marlon
Edit: Here's my Manifest:
<application android:allowBackup="true"
android:label="#string/app_name"
android:icon="#drawable/wifi"
android:theme="#style/AppTheme">
<receiver android:name=".SmartWifiWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="de.regenhardt.smartwifiwidget.WIDGET_CLICK"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/smart_wifi_widget_info"/>
</receiver>
<service android:name="de.regenhardt.smartwifiwidget.SmartWifiService"/>
</application>
Edit 2: Update; updated to current state of my code, adapted to Y.S.' answer.
LogCat after adding the widget, clicking it still doesn't do anything:
04-08 20:12:30.985 14867-14867/de.regenhardt.smartwifiwidget E/DEBUG﹕ received
04-08 20:12:30.998 14867-14867/de.regenhardt.smartwifiwidget E/DEBUG﹕ received
04-08 20:12:30.998 14867-14867/de.regenhardt.smartwifiwidget E/DEBUG﹕ onUpdate called
04-08 20:12:31.155 14867-14867/de.regenhardt.smartwifiwidget E/DEBUG﹕ received
Solution:
The blowing line was views.setOnClickPendingIntent(R.id.widgetImage, pendingIntent);, I had R.id.layout instead of widgetImage there. It seems a widget doesnt hand the click through to views below if it doesnt get handled.
The Problem:
To start a Service in this way, you need to use PendingIntent.getBroadcast(), not PendingIntent.getService(). And the WIDGET_CLICK action needs to be specified in the app manifest under the receiver tag, not the service tag.
STEP 1:
Replace
Intent clickIntent = new Intent("de.regenhardt.smartwifiwidget.WIDGET_CLICK");
with
Intent clickIntent = new Intent(context, SmartWifiWidgetProvider.class);
clickIntent.setAction("de.regenhardt.smartwifiwidget.WIDGET_CLICK");
STEP 2:
Replace
PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(),
0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
with
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(),
0, clickIntent, 0);
STEP 3:
In the manifest, add the action to the receiver tag and remove it from the service tag:
<application android:allowBackup="true"
android:label="#string/app_name"
android:icon="#drawable/wifi"
android:theme="#style/AppTheme">
<receiver android:name=".SmartWifiWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="de.regenhardt.smartwifiwidget.WIDGET_CLICK"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/smart_wifi_widget_info"/>
</receiver>
<service android:name="de.regenhardt.smartwifiwidget.SmartWifiService"></service>
</application>
STEP 4:
Set the PendingIntent on the RemoteViews in your widget:
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.widgetImage, pendingIntent);
STEP 5:
Override the onReceive() method of the SmartWifiWidgetProvider class:
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals("de.regenhardt.smartwifiwidget.WIDGET_CLICK")) {
Intent i = new Intent(context.getApplicationContext(), SmartWifiService.class)
startService(i);
}
}
Try this. This should start the Service correctly.
You should add your service into manifest:
<service android:name="SmartWifiService"></service>
You didn't say how you are calling service, so I could say that need to call startService(Intent) from some Activity - it would not start without that.
I am for the first time checking how to make a widget app. The first thing I want to do is add a widget to the home screen, a basic textview with a static text. Nothing else.
After reading the guide I tried to construct one. I get to the point that the widget is listed by the system, I run normally the configuration activity. But when I drag and drop the widget to the homescreen, nothing happens. I don't know where to debug, when I do debug my Widgetprovider class all looks fine (resources are not null, view gets updated) so I don't know where to look for an error message.
What is wrong?
At least some direction on where to look would be very appreciated!
Here's the manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tizanacode.ExJakdojade">
<application android:allowBackup="true"
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme">
<activity
android:name="WidgetConfigurationActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:icon="#drawable/ic_launcher"
android:label="Watched Line"
android:name="ExJakdoJade" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/ex_jakdojade_info" />
</receiver>
</application>
Here is the provider class:
public class ExJakdoJade extends AppWidgetProvider {
private static final String ACTION_CLICK = "ACTION_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context,
ExJakdoJade.class);
/*int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {*/
for (int widgetId : appWidgetIds) {
// Create some random data
int number = (new Random().nextInt(100));
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.layout);
Log.w("WidgetExample", String.valueOf(number));
// Set the text
remoteViews.setTextViewText(R.id.update, String.valueOf(number));
// Register an onClickListener
Intent intent = new Intent(context, ExJakdoJade.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
}
In my application, I have a Fragment which is attached to the main activity. This Fragment displays data with the help of an adapter. In the adapter, I have inflated a layout which has a clickable text "Watch From Home". The adapter displays data from the server. I want to show the same data on the home screen and when I click on the "Watch From Home" text, a home screen widget should be created without any user interaction.
I made a receiver MyWidgetProvider.What should the method onClickText() for "Watch From Home" have so that it takes me to the widget? I must admit, I am new to android. Thanks
Android Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pack.android.receiver"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="#drawable/icon"
android:label="#string/app_name" >
<receiver android:name="MyWidgetProvider" >
<intent-filter >
<action
android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
MyWidgetProvider.Java file
public class MyWidgetProvider extends AppWidgetProvider {
private TextView team1Name;
private TextView team2Name;
private TextView team1Score;
private TextView team2Score;
public static boolean widgetView=false;
private static final String LOG = "com.playup.android.receiver";
public MyWidgetProvider(TextView team1Name, TextView team2Name, TextView team1Score, TextView team2Score){
this.team1Name=team1Name;
this.team2Name=team2Name;
this.team1Score=team1Score;
this.team2Score=team2Score;
initializeViews();
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
Log.w(LOG, "onUpdate method called");
// Get all ids
ComponentName thisWidget = new ComponentName(context,MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
// Update the widgets via the service
context.startService(intent);
}
public void initializeViews(){
// team1Name= (TextView)content_layout.findViewById(R.id.team1Name);
}
}
UpdateWidgetService
public class UpdateWidgetService extends Service {
private static final String LOG = "com.playup.android.receiver";
#Override
public void onStart(Intent intent, int startId) {
Log.i(LOG, "Called");
// Create some random data
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// Create some random data
int number = (new Random().nextInt(100));
RemoteViews remoteViews = new RemoteViews(this
.getApplicationContext().getPackageName(),0x7f030061); //Since R could not be resolve, I used the generated ids
Log.w("Widget", String.valueOf(number));
// Set the text
remoteViews.setTextViewText(0x7f0a022a,"Random: " + String.valueOf(number));
// Register an onClickListener
Intent clickIntent = new Intent(this.getApplicationContext(),MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent,PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(0x7f0a022a, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
stopSelf();
super.onStart(intent, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
Simply saying, You can't create a home widget without any user interaction.
Update:
Your receiver tag should start like this:
<receiver
android:name=".MyWidgetProvider"
android:label="My widget label" >
<!-- The rest as is -->
</receiver>
Home Screen Widget can only add to Home Screen directly by user.Only user can add widget as guest to Home Screen or other applications.
Edit:
To see your widget in widgets list:
It is necessary that register your AppWidgetProvider in manifest.
Your App has to have Launcher/Main Activity,and App must be directly run by user,before it be visible in widgets list.This is necessary ,because no broadcastreceiver(and so no AppWidgetProvider),no service,... of your App could not register before your App run directly by user.If you look at your manifest,you will see that your App has no Launcher/Main Activity(it has only a receiver),so it can not run by user and your AppWidgetProvider(that is a broadcastreceiver) will not register and thereupon you can not see your widget in widget list.
This had me scratching my head for a while.
I had the meta-data tag as child of the intent-filter tag, which is wrong. The meta-data is to be child of the receiver tag.
Incorrect version
<receiver
android:name=".AppWidgetReceiver"
android:label="AppWidgetReceiver" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/appwidget_info" />
</intent-filter>
</receiver>
Following is the correct version
<receiver android:name=".AppWidgetReceiver"
android:label="AppWidgetReceiver" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/appwidget_info" />
</receiver>
I am making a simple app widget that displays a toast message when a button in the widget is touched. The issue I am having is that the toast never appears when the button is clicked. In fact, the onReceive event is never fired when the button is touched. I suspect the issue has to do with my manifest, but it looks ok to me.
Here is the relevant portions of my manifest:
<receiver android:name=".GPSWidget" android:label="GPS Receiver">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="luke.app.steal.GPSWidget.ACTION_WIDGET_RECEIVER"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_provider" />
</receiver>
Here is the code to "wire up" the button to an event listener, as well as the onReceive event it is in a class called GPSReceiver.
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(ACTION_WIDGET_RECEIVER)) {
Toast.makeText(context, "Button hit", Toast.LENGTH_SHORT).show();
}
super.onReceive(context, intent);
}
#Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
{
RemoteViews remoteViews;
remoteViews = new RemoteViews( context.getPackageName(), R.layout.gpswidget );
remoteViews.setTextViewText( R.id.widgetTexts, "Click Me!");
Intent inte = new Intent(context, lukeService.class);
inte.setAction(ACTION_WIDGET_RECEIVER);
PendingIntent configPendingIntent = PendingIntent.getBroadcast(context, 0, inte, 0);
remoteViews.setOnClickPendingIntent(R.id.widgetTexts, configPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews );
}
widgetTexts is the button that should be launching the toast, but like I said nothing happens when the button is hit. I thought that my path in the manifest was wrong, luke.app.steal, but that same path works just fine for all my other activities.
Anyone got any ideas? or need more info?
I have developed an application that makes use of a widget. The widget could be added in the homescreen and used as a button. I have recently downgraded the version to <uses-sdk android:minSdkVersion="7" /> and no errors were spotted. However, now when i reinstall the, the widget is not responsive. In addition when I try to install the app on another phone running android 4.0.3, widget is not available anywhere, so i cannot even add it to the homescreen. Here is my code for the widget:
public class MyWidget extends AppWidgetProvider {
#Override
public void onUpdate(Context c, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
final int N = appWidgetIds.length;
//for each of the instances of the widget
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(c.getPackageName(), R.layout.widget_layout);
Intent fireDialog = new Intent(c,Execute.class);
PendingIntent pendingIntent = PendingIntent.getActivity(c, 0, fireDialog, 0);
views.setOnClickPendingIntent(R.id.myButton, pendingIntent); //when the button is clicked, an activity is launched
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context c, Intent intent)
{
final String action=intent.getAction();
if(AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)){
final int appWidgetId=intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
if(appWidgetId!=AppWidgetManager.INVALID_APPWIDGET_ID){
this.onDeleted(c,new int[]{appWidgetId});
}
}else{
super.onReceive(c, intent);
}
}
}
Here is the manifest.xml:
<application>
<receiver android:name=".myButton"
android:icon="#drawable/icon"
android:label="myWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/my_xml" />
</receiver>
</application>