Android Widget onClick not working - Service won't start - android

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.

Related

Android - Clickable Widget - Working on emulator, but not on phone

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)

Android Widget Button Click Toast Maessage

I've created a simple widget have only a button and textView. When I add my widget first time to the homescreen a FC message coming and widget will added. And button click toast message won't work. Only i need to have a toast message when clicking the widget button. I've gone through lots of tutorials but couldn't figure out whats the problem. Any genius who'd like to help..really appriciate the help..Thanks..
widgetProvider.java
public class widgetProvider extends AppWidgetProvider{
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, widgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
views.setOnClickPendingIntent(R.id.button1, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
Toast.makeText(context, "Button Clicked", Toast.LENGTH_SHORT).show();
}
}
}
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".widgetProvider" android:label="#string/app_name">
<intent-filter >
<action
android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widgetprovider" />
</receiver>
</application>
your onUpdate is never called since you overriden the onReceive method.

Android: Widget onReceive() not getting called

I have a widget whose layout has an imageView. The view needs to be changed based on some activity. So, whenever that happens, I am calling a sendBroadcast() with the action set to UPDATE_WIDGET. However, the onReceive() in the widget code is not getting called. Below is my code.
public class TaskWidget extends AppWidgetProvider {
...
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "widget update", 2000).show();
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.searchwidget);
if (intent.getAction().equals(UPDATE_WIDGET)) {
views.setImageViewResource(R.id.newImage, R.drawable.Pic1);
}
super.onReceive(context, intent);
}
}
In the manifest,
<receiver
android:name="com.rahul.testwidget.TaskWidget"
android:label="Task Widget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.rahul.UPDATE_WIDGET" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget" />
</receiver>
you have to update your widget layout
use this code just befor super.onReceive(context, intent);
ComponentName widget = new ComponentName(context, SimpleWidget.class);
AppWidgetManager.getInstance(context).updateAppWidget(widget, views);
I think your action name must be com.rahul.UPDATE_WIDGET instead of UPDATE_WIDGET.
If you are sending the broadcast from a listener on your widget you need to create a PendingIntent for a Broadcast.
PendingIntent sentPI = PendingIntent.getBroadcast(activity, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
Also, you don't seem to be able to attach 2 pending intents to a button in the widget.

Android App Widget button click not working properly

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?

Android alarm not being triggered

I"m sure this is something that is simple, but I'm not figuring it out. I'm trying to make a simple repeating alarm and it never gets triggered. What I have is:
private void setupAlarms()
{
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, RepeatingAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(HelloAndroid.this, 0, intent, 0);
GregorianCalendar fifteenSeconds = (GregorianCalendar)Calendar.getInstance();
fifteenSeconds.add(Calendar.MINUTE, 0);
fifteenSeconds.set(Calendar.SECOND, 15);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), fifteenSeconds.getTimeInMillis(), pendingIntent);
}
This is called from the main onCreate call.
My alarm receiver:
public class RepeatingAlarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, R.string.hello, Toast.LENGTH_SHORT).show();
}
}
In my manifest, I have added:
<receiver android:name=".RepeatingAlarm" android:process=":remote" />
Any help, much appreciated
Have you added an intent filter to your BroadcastReceiver?
Code might look something like this in your AndroidManifest.xml file:
<receiver android:name=".RepeatingAlarm" android:exported="true">
<intent-filter>
<action android:name="intent id text" />
</intent-filter>
</receiver>
and when creating your intent do something like this:
Intent intent = new Intent("intent id text")
where the "intent id text" can be any string you use to identify your intent. Also Android alarms get reset if you reboot your device so that may be something you need to look into.
Hope this helps.

Categories

Resources