Open android webview app when clicked on onesignal notification - webview

Can somebody tell me what am I missing. I have a webview app. It works fine except this, when I close app onesignal notification arrives fine, but when I click notification app does not open. Here is some code related to this problem.
I have been searching for solution but what ever I have tried it does not work.
When app is running notification comes and opens fine, but when it is closed it wont start app.
Thanks.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OneSignal.startInit(this)
.inFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification)
.unsubscribeWhenNotificationsAreDisabled(true)
.setNotificationOpenedHandler(new
OneSignal.NotificationOpenedHandler() {
#Override
public void notificationOpened(OSNotificationOpenResult
result) {
String launchURL =
result.notification.payload.launchURL;
Intent intent = new Intent(getApplicationContext(),
NotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
| Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("url", launchURL);
startActivity(intent);
}
})
.init();
}
public class NotificationExtender extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult notification) {
OverrideSettings overrideSettings = new OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
#Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
// Sets the background notification color to Green on Android 5.0+ devices.
return builder.setColor(new BigInteger("#005aaa", 16).intValue())
.setSmallIcon(R.drawable.ic_stat_onesignal_default);
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
Log.d("OneSignalExample", "Notification displayed with id: " + displayedResult.androidNotificationId);
return true;
}
}
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".NotificationExtender"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="com.onesignal.NotificationExtender" />
</intent-filter>
</service>
<activity
android:name=".NotificationActivity"
android:parentActivityName=".MainActivity"/>
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT" android:value="DISABLE" />

I solved it.
It seams you do not need NotificationOpenedHandler, just NotificationExtender extends NotificationExtenderService. It look like this:
public class NotificationExtender extends NotificationExtenderService {
public NotificationExtender() {
super();
}
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult receivedResult) {
Intent intent = new Intent(getApplicationContext(), NotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("url", receivedResult.payload.launchURL);
PendingIntent pendingIntent = PendingIntent.getActivity(
getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_stat_onesignal_default)
.setSound(uri)
.setContentTitle(receivedResult.payload.title)
.setContentText(receivedResult.payload.body)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_onesignal_large_icon_default))
.setColor(getResources().getColor(R.color.logo_color))
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
return true;
}
}

Related

Error Exception occurred while processing task when using Iap API from Amazon purchase

followed the instructions on amazon developer page to be able to add IAP API to my app. But it doesn't work and throws an error:
AbstractCommandTask: Exception occurred while processing task: com.amazon.a.a.n.a.a.a: AUTH_TOKEN_VERIFICATION_FAILURE: null: null
com.amazon.a.a.n.a.a.a: AUTH_TOKEN_VERIFICATION_FAILURE: null: null
at com.amazon.a.a.n.a.b.a(AuthenticationTokenVerifier.java:94)
at com.amazon.a.a.n.a.a.a(AbstractCommandTask.java:204)
at com.amazon.a.a.n.a.a.a(AbstractCommandTask.java:131)
at com.amazon.a.a.n.b.b$1.run(SimpleTaskPipeline.java:179)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
I downloaded the amazon app tester and added the amazon.sdkteste.json file to the sdcard folder as shown in the instructions and in the app tester app also recognized this file.
I also downloaded the AppstoreAuthenticationKey.pem file and saved it to the app's app/src/main/assets folder. Can anyone tell me what am I missing or can someone give me a solution to fix this problem.
Thank
Below Is My AndroidManifest.xml 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.amazontinhtoannhanh">
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.TinhToanNhanh"
tools:targetApi="31">
<activity
android:name=".MainActivity"
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 = "com.amazon.device.iap.ResponseReceiver"
android:permission = "com.amazon.inapp.purchasing.Permission.NOTIFY"
android:exported="true">
<intent-filter>
<action android:name = "com.amazon.inapp.purchasing.NOTIFY" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.amazon.device.drm.LicensingService;
import com.amazon.device.iap.PurchasingService;
import java.util.HashSet;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
Button btn_subcire;
Set <String>productSkus=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LicensingService.verifyLicense(this.getApplicationContext(), new LicensingCallback());
TinhToanNhanhPurchasingLIstener purchasingListener= new TinhToanNhanhPurchasingLIstener();
PurchasingService.registerListener(this.getApplicationContext(), purchasingListener);
btn_subcire= (Button) findViewById(R.id.btn_subcire);
btn_subcire.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PurchasingService.purchase("com.match.payment");
}
});
}
#Override
protected void onResume() {
super.onResume();
PurchasingService.getUserData();
productSkus = new HashSet<String>();
productSkus.add( "com.mathterm.payment" );
productSkus.add( "com.mathterm2.payment" );
productSkus.add( "com.mathterm3.payment" );
productSkus.add( "com.mathterm4.payment" );
productSkus.add("25");
PurchasingService.getProductData(productSkus);
PurchasingService.getPurchaseUpdates(false);
}
}
LicensingCallback.java:
import static android.content.ContentValues.TAG;
import android.util.Log;
import com.amazon.device.drm.model.LicenseResponse;
public class LicensingCallback implements com.amazon.device.drm.LicensingListener {
public void onLicenseCommandResponse(final LicenseResponse licenseResponse) {
final LicenseResponse.RequestStatus status = licenseResponse.getRequestStatus();
Log.d(TAG, "onLicenseCommandResponse: RequestStatus (" + status + ")");
switch (status) {
case LICENSED:
Log.d(TAG, "onLicenseCommandResponse: LICENSED");
break;
case NOT_LICENSED:
Log.d(TAG, "onLicenseCommandResponse: NOT_LICENSED");
break;
case ERROR_VERIFICATION:
Log.d(TAG, "onLicenseCommandResponse: ERROR_VERIFICATION");
break;
case ERROR_INVALID_LICENSING_KEYS:
Log.d(TAG, "onLicenseCommandResponse: ERROR_INVALID_LICENSING_KEYS");
break;
case EXPIRED:
Log.d(TAG, "onLicenseCommandResponse: EXPIRED");
break;
case UNKNOWN_ERROR:
Log.d(TAG, "onLicenseCommandResponse: ERROR");
} } }
TinhToanNhanhPurchasingLIstener:
import static android.content.ContentValues.TAG;
import android.util.Log;
import com.amazon.device.iap.PurchasingListener;
import com.amazon.device.iap.PurchasingService;
import com.amazon.device.iap.model.FulfillmentResult;
import com.amazon.device.iap.model.Product;
import com.amazon.device.iap.model.ProductDataResponse;
import com.amazon.device.iap.model.PurchaseResponse;
import com.amazon.device.iap.model.PurchaseUpdatesResponse;
import com.amazon.device.iap.model.Receipt;
import com.amazon.device.iap.model.UserDataResponse;
import java.util.Map;
public class TinhToanNhanhPurchasingLIstener implements PurchasingListener {
private String currentUserId = null ;
private String currentMarketplace = null ;
boolean reset = false ;
#Override
public void onUserDataResponse(UserDataResponse userDataResponse) {
final UserDataResponse.RequestStatus status = userDataResponse.getRequestStatus();
switch (status) {
case SUCCESSFUL:
currentUserId = userDataResponse.getUserData().getUserId();
currentMarketplace = userDataResponse.getUserData().getMarketplace();
break ;
case FAILED:
case NOT_SUPPORTED:
break ;
}
}
#Override
public void onProductDataResponse(ProductDataResponse response) {
switch (response.getRequestStatus()) {
case SUCCESSFUL:
for ( final String s : response.getUnavailableSkus()) {
Log.v(TAG, "Unavailable SKU:" + s);
}
final Map<String, Product> products = response.getProductData();
for ( final String key : products.keySet()) {
Product product = products.get(key);
Log.v(TAG, String.format( "Product: %s\n Type: %s\n SKU: %s\n Price: %s\n Description: %s\n" , product.getTitle(), product.getProductType(), product.getSku(), product.getPrice(), product.getDescription()));
}
break ;
case FAILED:
Log.v(TAG, "ProductDataRequestStatus: FAILED" );
break ;
}
}
#Override
public void onPurchaseResponse(PurchaseResponse purchaseResponse) {
switch (purchaseResponse.getRequestStatus())
{
case SUCCESSFUL:
PurchasingService. notifyFulfillment(purchaseResponse.getReceipt().getReceiptId(), FulfillmentResult.FULFILLED);
break;
case FAILED:
break;
}
}
#Override
public void onPurchaseUpdatesResponse(PurchaseUpdatesResponse response) {
switch (response.getRequestStatus()) {
case SUCCESSFUL:
for ( final Receipt receipt : response.getReceipts()) {
// Process receipts
}
if (response.hasMore()) {
PurchasingService.getPurchaseUpdates(true);
}
break ;
case FAILED:
break ;
}
}
}
I found the solution for it you just need to run the following adb command on the device where you want to run the app:
adb shell setprop debug.amazon.sandboxmode debug

AltBeacon DidEnterRegion not triggered

In my xamarin android app, AltBeacon DidEnterRegion not triggered when MainLauncher attribute set to false for MainActivity. As I have SplashActivity for showing splash screen, I have to make the SplashActivity as my MainLauncher. I am using foreground service to detect iBeacon.
Code of my Application class:
namespace AltBeaconLibrarySample.Droid
{
#if DEBUG
[Application(Debuggable = true)]
#else
[Application(Debuggable = false)]
#endif
public class MainApplication : Application, IBootstrapNotifier
{
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
Region _generalRegion;
public bool IsStartedRanging { get; set; }
string foregroundServiceChannelId = "foregroundService";
string channelName = "ForegroundService";
int pendingIntentId = 1;
public MainApplication(IntPtr handle, JniHandleOwnership transer)
: base(handle, transer)
{
}
public void DidDetermineStateForRegion(int p0, Region p1)
{
}
public void DidEnterRegion(Region p0)
{
var beaconService = Xamarin.Forms.DependencyService.Get<IAltBeaconService>();
if (!IsStartedRanging)
{
beaconService.StartRanging();
IsStartedRanging = true;
}
}
public void DidExitRegion(Region p0)
{
var beaconService = Xamarin.Forms.DependencyService.Get<IAltBeaconService>();
if (IsStartedRanging)
{
beaconService.StopRanging();
IsStartedRanging = false;
}
beaconService.DidExitRegion();
}
public override void OnCreate()
{
base.OnCreate();
CrossCurrentActivity.Current.Init(this);
BeaconManager bm = BeaconManager.GetInstanceForApplication(this);
CreateNotificationChannel();
bm.EnableForegroundServiceScanning(GetForegroundServiceNotification(), 456);
bm.SetEnableScheduledScanJobs(false);
_generalRegion = new Org.Altbeacon.Beacon.Region/* AltBeaconOrg.BoundBeacon.Region*/("myEmptyBeaconId", Identifier.Parse("23A01AF0-232A-4518-9C0E-323FB773F5EF"), null, null);
regionBootstrap = new RegionBootstrap(this, _generalRegion);
backgroundPowerSaver = new BackgroundPowerSaver(this);
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channelDescription = "Foreground Sertrvice";
var channel = new NotificationChannel(foregroundServiceChannelId, channelName, NotificationImportance.High)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
public Notification GetForegroundServiceNotification()
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, foregroundServiceChannelId);
builder.SetSmallIcon(Resource.Drawable.xamagonBlue);
builder.SetContentTitle("Scanning for Beacons");
Intent intent = new Intent(this, typeof(MainActivity));
PendingIntent pendingIntent = PendingIntent.GetActivity(this, pendingIntentId, intent, PendingIntentFlags.UpdateCurrent);
builder.SetContentIntent(pendingIntent);
return builder.Build();
}
}
}
Code of SplashActivity class:
namespace AltBeaconLibrarySample.Droid
{
[Activity(Label = "AltBeaconLibrarySample.Droid",
Icon = "#mipmap/icon",
Theme = "#style/MainTheme",
MainLauncher = true,
NoHistory = true,
LaunchMode = Android.Content.PM.LaunchMode.SingleInstance,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class SplashActivity : Activity
{
static readonly string TAG = "X:" + typeof(SplashActivity).Name;
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
{
base.OnCreate(savedInstanceState, persistentState);
}
// Launches the startup task
protected override void OnResume()
{
base.OnResume();
Task startupWork = new Task(() => { SimulateStartup(); });
startupWork.Start();
}
// Simulates background work that happens behind the splash screen
async void SimulateStartup()
{
Log.Debug(TAG, "Performing some startup work that takes a bit of time.");
await Task.Delay(50); // Simulate a bit of startup work.
Log.Debug(TAG, "Startup work is finished - starting MainActivity.");
StartActivity(new Intent(Application.Context, typeof(MainActivity)));
}
}
}
Android manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.AltBeaconLibrarySample" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application android:label="AltBeaconLibrarySample.Android">
<service android:enabled="true" android:exported="false" android:isolatedProcess="false" android:label="Beacon" android:name="org.altbeacon.beacon.service.BeaconService"></service>
<service android:enabled="true" android:exported="false" android:name="org.altbeacon.beacon.BeaconIntentProcessor"></service>
<receiver android:name="org.altbeacon.beacon.startup.StartupBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
</application>
</manifest>
Code of MainActivity class:
namespace AltBeaconLibrarySample.Droid
{
[Activity(Label = "AltBeaconLibrarySample.Droid",
Icon = "#mipmap/icon",
Theme = "#style/MainTheme",
MainLauncher = false,
LaunchMode = Android.Content.PM.LaunchMode.SingleInstance,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IBeaconConsumer
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
CrossCurrentActivity.Current.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
#region IBeaconConsumer Implementation
public void OnBeaconServiceConnect()
{
}
#endregion
protected override void OnDestroy()
{
base.OnDestroy();
DependencyService.Get<IAltBeaconService>().OnDestroy();
}
protected override void OnResume()
{
base.OnResume();
}
protected override void OnPause()
{
base.OnPause();
}
}
}
BeaconManager code snippet:
BeaconManager bm = BeaconManager.GetInstanceForApplication(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity);
var iBeaconParser = new BeaconParser();
// Estimote > 2013
iBeaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
bm.BeaconParsers.Add(iBeaconParser);
bm.BackgroundMode = false;
bm.Bind((IBeaconConsumer)Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity);

JobService not running on Android Things

I try to work with JobScheduler and JobService on Android Things
My installation is RPI (Raspberry Pi) running IoT RPI3 1.0.2
this is my simple code:
package com.mystuff.jobservicetest;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JobScheduler jobScheduler = (JobScheduler) getSystemService(
Context.JOB_SCHEDULER_SERVICE);
ComponentName name = new ComponentName(this, JobServiceTest.class);
JobInfo jobInfo = new JobInfo.Builder(1,name).setPeriodic(1000).build();
int result = jobScheduler.schedule(jobInfo);
Log.d(TAG, "result = "+result);
}
public class JobServiceTest extends JobService {
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d(TAG, "Service job started");
return false;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
return false;
}
}
}
AndroidManifest.xml looks simple like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mystuff.jobservicetest">
<application>
<uses-library android:name="com.google.android.things" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.IOT_LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".MainActivity$JobServiceTest"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
</manifest>
Outcome of logcat is just:
W/JobInfo: Specified interval for 1 is +1s0ms. Clamped to +15m0s0ms
Specified flex for 1 is +1s0ms. Clamped to +5m0s0ms
D/MainActivity: result = 1
I am missing "Service job started" log. Seems to onStartJob is never called.
Any hints?
Thanks
A JobService can only be scheduled in intervals of 15 minutes or longer. If you want a shorter task, you may want to look at alternative methods.

Is it possible to register a Flutter app as an Android Intent Filter and to handle Incoming Intents?

One can launch another Activity using an Intent from a Flutter app:
https://github.com/flutter/flutter/blob/master/examples/widgets/launch_url.dart
import 'package:flutter/widgets.dart';
import 'package:flutter/services.dart';
void main() {
runApp(new GestureDetector(
onTap: () {
Intent intent = new Intent()
..action = 'android.intent.action.VIEW'
..url = 'http://flutter.io/';
activity.startActivity(intent);
},
child: new Container(
decoration: const BoxDecoration(
backgroundColor: const Color(0xFF006600)
),
child: new Center(
child: new Text('Tap to launch a URL!')
)
)
));
}
But can one do the following with the Flutter Activity Intent services when an Intent is passed to the app?
http://developer.android.com/training/sharing/receive.html
. . .
void onCreate (Bundle savedInstanceState) {
...
// Get intent, action and MIME type
Intent intent = getIntent();
. . .
To my knowledge, there is no way to handle incoming Intents from Dart code at this time. Specifically the case of handling incoming URLs is tracked by https://github.com/flutter/flutter/issues/357.
It's also possible to handle incoming intents from Java code and post the result across to Dart using the HostMessage system documented at https://flutter.io/platform-services/
Update 2020- Accept incoming intent in the Flutter from Flutter Doc
This maybe can help u, thios show how to handle
https://flutter.io/flutter-for-android/#what-is-the-equivalent-of-an-intent-in-flutter
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- ... -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
On MainActivity
public class MainActivity extends FlutterActivity {
private String sharedText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent); // Handle text being sent
}
}
MethodChannel(getFlutterView(), "app.channel.shared.data")
.setMethodCallHandler(MethodChannel.MethodCallHandler() {
#Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.contentEquals("getSharedText")) {
result.success(sharedText);
sharedText = null;
}
}
});
}
void handleSendText(Intent intent) {
sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
}
}
And finally to get it
class _SampleAppPageState extends State<SampleAppPage> {
static const platform = const MethodChannel('app.channel.shared.data');
String dataShared = "No data";
#override
void initState() {
super.initState();
getSharedText();
}
#override
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text(dataShared)));
}
getSharedText() async {
var sharedData = await platform.invokeMethod("getSharedText");
if (sharedData != null) {
setState(() {
dataShared = sharedData;
});
}
}
}
But if need to send a real intent to android system u can use this library
https://github.com/flutter/plugins/tree/master/packages/android_intent

Push Notifications Not Arriving

I am developing an android app using Xamarin and for push notifications I am using PushSharp.
I am having some trouble with receiving push notifications while the app is not running (after a reboot for example). Here is the Service code:
[BroadcastReceiver(Permission=GCMConstants.PERMISSION_GCM_INTENTS)]
[IntentFilter(new string[] { GCMConstants.INTENT_FROM_GCM_MESSAGE }, Categories = new string[] { "com.xxx" })]
[IntentFilter(new string[] { GCMConstants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new string[] { "com.xxx" })]
[IntentFilter(new string[] { GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY }, Categories = new string[] { "com.xxx" })]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class PushHandlerBroadcastReceiver : PushHandlerBroadcastReceiverBase<PushHandlerService>
{
//IMPORTANT: Change this to your own Sender ID!
//The SENDER_ID is your Google API Console App Project ID.
// Be sure to get the right Project ID from your Google APIs Console. It's not the named project ID that appears in the Overview,
// but instead the numeric project id in the url: eg: https://code.google.com/apis/console/?pli=1#project:785671162406:overview
// where 785671162406 is the project id, which is the SENDER_ID to use!
public static string[] SENDER_IDS = new string[] {"1234"};
public const string TAG = "PushSharp-GCM";
}
And here is the appManifest that is created:
<receiver android:permission="com.google.android.c2dm.permission.SEND" android:name="xxx.PushHandlerBroadcastReceiver">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.xxx" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.xxx" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gcm.intent.RETRY" />
<category android:name="com.xxx" />
</intent-filter>
</receiver>
<service android:name="xxx.PushHandlerService" />
My service code is very basic:
[Service] //Must use the service tag
public class PushHandlerService : PushHandlerServiceBase
{
public PushHandlerService () : base (PushHandlerBroadcastReceiver.SENDER_IDS)
{
}
protected override void OnRegistered (Context context, string registrationId)
{
...
}
protected override void OnUnRegistered (Context context, string registrationId)
{
...
}
protected override void OnMessage (Context context, Intent intent)
{
...
}
protected override bool OnRecoverableError (Context context, string errorId)
{
...
}
protected override void OnError (Context context, string errorId)
{
...
}
void createNotification (string title, string desc, Intent intent)
{
...
}
}
Am I missing something? why is the service not started once the phone is rebooted. Should I be doing something in the broadcast receiver? Should I register to the push notifications in the service constructor (to handle the case where the app is not started yet)?
If your service does not start on reboot you can add a BroadcastReceiver to your project which starts it:
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class MyBootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
MyNotificationService.RunIntentInService(context, intent);
SetResult(Result.Ok, null, null);
}
}
If you are using PushSharp you can probably get away with adding that filter to the PushHandlerBroadcastReceiverBase implementation.

Resources