AndroidAlarmManagerPlus not starting automatically after reboot - flutter

I've set permissions in the AndroidManifest.xml file
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
I've also added the following lines in the AndroidManifest.xml as specified in the docs
<service
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.AlarmBroadcastReceiver"
android:exported="false"/>
<receiver
android:name="dev.fluttercommunity.plus.androidalarmmanager.RebootBroadcastReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
In my main.dart file, I've the following lines of codes...
import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await AndroidAlarmManager.initialize();
runApp(MyApp());
await AndroidAlarmManager.periodic(Duration(minutes: 1), 0, syncData);
}
void syncData() async {
print("synching data");
String? uploadedUrl = await S3.uploadToS3();
print(uploadedUrl);
}
What should I add for this to work automatically on reboot? TIA :)

From Android 8.0 You can't use most of the implicit broadcast ,
So your application service will not start on
ACTION_LOCKED_BOOT_COMPLETED or ACTION_BOOT_COMPLETED
for more details
you can use WorkManager instead to sync data to server
here is a good example

Related

How to start Flutter app as a background service on system startup

I'm wanting to automatically run my flutter application's background services as soon as the mobile is rebooted.
I implemented the following Solution, but it's throwing some errors
AndroidStudioProjects\db_app\android\app\src\main\kotlin\com\example\laravel_login\MainActivity.kt: (14, 22): Unresolved reference: Uri
AndroidStudioProjects\db_app\android\app\src\main\kotlin\com\example\laravel_login\MainActivity.kt: (14, 28): Unresolved reference: Uri
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugKotlin'.
> Compilation error. See log for more details
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
If you know any alternative, please help.
Thank you.
MainActivity.kt
package com.example.laravel_login
import android.os.Bundle
import android.provider.Settings
import io.flutter.embedding.android.FlutterActivity
import android.content.BroadcastReceiver
import android.content.Context;
import android.content.Intent;
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var REQUEST_OVERLAY_PERMISSIONS = 100
if (!Settings.canDrawOverlays(getApplicationContext())) {
val myIntent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
val uri: Uri = Uri.fromParts("com.example.laravel_login.BootReceiver", getPackageName(), null)
myIntent.setData(uri)
startActivityForResult(myIntent, REQUEST_OVERLAY_PERMISSIONS)
return
}
}
}
class BootReceiver: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
val i = Intent(context, MainActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(i)
}
}
}
AndroidManifest.xml
<!-- app auto restart on phone restart -->
<receiver
android:enabled="true"
android:exported="true"
android:name="com.example.laravel_login.BootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- app auto restart on phone restart -->
Add this to the imports of MainActivity.kt and you're good to go.
import android.net.Uri

Trying to delete an audio file but giving exception in flutter

I'm trying to delete song file but it is unable to delete and throws an exception of permission denied but permissions are already granted using permission_handler and required storage permissions are added in AndroidManifest.xml as well. I have also checked path is valid and file exist before delete which return true. Would anyone help me to solve this.
Error on file.delete() line.
Unhandled Exception: FileSystemException: Deletion failed, path = '/storage/0E15-2E06/Music/Call Sound Effect.mp3' (OS Error: Permission denied, errno = 13)
AndroidManifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application
android:label="Example"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true" >
Code snippet:
if (await Permission.storage.request().isGranted) {
// Either the permission was already granted before or the user just granted it.
// permission was granted
if (song != null) {
String? path = song.data;
File file = File(path);
bool isExist = await file.exists();
if (isExist) {
await file.delete(recursive: true);
}
}
}
You have to use the permission_handler(https://pub.dev/packages/permission_handler) package and have to mention some permissions in the Androidmanifest.xml file.
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Also, you have to ask Permission of storage before doing storage related operation(In your case deletion of audio file).
final _permissionStatus = await Permission.storage.request();
if(_permissionStatus = PermissionStatus.isGranted){
/// Delete audio file
}else{
/// Permission Denied.
}

FileProvider - IllegalArgumentException: Failed to find configured root share flutter

I'm trying to share a image with plugin share flutter, but I'm getting the following error:
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/.../cache/share/image-777.jpg
AndroidManifest.xml:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_path"/>
</provider>
flutter:
final urlImage =
'https://images.tokopedia.net/img/cache/500-square/hDjmkQ/2021/9/13/343063bb-f7c5-468d-9602-9b06ced70bdb.jpg';
final uri = Uri.parse(urlImage);
final response = await http.get(uri);
final bytes = response.bodyBytes;
final temp = await getTemporaryDirectory();
final path = '${temp.path}/image-777.jpg';
File(path).writeAsBytesSync(bytes);
await Share.shareFiles(
[path],
// text: wording + ' ' + url,
// subject: 'Refer your friend',
);
provider_path.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="/" />
<external-files-path
name="external_files"
path="/" />
<cache-path
name="cache"
path="/" />
<external-cache-path
name="external_cache"
path="/" />
<files-path
name="files"
path="/" />
</paths>
I was searching whole day about this error and trying to understand FileProvider, but I have no idea what this error message tries to tell me, i already change '.' to '/' in provider_path.xml or '/cache/share' but still not working . If you want more info/code, write me in the comment.

How to wire up an Share intent in MAUI for Android?

I'm trying to work out how to wire up a Share intent in Android using MAUI.
Am I running into preview bugs, or am I not doing it correctly?
I'm running MAUI Preview 10, with Visual Studio 17.1.0 Preview 1.0.
Version 1
I've added the share intent to the AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<application android:allowBackup="true" android:icon="#mipmap/appicon" android:roundIcon="#mipmap/appicon_round" android:supportsRtl="true">
<activity android:name="SomeLongName.MainActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
And then by adding a Name property to the MainActivity class:
[Activity(Name = "SomeLongName.MainActivity", Theme = "#style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
public class MainActivity : MauiAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (Intent.Type == "text/plain")
{
}
}
}
When I debug the application in MAUI, the app builds correctly and the Output says that the app has deployed. However, in Visual Studio, the debugger fails to run, and there is no evidence of the app on the emulator.
Version 2
In version 2, I've tried to create a separate activity for the Share intent:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<application android:allowBackup="true" android:icon="#mipmap/appicon" android:roundIcon="#mipmap/appicon_round" android:supportsRtl="true">
<activity android:name="SomeLongName.ShareActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
[Activity(Name = "SomeLongName.ShareActivity")]
public class ShareActivity : MauiAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
if (Intent.Type == "text/plain" && Intent.Action == "android.intent.action.SEND")
{
//handleSendUrl();
}
base.OnCreate(savedInstanceState);
}
I can now successfully debug the application, but when I try to share to the application, I get an exception on the base.OnCreate call:
Java.Lang.IllegalStateException: 'The specified child already has a parent. You must call removeView() on the child's parent first.'
Seems the issue centres around themes. The solution is in the original question, apply Version 2. With some minor updates. In the MainApplication class add an attribute defining the theme (same as in MainActivity class but could be different).
[Application(Theme = "#style/Maui.SplashTheme")]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
This both works without error and enables debugging.
Without the MainApplication theme setting, when sharing to the android app (incoming), an error thrown:
Java.Lang.IllegalArgumentException: 'The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).'
In my secondary activity, the Activity attribute sets the Theme, but is ignored and error still shown, hence the Application level needed. Not sure why.
[Activity(Theme = "#android:style/Theme.MaterialComponents.Light", Name = "com.somename.receiveurlactivity", MainLauncher = false, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
public class ReceiveUrlActivity : MauiAppCompatActivity
{
//.... etc

Scringo Login status changes not received on Android

I'm trying to implement Scringo Login status change on Android. But my Broadcast receiver is never called.
I've followed the instructions described on http://www.scringo.com/docs/android-guides/popular/handling-login-status-changes/
So I registered my broadcast receiver:
<receiver android:name="com.jino.footster.MyReceiver">
<intent-filter>
<action android:name="com.scringo.LoginBroadcast" />
</intent-filter>
</receiver>
And I then defined my Broacast receiver:
package com.jino.footster;
import com.scringo.utils.ScringoLogger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.scringo.LoginBroadcast")) {
boolean isLogin = intent.getExtras().getBoolean("isLogin");
String accountId = intent.getExtras().getString("accountId");
ScringoLogger.e("Got Login receiver: " + isLogin + ", " + accountId);
}
}
}
When I start the application the login seems to be successful: I see the below message in logcat:
04-24 01:12:35.000: I/Scringo(4717): Your Scringo user token is: a03fgalc5E
However, the onReceive method of my broadcast receiver is never called.
Would someone be able to help?
thank you
You forgot the category:
<receiver android:name="com.jino.footster.MyReceiver">
<intent-filter>
<action android:name="com.scringo.LoginBroadcast" />
<category android:name="com.jino.footster"/>
</intent-filter>
</receiver>