flutter audio_service not playing audio - android

So I have followed the tutorial https://github.com/ryanheise/audio_service/wiki/Tutorial
However I have not had any success getting it to work.
My first issues was
final _completer = Completer();
Their is no Completer class so that throw an error.
And it seems that the code they provide just does not fire the following class.
/*AUDIO PLAYER*/
class AudioPlayerTask extends BackgroundAudioTask {
final _audioPlayer = AudioPlayer();
// final _completer = Completer();
#override
Future<void> onStart(Map<String, dynamic> params) async {
// Connect to the URL
print("test");
await _audioPlayer.setUrl("https://perth.adstichr.com.au/station/DRN1?uuid=0000-0000-0000-0000");
// Now we're ready to play
_audioPlayer.play();
}
#override
Future<void> onStop() async {
// Stop playing audio
await _audioPlayer.stop();
// Shut down this background task
await super.onStop();
}
}
The full code is
import 'package:flutter/material.dart';
import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Example',
theme: ThemeData(primarySwatch: Colors.blue),
home: AudioServiceWidget(child: MainScreen()),
);
}
}
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Example")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(child: Text("Start"), onPressed: start),
RaisedButton(child: Text("Stop"), onPressed: stop),
],
),
),
);
}
start() =>
AudioService.start(backgroundTaskEntrypoint: _backgroundTaskEntrypoint);
stop() => AudioService.stop();
_backgroundTaskEntrypoint() {
AudioServiceBackground.run(() => AudioPlayerTask());
}
}
/*AUDIO PLAYER*/
class AudioPlayerTask extends BackgroundAudioTask {
final _audioPlayer = AudioPlayer();
// final _completer = Completer();
#override
Future<void> onStart(Map<String, dynamic> params) async {
// Connect to the URL
print("test");
await _audioPlayer.setUrl("https://perth.adstichr.com.au/station/DRN1?uuid=0000-0000-0000-0000");
// Now we're ready to play
_audioPlayer.play();
}
#override
Future<void> onStop() async {
// Stop playing audio
await _audioPlayer.stop();
// Shut down this background task
await super.onStop();
}
}

I followed the document we must add the method _backgroundTaskEntrypoint() on the top level function, so you should move the function outside the class.
// Must be a top-level function
void _backgroundTaskEntrypoint() {
AudioServiceBackground.run(() => AudioPlayerTask());
}
/*AUDIO PLAYER*/
class AudioPlayerTask extends BackgroundAudioTask {
final _audioPlayer = AudioPlayer();
...
}

It's not working for me either. Note that to use audio_service on Android you must put the following lines into AndroidManifest.xml. However, when I do so, com.ryanheise.audioservice.MediaButtonReceiver gives an error "Class referenced in the manifest, com.ryanheise.audioservice.AudioService, was not found in the project or the libraries", and I'm not sure what to do about that.
This needs to go into the Manifest. See the documentation.
<manifest ...>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application ...>
...
<service android:name="com.ryanheise.audioservice.AudioService">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
</application>
</manifest>

Related

Unable to Send Sms using Telephony package on flutter

I have been trying to write a simple flutter code and trying to send SMS using telephony. Sending Sms via the default SMS app works (telephony.sendSmsByDefaultApp()) but not sending directly from the app.
My code is as follows:
import 'package:flutter/material.dart';
import 'package:telephony/telephony.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
sendSMS();
},
child: Text("Send SMS"),
),
),
),
);
}
void sendSMS() async {
final Telephony telephony = Telephony.instance;
bool? permissionsGranted = await telephony.requestPhoneAndSmsPermissions;
print(permissionsGranted);
await telephony.sendSms(to: "+92xxxxxxxxxx", message: "Hello, this is a test message.");
print("SMS Sent");
}
}
I have added the following required permissions
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
can you try the code
https://d7networks.com/docs/Messages/Send_Message/
we need to have an account on https://d7networks.com/ platform.
Have you tried changing that onPressed() function in the ElevatedButton(), to an async function:
ElevatedButton(
onPressed: () async {
await sendSMS();
},
child: Text("Send SMS"),
)
And then change your sendSMS() function to return a Future<void>, instead of void:
Future<void> sendSMS() async {
final Telephony telephony = Telephony.instance;
bool? permissionsGranted = await telephony.requestPhoneAndSmsPermissions;
print(permissionsGranted);
await telephony.sendSms(to: "+92xxxxxxxxxx", message: "Hello, this is a test message.");
print("SMS Sent");
}
}

make a flutter app in which the launch icon is working as a link

I was wondering if it is possible to make a Flutter app and when the user hits the launch icon, the browser opens with a specific URL. I know that you can make shortcuts on your phone home screen with the URL you want but I was wondering if it is possible as an Android app. So the app should do almost nothing just when I tap on it the browser should open..
is this possible? and is yes how should I think it?
I think it can be possible using the url_launcher package. You need to execute the code in the main function.
In main.dart
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(App());
}
class App extends StatefulWidget {
const App({Key? key}) : super(key: key);
#override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
Future<String> _launchURL() async {
const url = 'https://www.google.com';
if (await canLaunch(url)) {
await launch(url);
return 'text';
} else {
throw 'Could not launch $url';
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: FutureBuilder<String>(
future: _launchURL(), // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
return Center(
child: GestureDetector(
onTap: () => _launchURL(),
child: Text('Hello'))
);
},
),
),
);
}
}
In your AndroidManifest.xml
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
</queries>

flutter deep linking (uni_links) don't work on a real device

I'm trying to add deep linking to my app, i'm using uni_links https://pub.dev/packages/uni_links
I followed the instructions on the page, and on android emulator everything works fine- I open the app by the deep link, the snapshot has data and the urlResponse is returned.
but on a real device, when I open the app by the deep link, the snapshot doesn't have any data and the HomePage is returned.
here is my code:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.white,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: StreamBuilder(
stream: getLinksStream(),
builder: (context, snapshot) {
if (snapshot.hasData) {
// our app started by configured links
Uri uri = Uri.parse(snapshot.data);
List<MapEntry<String, List<String>>> list =
uri.queryParametersAll.entries.toList();
return urlResponse(uri, list);
} else {
// our app started regularly
return HomePage();
}
},
),
);
}
and my AndroidManifest.xml:
<!-- Deep Links -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
<data
android:scheme="http"
android:host="example.com"
android:pathPrefix="/myApp"/>
</intent-filter>
Can anyone help me to understand why it's work on emulator but not on a real device?
I Used uni_links in StatefulWidget with getLinksStream() like this:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:uni_links/uni_links.dart';
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
StreamSubscription _linkSubscription;
#override
Widget build(BuildContext context) {
return MaterialApp(
//...
);
}
#override
void initState() {
super.initState();
initDeepLink();
}
#override
void dispose() {
if (_linkSubscription != null) _linkSubscription.cancel();
super.dispose();
}
Future<void> initDeepLink() async {
_linkSubscription = getLinksStream().listen((url) {
if (!mounted) return;
setState(() {
//Here you have url data
Uri uri = Uri.parse(url);
List<MapEntry<String, List<String>>> list =
uri.queryParametersAll.entries.toList();
});
}, onError: (Object err) {
print("$err");
});
}

Platform location permission error with Flutter isolates

I'm attempting to run location updates on a Flutter isolate thread, the error is only present when running an isolate. Location requests works without issues on the main thread. The goal here is to run this as a background service, working with dart code only.
I am using Geolocator plugin for location requests.
This is the error I am facing when starting the isolate:
Exception has occurred. FlutterError
(ServicesBinding.defaultBinaryMessenger was accessed before the
binding was initialized.
I have tried to include the WidgetsFlutterBinding.ensureInitialized() before runApp but without results.
Looking at the call stack of the error, it seems problems occur at the android location platform call: checkPermissionStatus
This happens regardless of what location plugin I am using, it stops at the permission status check.
I have figured it could have something to do with awaiting location permission user input, but this check will fail on a non-ui thread?
See this simple main.dart file for an example:
import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Isolate location test',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Isolate location test'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Isolate isolate;
bool isRunning = false;
String output = '';
ReceivePort receivePort;
void start() async {
receivePort = ReceivePort();
await Isolate.spawn(locationUpdate, receivePort.sendPort);
receivePort.listen((dynamic data) {
setState(() {
isRunning = true;
});
}, onDone: () {
print("done");
});
}
void stop() {
if (isolate != null) {
setState(() {
isRunning = false;
});
receivePort.close();
isolate.kill(priority: Isolate.immediate);
isolate = null;
}
}
static void locationUpdate(SendPort sendPort) async {
Geolocator().checkGeolocationPermissionStatus().then((status) {
sendPort.send(status);
});
// Geolocator().getCurrentPosition().then((pos) {
// sendPort.send(pos);
// });
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(child: Text(output)),
floatingActionButton: FloatingActionButton(
onPressed: isRunning ? stop : start,
child: Icon(isRunning ? Icons.stop : Icons.play_circle_filled),
),
);
}
}

I'm trying to call a functions inside a widget in flutter, but nothing happens

I building an app that interacts with some android camera features using dart and flutter on Android Studio.
I'm not very experienced with Dart & Flutter, I'm still in learning process.
class SwitchWidget extends StatefulWidget {
#override
SwitchWidgetClass createState() => new SwitchWidgetClass();
}
Whenever I call Torch.turnOn() nothing is happening and I don't know why. I have tried many approaches and I'm still getting nothing.
The function I'm trying to call is from this package called torch. This package is for turning on and off the android camera flashlight.
The main file of this package I'm using has the following code:
import 'dart:async';
import 'package:flutter/services.dart';
class Torch {
static const MethodChannel _channel = const MethodChannel('io.siteplan.flutterplugins/torch');
static Future turnOn() => _channel.invokeMethod('turnOn');
static Future turnOff() => _channel.invokeMethod('turnOff');
static Future<bool> get hasTorch async => await _channel.invokeMethod('hasTorch');
static Future flash(Duration duration) => turnOn().whenComplete(() => Future.delayed(duration, () => turnOff()));
}
I wrote the code that is below this statement in my custom dart file called homepage.dart.
import 'package:flutter/material.dart';
import 'package:torch/torch.dart';
/**
* HomePage StatefulWidget is here!
*/
class SwitchWidgetClass extends State {
bool switchControl = false;
var textHolder = 'Switch is OFF';
void toggleSwitch(bool value) {
if (switchControl == false) {
setState(() {
switchControl = true;
textHolder = 'Switch is ON';
});
print('Switch is ON');
Torch.turnOn();
} else {
setState(() {
switchControl = false;
textHolder = 'Switch is OFF';
});
print('Switch is OFF');
Torch.turnOff();
}
}
#override
Widget build(BuildContext context) {
return Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Transform.scale(
scale: 1.5,
child: Switch(
onChanged: toggleSwitch,
value: switchControl,
activeColor: Colors.blue,
activeTrackColor: Colors.green,
inactiveThumbColor: Colors.white,
inactiveTrackColor: Colors.grey,
)),
Text(
'$textHolder',
style: TextStyle(fontSize: 24),
)
]);
}
}
What I want is When I call the Torch.turnOn() method, it should work and turn on the camera flashlight.
To use Torch you must import "torch.dart" package;A Flutter plugin to access the device's torch on Android and iOS.
import 'package:torch/torch.dart';
Read more here
try to add this Permission to Manifest file in Android
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera.flash" />

Categories

Resources