Hi I am making Android application and I want to make a widget for it. The concept of application is that it gets stt(speech-to-text) string from 'Voicemain_Activity' and put string to created field in 'AddActivity'.And in 'AddActivity' there are a button to call 'Voicemain_Activity'. I was trying to make it to start 'Voicemain_Activity'. So I made widget codes like this.
public class MyAppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
//CharSequence widgetText = context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget);
// views.setTextViewText(R.id.appwidget_text, widgetText);
Intent intent=new Intent(context, AddActivity.class);
PendingIntent pe=PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.imageButton_voice, pe);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context,appWidgetManager,appWidgetIds);
// There may be multiple widgets active, so update all of them
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
}
}
the 'AddActivity' that makes to get 'Voicemain_Activity' looks like this.
#Override
public void onClick(View v) {
int view = v.getId();
if(view == R.id.Bacode){
finish();
}
else if(view == R.id.Voice){
startActivityForResult(new Intent(this, VoiceMain_Activity.class), MY_UI);
}
}
But this code made the widget to just show me the 'Voicemain_Activity' screen and didn't get the string nor put it to 'AddActivity'. How can I make it to work?
Related
Introduction
I'm trying to make a widget for school as homework. It is done for Android SO and coded in Java. I'm pretty new to this so I had to read A LOT of documentation, specially from their main Website for Android Devs, I'm not that interested in Android developing so a quick and solid answer is more than welcome.
Problem
I'm sending a name and ID from a WidgetConfig class (an Activity) using an Intent to the widget. This data is supposed to be written on the TextView from the widget layout but for some reason it does not.
In this code below you may see my attempt, if you tested the program from the repository that I will provide you are going to see that it is not properly updated.
So my question is:
How I can manage to update my widget from data sent from an activity?
public class FerrixWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.ferrix_widget);
//views.setTextViewText(R.id.appwidget_text, widgetText);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
RemoteViews spm = new RemoteViews(context.getPackageName(), R.layout.ferrix_widget);
spm.setTextViewText(R.id.alumnoName, "plsupdate");
}
//This is called to update the App Widget at intervals defined by the updatePeriodMillis attribute
// in the AppWidgetProviderInfo.
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
//This is called when an instance the App Widget is created for the first time.
#Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
System.out.println("[INFO] FIRST INSTANCE CREATED");
}
//This is called when the last instance of your App Widget is deleted from the App Widget host.
#Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
//This is called for every broadcast and before each of the above callback methods.
#Override
public void onReceive(Context context, Intent intent) {
RemoteViews controles = new RemoteViews(context.getPackageName(), R.layout.ferrix_widget);
String alumnoName = intent.getStringExtra("Name"); //Gets the intent withthe key "Name"
System.out.println("[INFO] Key: Name gets result: " + alumnoName);
controles.setTextViewText(R.id.alumnoName, alumnoName);
controles.setTextViewText(R.id.claseName, "DAM2");
System.out.println("[INFO] Context: " + context);
System.out.println("[INFO] Received: " + intent.getAction().toString());
}
}
Full code at
https://gitlab.com/JonaFerre/ferrixwidget
My goal
I want that when you set tup the widget on your screen it pops up a config screen (it does that already), then you insert your name and class, this data is sent over to the widget (via Intent) so it gets written and shown alongside the time of the day and some other stuff (That I will add once I get this properly solved)
Notes:
IDE: Android Studio
Andriod: v15
You can easily fix this by updating your widget in widget's onReceive:
Just send a broadcast from configuration activity:
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences prefs = getSharedPreferences("WidgetPrefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("msg_" + widgetId, nameInput.getText().toString()); //???
editor.commit();
//Actualizar el widget tras la config
System.out.println("[INFO] Getting instance of WidgetConfig");
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(WidgetConfig.this);
System.out.println("[INFO] Updating the widget");
FerrixWidget.updateAppWidget(WidgetConfig.this, appWidgetManager, widgetId);
//Devolver un buen OK
Intent resultado = new Intent();
resultado.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
//System.out.println("[CONFIG INFO] Name text is: " + nameInput.getText().toString());
resultado.putExtra("Name", nameInput.getText().toString());
resultado.setAction("myUpdate");
ComponentName componentName = new ComponentName(getApplicationContext(), FerrixWidget.class);
resultado.setComponent(componentName);
sendBroadcast(resultado);
setResult(RESULT_OK, getIntent());
finish();
System.out.println("[INFO] OK devuelto!");
}
});
and on widget's onReceive
public void onReceive(Context context, Intent intent) {
if(intent.getAction() != null && intent.getAction().equals("myUpdate")) {
RemoteViews controles = new RemoteViews(context.getPackageName(), R.layout.ferrix_widget);
String alumnoName = intent.getStringExtra("Name"); //Gets the intent withthe key "Name"
int id = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
System.out.println("[INFO] Key: Name gets result: " + alumnoName);
controles.setTextViewText(R.id.alumnoName, alumnoName);
controles.setTextViewText(R.id.claseName, "DAM2");
AppWidgetManager.getInstance(context).updateAppWidget(id, controles);
System.out.println("[INFO] Context: " + context);
System.out.println("[INFO] Received: " + intent.getAction().toString());
} else {
super.onReceive(context, intent);
}
}
But the better way is to save your data and widget's id in db/preference and just update on widget's side in onUpdate.
Please, just read official doc. There a lot of stuff that can helps you.
I created a widget, which was working quite fine, and then I changed targetSDK from 23 to 26, due to the requirement from Google Play Developer Console.
After switching to Android SDK 26, my app widget is no more updating on the screen_on/User_present event. I can see that there are a bunch of changes in Android 26 for background running task due to (Background Execution Limits).
Following are my questions?
Q1- How can I update my app widget on every screen_on event, so that the user will see the right status on widget?
Q2- How can I update my app widget periodically after every 1 hour?
Following code I'm currently using.
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.app_widget);
String token = getToken();
getUUID();
getGatewayActivationStatus();
getEnvironment();
if (token != null) {
remoteViews.setViewVisibility(R.id.layoutBtn, View.VISIBLE);
AppWidgetIntentReceiver appWI = new AppWidgetIntentReceiver();
appWI.getMode(context);
} else {
remoteViews.setTextViewText(R.id.txt_mode, "Please sign into your App to see status.");
remoteViews.setViewVisibility(R.id.layoutBtn, View.INVISIBLE);
}
remoteViews.setOnClickPendingIntent(R.id.btn_refresh, buildButtonPendingIntent(context, _refresh));
remoteViews.setOnClickPendingIntent(R.id.txt_mode, buildButtonPendingIntent(context, _openApp));
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);//add this line
AppWidgetIntentReceiver appWI = new AppWidgetIntentReceiver();
if (_standby.equals(intent.getAction()) || _home.equals(intent.getAction()) || _away.equals(intent.getAction()) || _refresh.equals(intent.getAction()) || _openApp.equals(intent.getAction())) {
appWI.handleClickEvent(context, intent, intent.getAction());
} else if (intent.getAction().equals("android.intent.action.USER_PRESENT") || intent.getAction().equals("android.appwidget.action.APPWIDGET_ENABLED") || intent.getAction().equals("android.intent.action.MY_PACKAGE_REPLACED") || intent.getAction().equals("android.appwidget.action.APPWIDGET_UPDATE")) {
getToken();
getUUID();
getGatewayActivationStatus();
getEnvironment();
appWI.handleClickEvent(context, intent, _refresh);
}
};
static PendingIntent buildButtonPendingIntent(Context context, String event) {
if (!event.equals("OPEN_APP")) {
Intent intent = new Intent(context, AppWidgetProvider.class);
intent.setAction(event);
return PendingIntent.getBroadcast(context, 0, intent, 0);
} else {
Intent intent2 = new Intent(context, MainActivity.class);
return PendingIntent.getActivity(context, 0, intent2, 0);
}
}
Finally, I've found solution to this problem.
We can simply find answer here:
https://developer.android.com/training/monitoring-device-state/doze-standby
To solve the above problem, we can use Alarm Manager.
Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window.
So right after the doze mode finishes, or during a maintenance window, it will automatically execute the code, written in alarm manager service.
You can get help here to use Alarm Manager in your widget from this stackoverflow post:
https://stackoverflow.com/a/14319020/3497865
I have a widget that display a simple text and 3 buttons:
Refresh (Picks another random string and displays it)
Copy (Copy the contents of the textview to the clipboard)
Share (Share the content of the textview to social media and such)
I already Got the refresh button setup and working just fine but I can't seem to figure out a way to handle the other two buttons
PS. I don't need the actual code I already know how to do the copying and sharing I just need to know how to handle click events
Here is my code so far:
Button copy_content;
Button share_content;
void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
/** Code below will be executed once the timer is over*/
String widgetText = RandQuotes[rand.nextInt(RandQuotes.length)];
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.quotes_widget);
views.setTextViewText(R.id.sayings, widgetText);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
final int count = appWidgetIds.length;
for (int i = 0; i < count; i++) {
int widgetId = appWidgetIds[i];
String on_sayings = RandQuotes[rand.nextInt(RandQuotes.length)];
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.quotes_widget);
remoteViews.setTextViewText(R.id.sayings, on_sayings);
Intent intent = new Intent(context, HavamalWidget.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.switch_trigger, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
Just make pending intents on buttons with action. So in onReceive() just check action of intent and make some logic on that. If you make some long tasks, better to make all logic in IntentService.
Set pending intents on your buttons that are in RemoteViews like this:
public static final String ACTION_BUTTON_SHARE = "ACTION_BUTTON_SHARE";
public static final String ACTION_BUTTON_REFRESH = "ACTION_BUTTON_REFRESH";
Intent refreshIntent = new Intent(context, ExampleAppWidget.class)
.setAction(ACTION_BUTTON_REFRESH);
PendingIntent refreshPI = PendingIntent.getBroadcast(context, 0, refreshIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.refresh_button, refreshPI);
Intent shareIntent = new Intent(context, ExampleAppWidget.class)
.setAction(ACTION_BUTTON_SHARE);
PendingIntent sharePI = PendingIntent.getBroadcast(context, 0, shareIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.share_button, sharePI);
In ExampleAppWidget.class (that extends from AppWidgetProvider) override OnReceive() method
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
if (intent.getAction().equals(ACTION_BUTTON_REFRESH)) {
//make some logic here on button refresh
} else if (intent.getAction().equals(ACTION_BUTTON_SHARE)) {
//make some logic here on button share
} else {
super.onReceive(context, intent);
}
}
}
I made an widget which have the image and show the time. howerver , the time cannot update.so I try to implement that the time will be updated when user click on the widget.
I find some tutorial said that using setOnClickPendingIntent can do this but my code not work.
Any solutions can let the widget update the time onClick or Auto Updating?
public class NewAppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = DateFormat.getTimeInstance(DateFormat.SHORT).format(new Date());;
// Construct the RemoteViews object
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
Intent intent = new Intent(context, NewAppWidget.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
updateViews.setOnClickPendingIntent(R.id.imageView, pendingIntent);
updateViews.setTextViewText(R.id.editText2, widgetText);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
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
}
}
Change you PendingIntent like this
Intent intent = new Intent()
intent.putExtra(EXTRA_VALUES, values)
intent.setComponent(new ComponentName(context, NewAppWidget.class));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
I am currently trying to implement a configuration activity which allows for manipulating the widget.
I have looked at the official document, as well as many other blogs,
but do not understand how to change the content of the widget through the configuration activity.
I want to set the String targetName to a TextView in R.layout.widget_layout.
It says I need to update the widget through the configuration activity,
but what happens to the onUpdate code in WidgetProvider.java if I update it in the configuration activity? This is the part that is confusing me the most.
Here is part of my code:
Configure.java extending ActionBarActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_configure);
setResult(RESULT_CANCELED);
context = this;
final Bundle extras = getIntent().getExtras();
if (extras != null) {
appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
final AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
final TextView textView = (TextView) findViewById(R.id.batteryText);
final int targetId;
db = new DatabaseHandler(this);
loadListView(); // not present here
registerForContextMenu(listView);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
targetName = serverArrayList.get(position).getName();
widgetManager.updateAppWidget(appWidgetId, views);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
});
}
WidgetProvider.java extending AppWidgetProvider
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent();
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
Thanks in advance.
Doing a bit more research,
I found this question.
Despite the title being a bit misleading,
I think I've solved it, so I'll be closing this question.
Android - Custom Widget doesnt update