Battery level widget does not update - java

I need to show the battery level automatically in the widget, I've tried so many solutions to resolve this issue but unfortunately the widget does not update.
Here is my code:
Manifest.xml
<receiver
android:name=".BatteryWidget"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.leenah.battery.action.UPDATE" />
<action android:name="Intent.ACTION_BATTERY_CHANGED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
<service android:name=".ScreenMonitorService"></service> </manifest>
BatteryWidget.java
public class BatteryWidget extends AppWidgetProvider {
private static
final String ACTION_BATTERY_UPDATE = "com.leenah.battery.action.UPDATE";
private int batteryLevel = 0;
public static void turnAlarmOnOff(Context context, boolean turnOn) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(ACTION_BATTERY_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
if (turnOn) { // Add extra 1 sec because sometimes ACTION_BATTERY_CHANGED is called after the first alarm alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis() + 1000, 300 * 1000, pendingIntent); LogFile.log("Alarm set"); } else { alarmManager.cancel(pendingIntent); LogFile.log("Alarm disabled"); } }
#Override public void onEnabled (Context context){
super.onEnabled(context);
LogFile.log("onEnabled()");
turnAlarmOnOff(context, true); // context.startService(new Intent(context, ScreenMonitorService.class)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(new Intent(context, ScreenMonitorService.class)); } else { context.startService(new Intent(context, ScreenMonitorService.class)); }
//
}
#Override public void onUpdate (Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds){
super.onUpdate(context, appWidgetManager, appWidgetIds);
LogFile.log("onUpdate()");
// Sometimes when the phone is booting, onUpdate method gets called before onEnabled() int currentLevel = calculateBatteryLevel(context); if (batteryChanged(currentLevel)) { batteryLevel = currentLevel; LogFile.log("Battery changed"); }
updateViews(context);
}
private boolean batteryChanged ( int currentLevelLeft){
return (batteryLevel != currentLevelLeft);
}
#Override public void onReceive (Context context, Intent intent){
super.onReceive(context, intent);
LogFile.log("onReceive() " + intent.getAction());
if (intent.getAction().equals(ACTION_BATTERY_UPDATE)) {
int currentLevel = calculateBatteryLevel(context);
if (batteryChanged(currentLevel)) {
LogFile.log("Battery changed");
batteryLevel = currentLevel;
updateViews(context);
}
} ///
}
#Override public void onDisabled (Context context){
super.onDisabled(context);
LogFile.log("onDisabled()");
turnAlarmOnOff(context, false);
context.stopService(new Intent(context, ScreenMonitorService.class));
}
private int calculateBatteryLevel (Context context){
LogFile.log("calculateBatteryLevel()");
Intent batteryIntent = context.getApplicationContext().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
return level * 100 / scale;
}
private void updateViews (Context context){
LogFile.log("updateViews()");
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setTextViewText(R.id.batteryText, batteryLevel + " %");
ComponentName componentName = new ComponentName(context, BatteryWidget.class);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(componentName, views);
////////////////
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(componentName);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.batteryText);
}
}
ScreenMonitorService.java
public class ScreenMonitorService extends Service {
private static BroadcastReceiver screenOffReceiver;
private static BroadcastReceiver screenOnReceiver;
private static BroadcastReceiver userPresentReceiver;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
registerScreenOffReceiver();
registerScreenOnReceiver();
registerUserPresentReceiver();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(screenOffReceiver);
unregisterReceiver(screenOnReceiver);
unregisterReceiver(userPresentReceiver);
}
private void registerScreenOffReceiver() {
screenOffReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
LogFile.log(intent.getAction());
BatteryWidget.turnAlarmOnOff(context, false);
}
};
registerReceiver(screenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
private void registerScreenOnReceiver() {
screenOnReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
LogFile.log(intent.getAction());
KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (!keyguardManager.inKeyguardRestrictedInputMode())
BatteryWidget.turnAlarmOnOff(context, true);
}
};
registerReceiver(screenOnReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
}
private void registerUserPresentReceiver() {
userPresentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
LogFile.log(intent.getAction());
BatteryWidget.turnAlarmOnOff(context, true);
}
};
registerReceiver(userPresentReceiver, new IntentFilter(Intent.ACTION_USER_PRESENT));
}
}
so the widget is showing correctly only at the first time and does not updating anymore.
Please help me to fix this problem I will be waiting for your answers.
Have a great day

Related

Android Studio media player doesnt play when the app is closed

I made an Android app that should play a sound when event is received, it works when app is in focus, but when the app is closed/collapsed sound doesnt play, only standard notification.
How to start a sound/music that is placed inside the app when app with the foreground service?
Main activity:
public class MainActivity extends AppCompatActivity {
private Intent alarmServiceIntent;
private ServiceConnection sConn;
private boolean bound;
private boolean alarm = false;
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Init();
}
private void Init() {
alarmServiceIntent = new Intent(this, AlarmService.class);
sConn = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder binder) {
bound = true;
}
public void onServiceDisconnected(ComponentName name) {
bound = false;
}
};
ContextCompat.startForegroundService(this, alarmServiceIntent);
}
private void playAlarm() {
bindService(alarmServiceIntent, sConn, BIND_AUTO_CREATE);
}
public void stopAlarm(View v) {
if (sConn != null ) {
unbindService(sConn);
}
if(alarmServiceIntent != null) {
stopService(alarmServiceIntent);
}
}
//here is the method to receive event and call playAlarm
}
Alarm service:
public class AlarmService extends Service{
private final String CHANNEL_ID = "ID";
private final String CHANNEL_NAME = "NAME";
private IBinder mBinder = new MyBinder();
private MediaPlayer player;
#Nullable
#Override
public IBinder onBind(Intent intent) {
play();
return mBinder;
}
#Override
public boolean onUnbind(Intent intent) {
onStop();
return super.onUnbind(intent);
}
#Override
public void onCreate() {
player = MediaPlayer.create(this,R.raw.alarm);
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getActivity
(this, 0, notificationIntent, PendingIntent.FLAG_MUTABLE);
}
else
{
pendingIntent = PendingIntent.getActivity
(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);
}
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("TITLE")
.setSmallIcon(R.mipmap.icon)
.setContentIntent(pendingIntent)
.build();
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel( CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(channel);
new NotificationCompat.Builder(this, CHANNEL_ID);
}
startForeground(619, notification);
return START_REDELIVER_INTENT;
}
public void play() {
if(player == null) {
player = MediaPlayer.create(this,R.raw.alarm);
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
}
Log.v("ALARM", "play: 12345");
player.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
);
player.setVolume(2,2);
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
// audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
player.setLooping(true);
player.start();
}
class MyBinder extends Binder {
AlarmService getService(){
return AlarmService.this;
}
}
}
You should override onDestroy method and call stop there.
#Override
public void onDestroy() {
player.stop();
}

BOOT_COMPLETED not worknig

I want to run my android application always in background like whatsapp,truecaller i have used all things but when device is reboot the application is stop running in background for that i have used broadcast receiver to listen boot. here is my code.
My Service
public class Myservice extends Service {
File file;
private static String fileName = null;
private MediaRecorder recorder = null;
boolean mStartRecording = true;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
Intent intent = new Intent("RestartService");
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
onTaskRemoved(intent);
file = new File(Environment.getExternalStorageDirectory(), "pranay");
if (!file.exists()) {
boolean mkdir = file.mkdirs();
if (!mkdir) {
Toast.makeText(this, "Fialed", Toast.LENGTH_SHORT).show();
}
}
fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pranay/" + UUID.randomUUID().toString() + "sample.mp3";
Log.i("msg", "running");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
String channel = "pranay";
NotificationChannel notificationChannel = new NotificationChannel("id", channel, NotificationManager.IMPORTANCE_NONE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
Notification notification = new NotificationCompat.Builder(this, "id")
.setContentTitle("sa")
.setContentText("ssa")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
TelephonyManager manager1 = (TelephonyManager) getApplicationContext().getSystemService(getApplicationContext().TELEPHONY_SERVICE);
manager1.listen(new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String phoneNumber) {
super.onCallStateChanged(state, phoneNumber);
if (TelephonyManager.EXTRA_STATE_IDLE.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
cleanup();
} else if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
try {
recorder.prepare();
} catch (IOException e) {
Log.e("msg", "prepare() failed");
}
recorder.start();
mStartRecording = true;
}
}
}, PhoneStateListener.LISTEN_CALL_STATE);
return super.onStartCommand(intent,flags,startId);
}
private void startForeground(Notification notification, String id) {
startForeground(notification, id);
}
private void cleanup(){
if(recorder!=null)
{
try {
recorder.stop();
}catch (Exception e){
Log.e("msg",String.valueOf(e.getMessage()));
}finally {
recorder.release();
recorder=null;
}
stopSelf();
mStartRecording = false;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(),this.getClass());
restartServiceIntent.setPackage(getPackageName());
startService(restartServiceIntent);
super.onTaskRemoved(rootIntent);
}
}
Broad cast receiver
public class Receiver extends BroadcastReceiver {
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Toast.makeText(context,"Booted",Toast.LENGTH_SHORT).show();
Intent serviceIntent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(serviceIntent);
}
}
Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".Receiver"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="RestartService"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="android.intent.action.REBOOT"/>
</intent-filter>
</receiver>
<service android:name=".Myservice"/>
I am using android 10 and pie is it working on this versions?
You can use JobService android.intent.action.BOOT_COMPLETED this method is not worked on latest version of Android.
JobService
public MyJobService extends JobService {
private Handler myHandler = new Handler(new Handler.Callback() {
#Override
public boolean handler(Message msg) {
Log.e("TAG", "Does it run after reboot? ");
return true;
}
});
#Override
public boolean onStartJob(JobParameters params) {
myHandler.sendMessage(Message.obtain(myHandler, 1, params));
return true;
}
#Override
public boolean onStopJob(JobParameters params) {
myHandler.removeMessages(1);
}
}
MainActivity
MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle saveInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
ComponentName serviceComponent = new ComponentName(this,MyJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
builder.setMinimumLatency(1 * 1000);
builder.setOverrideDeadline(5 * 1000);
builder.setPersisted(true);
JobScheduler jobScheduler = (JobScheduler) getSystemService(this.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="you.package.name">
<application
..............
>
<service
android:name=".your.package.MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
</mainfest>

How to update widget views instantly when button clicked

I've seen a lot of answer here, none of them worked..! I just want a textview to get updated instantly once I click a button next to it.! I've tried to print a toast message and it shows normally, but updating views is the problem.
My Code
public class FollowersWidget extends AppWidgetProvider {
public static String REFRESH_ACTION = "android.appwidget.action.APPWIDGET_UPDATE";
int x = 0;
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(REFRESH_ACTION)) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
x++;
views.setTextViewText(R.id.textv_count, x + "");
int[] appWidgetId = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, FollowersWidget.class));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
try {
String count = MyConfigureActivity.getNumCount(context, appWidgetId);
views.setTextViewText(R.id.textv_count, count );
views.setOnClickPendingIntent(R.id.refreshButton,getRefreshPendingIntent(context, appWidgetId));
} catch (Exception e) {
e.printStackTrace();
}
appWidgetManager.updateAppWidget(appWidgetId, views);
}
public static PendingIntent getRefreshPendingIntent(Context context, int appWidgetId) {
Intent intent = new Intent(REFRESH_ACTION);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
// other widget methods..
..
.
}
My Manifest
<receiver android:name=".FollowersWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/followers_info"/>
</receiver>
I figured it out finally, I've seen a lot of ways to handle the onClick on widgets, but this way that worked out for me and it updates views intantally.
Code
public class TestWidget extends AppWidgetProvider {
public static String REFRESH_ACTION = "android.appwidget.action.APPWIDGET_UPDATE";
static private RemoteViews views;
private int x = 0;
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equalsIgnoreCase(REFRESH_ACTION)) {
views = new RemoteViews(context.getPackageName(), R.layout.test_widget);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, TestWidget.class));
x++;
views.setTextViewText(R.id.textv_count, x + "");
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
views = new RemoteViews(context.getPackageName(), R.layout.test_widget);
views.setTextViewText(R.id.textv_count, x + "");
views.setOnClickPendingIntent(R.id.button, getPenIntent(context));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
static private PendingIntent getPenIntent(Context context) {
Intent intent = new Intent(context, TestWidget.class);
intent.setAction(REFRESH_ACTION);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
Just check out following code:
public class WidgetExample extends AppWidgetProvider {
public static final String REFRESH_ACTION = "YOUR_REFRESH_ACTION";
public static final String VALUE_KEY = "VALUE_KEY";
public static final String PREFERENCE_FILE_KEY = "PREFERENCE_FILE_KEY";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent != null) {
if (intent.getAction() != null) {
if (intent.getAction().equals(REFRESH_ACTION)) {
int value = readValue(context) + 1;
saveValue(context , value);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetExample.class));
for (int id : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
views.setTextViewText(R.id.textv_count, String.valueOf(value));
views.setOnClickPendingIntent(R.id.button_refresh, getRefreshPendingIntent(context));
appWidgetManager.updateAppWidget(id, views);
}
}
}
}
}
#Override
public void onEnabled(Context context) {
int value = readValue(context);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetExample.class));
for (int id : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
views.setTextViewText(R.id.textv_count, String.valueOf(value));
views.setOnClickPendingIntent(R.id.button_refresh, getRefreshPendingIntent(context));
appWidgetManager.updateAppWidget(id, views);
}
}
private void saveValue(Context context, int value) {
SharedPreferences sharedPref = context.getSharedPreferences(PREFERENCE_FILE_KEY, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(VALUE_KEY, value);
editor.apply();
}
private int readValue(Context context) {
SharedPreferences sharedPref = context.getSharedPreferences(PREFERENCE_FILE_KEY, Context.MODE_PRIVATE);
return sharedPref.getInt(VALUE_KEY, 0);
}
public static PendingIntent getRefreshPendingIntent(Context context) {
Intent intent = new Intent(REFRESH_ACTION);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}

How to manually call `onUpdate` from within the widget itself

public class VWid extends AppWidgetProvider {
public static String WIDGET_UPDATE = "WIDGET_UPDATE";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (WIDGET_UPDATE.equals(intent.getAction())) {
Toast.makeText(context, "onReceiver()", Toast.LENGTH_LONG).show();
}
}
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this
// provider
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
int k, p;
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy hh:mm a");
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int k = audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
Toast.makeText(getActivity(), k+"", Toast.LENGTH_LONG).show();
Intent imageview2Intent= new Intent(context, VWid.class);
PendingIntent pendingIntent2= PendingIntent.getBroadcast(context,0, imageview2Intent,0);
views.setOnClickPendingIntent(R.id.imagebuttonrefresh, pendingIntent2); //
views.setTextViewText(R.id.textview1, "Last Refresh: " + dateFormat.format(new Date()).toString());
pushWidgetUpdate(context, views);
}
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, VWid.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
Log.d("UPDATED", "testing");
}
}
When I first add the widget to my homescreen, textview1 displays: Last Refresh: {current date and time}. It also displays the system volume in a Toast.
Let's say I increase/decrease the system volume, when I hit refresh the onUpdate() function should fire showing the updated Toast and also updating the textview1 text to the new data and time but that's not happening.
How can I modify the code so I can achieve a refresh, in essence calling the onUpdate() function.
Try this:
public class WidgetProvider extends AppWidgetProvider {
public static final String REFRESH_ACTION = "com.packagename.REFRESH_ACTION";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(WidgetProvider.REFRESH_ACTION)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
Toast.makeText(context, "REFRESH", Toast.LENGTH_SHORT).show();
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
}
}
#Override
public void onUpdate(final Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; ++i) {
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent intentServiceCall = new Intent(context, WidgetService.class);
intentServiceCall.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
//Refresh
Intent refreshIntent = new Intent(context, WidgetProvider.class);
refreshIntent.setAction(WidgetProvider.REFRESH_ACTION);
refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
intentServiceCall.setData(Uri.parse(intentServiceCall.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.ivRefreshWidget, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
Change this section :
Intent imageview2Intent= new Intent(context, VWid.class);
imageview2Intent.setAction(WIDGET_UPDATE);
PendingIntent pendingIntent2= PendingIntent.getBroadcast(context,0, imageview2Intent,0);
views.setOnClickPendingIntent(R.id.imagebuttonrefresh, pendingIntent2); //
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (WIDGET_UPDATE.equals(intent.getAction())) {
pushWidgetUpdate(context);
}
}

Handling a button click in a home screen widget

I am trying to make a home screen widget which will toggle on and off the gps (Location in settings). I still don't understand how to handle a button click event.
I took this code from a tutorial online.
public class LocationWidget extends AppWidgetProvider {
private static String SYNC_CLICKED = "automaticWidgetSyncButtonClick";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int count = appWidgetIds.length;
String status;
LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
for (int i = 0; i < count; i++) {
int widgetId = appWidgetIds[i];
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
status = "OFF";
} else {
status = "ON";
}
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
remoteViews.setTextViewText(R.id.textView, status);
Intent intent = new Intent(context, LocationWidget.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.actionButton, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
remoteViews.setTextViewText(R.id.textView, "Button clicked");
Log.v("ACTION", intent.getAction());
}
}
Inside onReceive, Log.v returns "ACTION﹕android.appwidget.action.APPWIDGET_UPDATE". So I need help to make the button behave the way i want when clicked. Can someone explain how and why?
i will open my heplactivity you can change and add your setting intent
appwidget.java
public class MyWidget extends AppWidgetProvider {
Button btnhelp;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent configIntent = new Intent(context, HelpActivity.class);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.btnhelp, configPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
}
manifest
<receiver android:name=".MyWidget">
<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>
resource xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="#layout/widget_layout"
android:minHeight="70dp"
android:minWidth="70dp"
android:updatePeriodMillis="300000"></appwidget-provider>
layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dip"
android:background="#drawable/ic_dashboard_help"
android:clickable="true">
<Button
android:id="#+id/btnhelp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dip"
android:background="#android:color/transparent" />
</LinearLayout>
I got it.
public class LocationWidget extends AppWidgetProvider {
public static String WIDGET_BUTTON = "MY_PACKAGE_NAME.WIDGET_BUTTON";
private static final String ACTION_CLICK = "ACTION_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int count = appWidgetIds.length;
String status;
LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
for (int i = 0; i < count; i++) {
int widgetId = appWidgetIds[i];
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
status = "OFF";
} else {
status = "ON";
}
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
if (status == "ON") {
remoteViews.setInt(R.id.actionButton, "setBackgroundColor", Color.GREEN);
remoteViews.setTextViewText(R.id.actionButton, "Location Service On");
}
if (status == "OFF") {
remoteViews.setInt(R.id.actionButton, "setBackgroundColor", Color.RED);
remoteViews.setTextViewText(R.id.actionButton, "Location Service Off");
}
Intent intent = new Intent(context, LocationWidget.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
String buttonclick = "buttonclick";
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.actionButton, getPendingSelfIntent(context, buttonclick));
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
protected PendingIntent getPendingSelfIntent(Context context, String action) {
Intent intent = new Intent(context, LocationWidget.class);
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
if (intent.getAction() == "buttonclick") {
Log.v("ACTION", "buttonclick");
Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
callGPSSettingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(callGPSSettingIntent);
}
}
}
You should be able to do
if( intent.getAction() == <action_type> )
{
/*Handling code here*/
}

Categories