I want to install my widget to my home page after i drag and drop it, but when i do it, it says app can't get installed here is my code:
public class WidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Intent receiver = new Intent(context, WidgetReceiver.class);
receiver.setAction("COM_FLASHLIGHT");
receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.Button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
And my provider info:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:previewImage="#drawable/more"
android:initialLayout="#layout/widget_layout"
android:configure="com.flashlight.standroid.WidgetProvider"
android:resizeMode="horizontal|vertical"
android:label="Monitor Widget">
</appwidget-provider>
My Manifest:
<receiver
android:name=".WidgetProvider"
android:icon="#drawable/more"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.example.flash.ACTION_WIDGET_RECEIVER" />
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/provider_info" />
</receiver>
<receiver
android:name="WidgetReceiver">
<intent-filter>
<action android:name="com.flashlight"></action>
</intent-filter>
</receiver>
Here i have gathered almost all the parts of code that i use to run/install.. my widget.Thanks in advance
Remove android:configure from your app widget metadata, or have it point to an activity to be used for configuring the app widget.
You can read more about configuration activities in the documentation.
change
android:configure="com.flashlight.standroid.FlashlightWidgetProvider"
with
android:configure="com.flashlight.standroid.WidgetProvider"
And make sure the Activity name is exactly wrote down on the android manifest.
Related
As long as I don't turn the phone off (even if the application is closed), the forward notification that I have created with the alarm manager in my android-java mobile application does not have a problem. But when I restart the phone before the notification time comes, it doesn't work even if it's time for my notification. Can you please help? Thanks.
MY ALARM SERVICE CLASS
package com.gokhankopuz.kopuzfilo.services;
public class AlarmService {
private Context context = null;
private long timeInMillis = 0L;
private String notificationTitle, notificationDesc = "";
public AlarmService(Context context, long timeInMillis, String notificationTitle, String notificationDesc) {
this.context = context;
this.timeInMillis = timeInMillis;
this.notificationTitle = notificationTitle;
this.notificationDesc = notificationDesc;
}
public void setAlarm() {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, getPendingIntent());
}
private PendingIntent getPendingIntent() {
#SuppressLint("UnspecifiedImmutableFlag")
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, (int) timeInMillis, getIntent(), PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
private Intent getIntent() {
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("notificationTitle", notificationTitle);
intent.putExtra("notificationDesc", notificationDesc);
return intent;
}
}
MY ALARM RECEIVER CLASS
package com.gokhankopuz.kopuzfilo.receivers;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
buildNotification(context, intent);
}
private void buildNotification(Context context, Intent intent) {
String notificationTitle = intent.getStringExtra("notificationTitle");
String notificationDesc = intent.getStringExtra("notificationDesc");
Notify.build(context)
.setImportance(Notify.NotifyImportance.HIGH)
.setTitle(notificationTitle)
.setContent(notificationDesc)
.setColor(R.color.app_background)
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(false)
.show();
}
}
MY MANIFEST
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.gokhankopuz.kopuzfilo">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
tools:ignore="CoarseFineLocation" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.KopuzFilo"
tools:ignore="AllowBackup">
<activity
android:name=".activities.NavigationActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:exported="true" />
<activity
android:name=".activities.MainActivity"
android:exported="true"
android:configChanges="orientation|screenSize|keyboardHidden"
android:windowSoftInputMode="stateVisible|adjustPan" />
<activity
android:name=".activities.SplashActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".receivers.AlarmReceiver" />
</application>
</manifest>
I added the following permissions to my manifest file but it didn't work
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
This is the expected behavior. If you turn off your device, all alarms are deleted. So, to workaround this issue, you must register for boot complete broadcast and re-schedule your alarm.
You can find more details on how to do it in the following question/answer:
does Alarm Manager persist even after reboot?
I think you can try use work manager, which will be executed by system.
WorkManager is the recommended solution for persistent work. Work is persistent when it remains scheduled through app restarts and system reboots. Because most background processing is best accomplished through persistent work, WorkManager is the primary recommended API for background processing.
I can't launch widgets on android 11.
This code works on my android 9 phone,
but android 11 Google Pixel 3a emulator not working.
what should I do for this.
Ok, so what I want to do is create a widget that will simply launch another application when the widget is pressed.
Widget Xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="Whatsapp Launch"
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<Button
android:layout_marginLeft="30dp"
android:text="Spotify Launch"
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
Widget Class
class SimpleAppWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
private fun updateAppWidget(
context: Context, appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.simple_app_widget)
// Construct an Intent object includes web adresss.
val launchIntent12 = context!!.packageManager.getLaunchIntentForPackage("com.spotify.music")
val launchIntent122 = context!!.packageManager.getLaunchIntentForPackage("com.whatsapp")
// In widget we are not allowing to use intents as usually. We have to use PendingIntent instead of 'startActivity'
val pendingIntent = PendingIntent.getActivity(context, 0, launchIntent122, 0)
val pendingIntent2 = PendingIntent.getActivity(context, 0, launchIntent12, 0)
// Here the basic operations the remote view can do.
views.setOnClickPendingIntent(R.id.button, pendingIntent)
views.setOnClickPendingIntent(R.id.button2, pendingIntent2)
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
First, you will need to add package visibility rules to your manifest. As it stands, getLaunchIntentForPackage() is probably returning null. After fixing this, fully uninstall and reinstall the app before continuing.
Also:
Use unique IDs for your PendingIntent objects (they are both set for 0 in the second parameter to getActivity())
Consider using PendingIntent.FLAG_UPDATE_CURRENT for the fourth parameter to getActivity()
WÄ°DGET Activity
class SimpleAppWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
#SuppressLint("RemoteViewLayout")
private fun updateAppWidget(
context: Context, appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.simple_app_widget)
val launchIntent2 = context!!.packageManager.getLaunchIntentForPackage("com.spotify.music")
val pendingIntent2 = PendingIntent.getActivity(context, 1, launchIntent2, PendingIntent.FLAG_UPDATE_CURRENT)
views.setOnClickPendingIntent(R.id.button2, pendingIntent2)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
widget permissions
<queries>
<package android:name="com.spotify.music"/>
<package android:name="com.example.widget11" />
<intent>
<action android:name="com.spotify.music" />
</intent>
</queries>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Widget11">
<receiver android:name=".SimpleAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/simple_app_widget_info" />
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Whenever I reboot my phone or upgrade the app (on my test device and on Android emulator) the widget stops updating until I create a new instance of the widget. Then both instances of the widget will start updating again. I assume it's something with calling the onUpdate() on old WidgetIds, but I can't figure it out.
Here's a small snipped of my code.
public class NewAppWidget extends AppWidgetProvider {
private static final String refresh = "b_refresh";
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
Intent intent = new Intent(context, NewAppWidget.class);
intent.setAction(refresh);
intent.putExtra("appWidgetId", appWidgetId);
views.setOnClickPendingIntent(R.id.refresh, PendingIntent.getBroadcast(context,0,intent, PendingIntent.FLAG_UPDATE_CURRENT));
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 onReceive(Context context, Intent intent) {
if(refresh.equals(intent.getAction())) {
Toast.makeText(context, "Clicked2", Toast.LENGTH_LONG).show();
}
}
}
EDIT: Here's my manifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".NewAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.EXTRA_APPWIDGET_IDS"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/new_app_widget_info" />
</receiver>
<activity android:name=".NewAppWidgetConfigureActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
</application>
Add a call to super.onReceive() to your onReceive().
Explanation
If you look at the source for the base class onReceive(), you can see that it implements part of the framework logic for managing Widget lifecycle. (Also hinted at by the docs). It handles APPWIDGET_UPDATE and is, in fact, what's responsible for calling onUpdate() in the first place. (E.g., when the system boots up, and it needs to draw your initial widget, it sends your app an APPWIDGET_UPDATE, which gets passed to onReceive()). So, I'm not 100% sure how onUpdate() was ever getting called, in your case, but I assume you have some code somewhere else that calls updateAppWidget(), and that's the only reason your widgets appeared to work even momentarily.
I'm trying to create some simple BroadcastReceiver according to manuals but I can't to make it work.
I'm calling procedure setAlarm in onCreate function in MainActivity that looks like this:
private void setAlarm() {
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
manager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000, pendingIntent);
}
It should activate AlarmReceiver that should do some action but doesn't do anything. It looks like this:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I'm running", Toast.LENGTH_LONG).show();
notifikace(context);
}
public void notifikace(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setSmallIcon(R.drawable.notifikace);
mBuilder.setContentTitle("Notification Alert, Click Me!");
mBuilder.setContentText("aaa");
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
mNotificationManager.notify(2, mBuilder.build());
}
}
I suspect that I'm missing something in AndroidManifest but I don't know what. AndroidManifest looks like this:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Nastaveni"
android:label="#string/title_activity_nastaveni"
android:theme="#style/AppTheme.NoActionBar" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".Tyden"
android:label="#string/title_activity_tyden"
android:theme="#style/AppTheme.NoActionBar"></activity>
<receiver android:name=".AlarmReceiver" >
</receiver>
</application>
Ultimately appliacation should be able to send notification every day at certain time even if application isn't running at the moment. (I will have to then replace
manager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000, pendingIntent);
line with setRepeating function but so far for testing purposes I need first to get it running.)
But so far AlarmReceiver class doesn't do anything. I'm getting some error when I try to run it (but application doesn't crash):
04-14 11:52:54.592 1300-1354/? I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.xxx.myapplication3/com.example.xxx.myapplication.MainActivity (has extras)} from uid 10014 on display 0
04-14 11:52:54.673 1300-1635/? I/ActivityManager: START u0 {act=android.content.pm.action.REQUEST_PERMISSIONS pkg=com.android.packageinstaller cmp=com.android.packageinstaller/.permission.ui.GrantPermissionsActivity (has extras)} from uid 10057 on display 0
I'm not sure whether the error log is related to this or something else in the project. What am I doing wrong? Thanks in advance for any answer.
Sorry I saw later your receiver in manifest, your error is that you ar getting a pending intent with getService instead of getBroadcast.
Just change it to:
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
I tried it just now :)
-- edited I will leave this as a reference --
You have to register the receiver somehow, either by code or by xml.
The alarm is an Intent broadcast that goes to a broadcast receiver that you registered with registerReceiver(BroadcastReceiver, IntentFilter) or through the tag in an AndroidManifest.xml file.
Refer to:
-Pending intent - getBroadcast
-AlarmManager
-Triggering alarm and issues
I am trying to capture download complete events, but my BroadcastReceiver is not receiving them. Here is the receiver:
public class DownloadListenerService extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
System.out.println("got here");
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = settings.edit();
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
String downloadPath = intent.getStringExtra(DownloadManager.COLUMN_URI);
editor.putString("downloadPath", downloadPath);
editor.commit();
}
}
}
Here is the manifest:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name="com.example.alreadydownloaded.DownloadListenerService"
android:exported="true">
<intent-filter>
<action android:enabled="true" android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
</application>
Anyone see what's wrong?
Use full package name for you receiver like com.example.DownloadListenerService
Add android:exported="true" BroadcastReceiver can receive messages from sources outside its application.
Change the name of the Action in the intent-filter to android.intent.action.DOWNLOAD_COMPLETE
<receiver
android:name="com.example.DownloadListenerService"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.INTERNET" />
The receiver only will be triggered if was registered from your application using registerReceiver(#Nullable BroadcastReceiver receiver,IntentFilter filter);
Code to enqueue Download :
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse("https://www.google.com/images/srpr/logo4w.png"));
dm.enqueue(request);
I think the action name in your XML is wrong. The docs state that the correct one is: android.intent.action.DOWNLOAD_COMPLETE not DownloadManager.ACTION_DOWNLOAD_COMPLETE - you need to use the constant, not the Java form.
<receiver android:name=".DownloadListenerService" >
<intent-filter>
<action android:enabled="true" android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
<receiver
android:name=".BroadCast_Service.Download_BroadCast"
android:exported="true">
<intent-filter android:priority="1099">
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
I think you are calling DownloadManger service from the IntentService/Service. If so remove it from there and put it into activity.
add permission in android manifest
<uses-permission android:name="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS" />
If the download is based on your app then you need to send a broadcast?
Intent i = new Intent();
i.setAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
sendBroadcast(i);