I am new to android widget.I did sample application , that want to show time .How to call widget from activity:
I tried like this but It say Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.weather/com.weather.CurrentCity}; have you declared this activity in your AndroidManifest.xml?
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.weather"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="#drawable/icon" android:label="Weather">
<!-- Broadcast Receiver that will process AppWidget updates -->
<receiver android:name=".CurrentCity" 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/hello_widget_provider" />
</receiver>
<activity android:name=".WeatherActivity"
android:label="Weather Application">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
and my initail activity :
public class WeatherActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent showContent = new Intent(getApplicationContext(),CurrentCity.class);
startActivity(showContent);
}
and my widget activity:
public class CurrentCity extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1,
1000);
}
private class MyTime extends TimerTask {
RemoteViews remoteViews;
AppWidgetManager appWidgetManager;
ComponentName thisWidget;
DateFormat format = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault());
public MyTime(Context context, AppWidgetManager appWidgetManager) {
this.appWidgetManager = appWidgetManager;
remoteViews = new RemoteViews(context.getPackageName(),
R.layout.current_weather);
thisWidget = new ComponentName(context, CurrentCity.class);
}
#Override
public void run() {
remoteViews.setTextViewText(R.id.country,"Time = " + format.format(new Date()));
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
}
}
and I have created main.xml & current_weather.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView android:id="#+id/country"
android:text="TextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="10dp"
android:textColor="#color/solid_yellow"
></TextView>
</RelativeLayout>
and I created hello_widget_provider.xml.xml in the res/xml/hello_widget_provider.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="10000"
android:initialLayout="#layout/main"
/>
Please help me
Thanks in advance
What you are trying to do is effectively impossible. You do this:
Intent showContent = new Intent(getApplicationContext(),CurrentCity.class);
startActivity(showContent);
You can not invoke a widget this way: a widget does not have an Activity you can show.
You need to follow very closely the tutorial at http://developer.android.com/guide/topics/appwidgets/index.html: there is really no succinct way I can think of to convert your code into a working widget, but the guide has everything you need to know/do to make a working widget.
EDIT: note that your widget must be added to the widget container (probably the home screen) and can not be added programmatically. The user of the Android device must do it manually.
I tried to do this in many different ways. But, in Android there is no intent or similar alternative, which can invoke a widget via activity (I mean application). You have to drag the widget and drop it on your home screen.
But, yes, other ways it is possible!
Related
I have an AppWidget with a configuration activity that launches when the widget is added to the home screen. It works perfectly fine on the emulator, but when I load on a physical device, the widget is not added to the home screen after the configuration activity finishes. Both the emulator and the hardware device are a Samsung Galaxy S7, API level 23, with the app's target API set to 26.
Even if I remove all my logic and just have an empty widget and an empty configuration activity, it does not work on my device. But as soon as I remove the activity from the appwidget-provider xml tag, it works fine.
Any ideas? I'm thinking it must be something with the system settings, maybe the storage options?
I notice these errors that appear when running on the device, but they don't look directly related to the problem
E/MotionRecognitionManager: mSContextService = android.hardware.scontext.ISContextService$Stub$Proxy#e5f8725
E/MotionRecognitionManager: motionService = com.samsung.android.motion.IMotionRecognitionService$Stub$Proxy#57800fa
E/MotionRecognitionManager: motionService = com.samsung.android.motion.IMotionRecognitionService$Stub$Proxy#57800fa
Configuration Activity
public class ConfigureActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_configure);
setResult(RESULT_CANCELED);
}
public void onDoneClick(View view) {
setResult(RESULT_OK);
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, WidgetActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
sendBroadcast(intent);
finish();
}
}
Widget Activity
public class WidgetActivity extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_activity);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
#Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
#Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.widget">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:installLocation="internalOnly"
android:theme="#style/AppTheme">
<activity android:name=".ConfigureActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<receiver android:name=".WidgetActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_activity_info" />
</receiver>
</application>
</manifest>
widget_activity_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.example.widget.ConfigureActivity"
android:initialKeyguardLayout="#layout/widget_activity"
android:initialLayout="#layout/widget_activity"
android:minHeight="110dp"
android:minWidth="250dp"
android:previewImage="#drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen|keyguard">
</appwidget-provider>
I'm trying to make a very simple widget there. It seems to be somehow unregistered WidgetProvider, because no debug messages come to my LogCat (I'm sure, log filter is right, and I tried adding Toast show), as well as no errors come out.
I will be really glad of any help, because I spend few hours and tried few lessons...
I have done everything by a lesson, but changed the names and classes. There are my classes:
Provider:
public class WidgetProvider extends AppWidgetProvider {
private static final String LOGIN_CLICKED = "com.example.intent.action.LOGIN_CLICKED";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.d("my_log", "onUpdate");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
remoteViews.setOnClickPendingIntent(R.id.button_login, buildButtonPendingIntent(context, LOGIN_CLICKED));
pushWidgetUpdate(context, remoteViews);
}
public static PendingIntent buildButtonPendingIntent(Context context, String action) {
Log.d("my_log", "buildButtonPendingIntent");
Intent intent = new Intent();
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
}
Receiver:
public class WidgetReceiver extends BroadcastReceiver {
private static final String LOGIN_CLICKED = "com.example.intent.action.LOGIN_CLICKED";
#Override
public void onReceive(Context context, Intent intent) {
Log.d("my_log", "onRecieve");
if(intent.getAction().equalsIgnoreCase(LOGIN_CLICKED)){
makeLogin(context);
}
}
private void makeLogin(Context context) {
Log.d("my_log", "MakeLogin");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
//remoteViews.setImageViewResource(R.id.widget_image, getImageToSet());
//REMEMBER TO ALWAYS REFRESH YOUR BUTTON CLICK LISTENERS!!!
remoteViews.setOnClickPendingIntent(R.id.button_login, WidgetProvider.buildButtonPendingIntent(context, LOGIN_CLICKED));
WidgetProvider.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
}
}
My manifest:
<application
android:label="TwiWi Twitter Widget">
<receiver
android:name="WidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_provider" />
</receiver>
<receiver
android:name="WidgetReceiver"
android:label="widgetBroadcastReceiver">
<intent-filter>
<action android:name="com.example.intent.action.LOGIN_CLICKED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_provider" />
</receiver>
</application>
And my xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dip"
android:minHeight="146dip"
android:updatePeriodMillis="1000000"
android:initialLayout="#layout/activity_main" >
</appwidget-provider>
If you think I messed with layout or button name, there is my Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:orientation="vertical"
android:background="#android:color/white"
android:layout_gravity="center"
android:layout_height="wrap_content">
<TextView android:id="#+id/widget_textview"
android:text="Hello Widget"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal|center"
android:textColor="#android:color/black"/>
<Button
android:id="#+id/button_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center"
android:text="Button" />
</LinearLayout>
I got the answer. Still, this Example can be full exaple of simple widget for someone, nothing wrong with it.
Lol, as always, just RESTART the Eclipse...
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 am doing a simple widget for the first time and it seems the tutorial I'm using has something missing because my LogCat states "Error inflating AppWidget" when selecting it from the pop up list of widgets.
According to the tutorial I did these.
Layout:
<TextView android:id="#+id/widget_textview" android:text="#string/widget_text"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_gravity="center_horizontal|center"
android:layout_marginTop="5dip" android:padding="10dip"
android:textColor="#android:color/black" />
</LinearLayout>
Class:
package hello.widget;
import android.appwidget.AppWidgetProvider;
public class HelloWidget extends AppWidgetProvider {
}
Strings:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Hello Widget</string>
<string name="widget_text">Hello Widget!</string>
</resources>
Widget Provider:
<?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="10000"
android:initialLayout="#layout/main"
</appwidget-provider>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hello.widget" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="3" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<!-- Broadcast Receiver that will process AppWidget updates -->
<receiver android:name="hello.widget.HelloWidget" 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/hello_widget_provider" />
</receiver>
</application>
</manifest>
You are missing the opening <LinearLayout> in your layout file. What you have here should not even compile.
You are also missing the entire implementation of your AppWidgetProvider. You need to implement onUpdate() to specify what the app widget should be displaying.
Also, your updatePeriodMillis is shorter than allowed -- you cannot update an app widget every 10 seconds this way.
Also, make sure that your layout is named main.xml, or update your android:initialLayout to reflect the proper name of the layout.
My solution:
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
{
long days = (((calendar.getTimeInMillis()- date1.getTime())/1000))/86400;
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
//Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER).setComponent(new ComponentName("com.android.alarmclock", "com.android.alarmclock.AlarmClock"));
// PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, AlarmClockIntent, 0);
Intent Date_Change= new Intent(Intent.ACTION_DATE_CHANGED);
PendingIntent pendingIntent2=PendingIntent.getActivity(context,0, Date_Change, 0);
views.setOnClickPendingIntent(R.id.textView1, pendingIntent2);
views.setTextViewText(R.id.textView1,""+days);
//views.setOnClickPendingIntent(R.id.AnalogClock, pendingIntent);
//AppWidgetManager.getInstance(context).updateAppWidget(intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS), views);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisWidget = new ComponentName(context, Widget.class);
appWidgetManager.updateAppWidget(thisWidget, views);
}
}
Looked like my #$#%$%#$ the receiver was not i application element in manifest
Hi
I just created the helloworld appwidget to see how its works. i followed the dev example on adroid dev site. But for some reason the widget does not want to show in the widget list.
AndroidManifest.xml
<receiver android:name="VoiceRIAWidget" android:label="Voice RIA">
<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>
appwidget_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:label="Voice RIA" android:minWidth="50dp" android:minHeight="50dp"
android:updatePeriodMillis="86400000" android:initialLayout="#layout/appwidget">
</appwidget-provider>
VoiceRIAWidget
public class VoiceRIAWidget 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];
CharSequence text = "Hello";
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.appwidget);
views.setTextViewText(R.id.appwidget_text, text);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
}
appwidget.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/appwidget_text" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textColor="#ff000000" />
I cant see what i am missing it runs but nothing in list.
I just had the same problem. My mistake was, that i put the receiver tag just inside my manifest tag, when i was supposed to put it inside my application-tag.
This was my not-working-XML:
<manifest....>
....
<receiver ...>
...
</receiver>
<application ...>
...
</applciation>
</manifest>
This is my well-working-XML:
<manifest...>
....
<application...>
...
<receiver...>
...
</receiver>
</application>
</manifest>
Hope it helps you!
I just had the same problem. My mistake was, that I building an app widget as addition to an existing app which was installed on sd-card. Moving the app to phone fixed it.
faced the similar problem . I was putting meta data outside the receiver which you have already done correctly in first place.