After phone restart 'unfortunately app has stopped' error - xamarin.forms

I get "unfortunately app has stopped" error after phone restart. My Phone is Oreo 8 but another phone with Nougat 7.1.1 also having the same error after phone restart. I use James Montemagnos' MyStepCounter bound services codes from GitHub with some changes in VS 2017 (Xamarin Cross-Platform App). The app is working fine if once started after phone restart with this error, else it is not counting steps and not working on the background. If I check the app in Phone Settings-General-Battery-Power saving exclusions then it works with no problems after phone restart and it is counting steps on the background without starting the app on Oreo phone. But there are no settings for battery power saving exclusions on the other phone
BootReceiver.cs
[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true)]
[IntentFilter(new string[] { Intent.ActionBootCompleted, Intent.ActionLockedBootCompleted, "android.intent.action.QUICKBOOT_POWERON", "com.htc.intent.action.QUICKBOOT_POWERON" })]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var stepServiceIntent = new Intent(context, typeof(StepService));
context.StartService(stepServiceIntent);
}
}
StepServiceBinder.cs
public class StepServiceBinder : Binder
{
StepService stepService;
public StepServiceBinder(StepService service)
{
this.stepService = service;
}
public StepService StepService
{
get { return stepService; }
}
}
StepServiceConnection.cs
public class StepServiceConnection : Java.Lang.Object, IServiceConnection
{
MainActivity activity;
public StepServiceConnection(MainActivity activity)
{
this.activity = activity;
}
public void OnServiceConnected(ComponentName name, IBinder service)
{
var serviceBinder = service as StepServiceBinder;
if (serviceBinder != null)
{
activity.Binder = serviceBinder;
activity.IsBound = true;
}
}
public void OnServiceDisconnected(ComponentName name)
{
activity.IsBound = false;
}
}
StepService.cs
public class StepServiceConnection : Java.Lang.Object, IServiceConnection
{
MainActivity activity;
public StepServiceConnection(MainActivity activity)
{
this.activity = activity;
}
public void OnServiceConnected(ComponentName name, IBinder service)
{
var serviceBinder = service as StepServiceBinder;
if (serviceBinder != null)
{
activity.Binder = serviceBinder;
activity.IsBound = true;
}
}
public void OnServiceDisconnected(ComponentName name)
{
activity.IsBound = false;
}
}
StepService.cs
[Service(Enabled = true)]
[IntentFilter(new String[] { "com.PedometerApp.StepService" })]
public class StepService : Service, ISensorEventListener, INotifyPropertyChanged
{
private SensorManager sManager;
private bool isRunning;
private long stepsToday = 0;
public bool WarningState
{
get;
set;
}
public long StepsToday
{
get { return stepsToday; }
set
{
if (stepsToday == value)
return;
stepsToday = value;
OnPropertyChanged("StepsToday");
Settings.CurrentDaySteps = value;
MessagingCenter.Send<object, long>(this, "Steps", Settings.CurrentDaySteps);
}
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
var alarmManager = ((AlarmManager)ApplicationContext.GetSystemService(AlarmService));
var intent2 = new Intent(this, typeof(StepService));
intent2.PutExtra("warning", WarningState);
var stepIntent = PendingIntent.GetService(ApplicationContext, 200, intent2, PendingIntentFlags.UpdateCurrent);
alarmManager.Set(AlarmType.Rtc, Java.Lang.JavaSystem
.CurrentTimeMillis() + 1000 * 60 * 60, stepIntent);
var warning = false;
if (intent != null)
warning = intent.GetBooleanExtra("warning", false);
Startup();
return StartCommandResult.Sticky;
}
public override void OnTaskRemoved(Intent rootIntent)
{
base.OnTaskRemoved(rootIntent);
UnregisterListeners();
var intent = new Intent(this, typeof(StepService));
intent.PutExtra("warning", WarningState);
((AlarmManager)GetSystemService(AlarmService)).Set(AlarmType.Rtc, Java.Lang.JavaSystem
.CurrentTimeMillis() + 500,
PendingIntent.GetService(this, 201, intent, 0));
}
private void Startup(bool warning = false)
{
CrunchDates(true);
if (!isRunning)
{
RegisterListeners();
WarningState = warning;
}
isRunning = true;
}
public override void OnDestroy()
{
base.OnDestroy();
UnregisterListeners();
isRunning = false;
CrunchDates();
}
void RegisterListeners()
{
sManager = GetSystemService(SensorService) as SensorManager;
sManager.RegisterListener(this, sManager.GetDefaultSensor(SensorType.StepCounter), SensorDelay.Ui);
}
void UnregisterListeners()
{
if (!isRunning)
return;
try
{
var sensorManager = (SensorManager)GetSystemService(Context.SensorService);
sensorManager.UnregisterListener(this);
isRunning = false;
}
catch (Exception ex)
{
}
}
StepServiceBinder binder;
public override Android.OS.IBinder OnBind(Android.Content.Intent intent)
{
binder = new StepServiceBinder(this);
return binder;
}
public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy)
{
//do nothing here
}
public void AddSteps(long count)
{
if (lastSteps == 0)
{
lastSteps = count;
}
newSteps = count - lastSteps;
if (newSteps < 0)
newSteps = 1;
else if (newSteps > 100)
newSteps = 1;
lastSteps = count;
CrunchDates();
Settings.TotalSteps += newSteps;
StepsToday = Settings.TotalSteps - Settings.StepsBeforeToday;
}
long newSteps = 0;
long lastSteps = 0;
public void OnSensorChanged(SensorEvent e)
{
if (lastSteps < 0)
lastSteps = 0;
var count = (long)e.Values[0];
WarningState = false;
AddSteps(count);
}
private void CrunchDates(bool startup = false)
{
if (!Utils.IsSameDay)
{
var yesterday = Settings.CurrentDay;
var dayEntry = StepEntryManager.GetStepEntry(yesterday);
if (dayEntry == null || dayEntry.Date.DayOfYear != yesterday.DayOfYear)
{
dayEntry = new StepEntry();
}
dayEntry.Date = yesterday;
dayEntry.Steps = Settings.CurrentDaySteps;
Settings.CurrentDay = DateTime.Today;
Settings.CurrentDaySteps = 0;
Settings.StepsBeforeToday = Settings.TotalSteps;
StepsToday = 0;
try
{
StepEntryManager.SaveStepEntry(dayEntry);
}
catch (Exception ex)
{
Console.WriteLine("Error {0}", ex.Message);
}
}
else if (startup)
{
StepsToday = Settings.TotalSteps - Settings.StepsBeforeToday;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}

Related

iOS web view renderer doesn't update its value

I have implemented WebViewRenderer it works well on Android but it doesn't work on iOS. It displays the value, but then user clicks next button and the value doesn't update. I have tried the the example on ms website, but that displayed no text, I don't have the values from URL. I have also tried several post here.
[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace MyApp.iOS.Renderers
{
public class ExtendedWebViewRenderer : ViewRenderer<ExtendedWebView, WKWebView>
{
WKWebView _wkWebView;
static ExtendedWebView _xwebView = null;
protected override void OnElementChanged(ElementChangedEventArgs<ExtendedWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
WKWebViewConfiguration config = new WKWebViewConfiguration();
_wkWebView = new WKWebView(Frame, config);
_wkWebView.NavigationDelegate = new CustomWKNavigationDelegate(this);
SetNativeControl(_wkWebView);
}
if (e.NewElement != null)
{
HtmlWebViewSource source = (Xamarin.Forms.HtmlWebViewSource)Element.Source;
string html = source.Html;
_wkWebView.LoadHtmlString(html, baseUrl: null);
_wkWebView.ScrollView.ScrollEnabled = false;
_wkWebView.SizeToFit();
}
}
}
public class CustomWKNavigationDelegate : WKNavigationDelegate
{
ExtendedWebViewRenderer _webViewRenderer;
public CustomWKNavigationDelegate(ExtendedWebViewRenderer webViewRenderer)
{
_webViewRenderer = webViewRenderer;
}
public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
var wv = _webViewRenderer.Element as ExtendedWebView;
if (wv != null)
{
await System.Threading.Tasks.Task.Delay(100); // wait here till content is rendered
wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
}
}
}
}
[assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
namespace MyApp.Droid.Renderers
{
public class ExtendedWebViewRenderer : WebViewRenderer
{
public static int _webViewHeight;
static ExtendedWebView _xwebView = null;
public WebView _webView;
bool isScroll;
[Obsolete]
public ExtendedWebViewRenderer(Context context) : base(context)
{
}
class ExtendedWebViewClient : WebViewClient
{
WebView _webView;
public async override void OnPageFinished(WebView view, string url)
{
try
{
_webView = view;
if (_xwebView != null)
{
view.Settings.JavaScriptEnabled = true;
await Task.Delay(100);
string result = await _xwebView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");
_xwebView.HeightRequest = Convert.ToDouble(result);
}
base.OnPageFinished(view, url);
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message}");
}
}
public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
{
return true;
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
_xwebView = e.NewElement as ExtendedWebView;
_webView = Control;
if (e.OldElement == null)
{
_webView.SetWebViewClient(new ExtendedWebViewClient());
}
}
}
}
public class ExtendedWebView : WebView
{
public ExtendedWebView()
{
}
}
XAML
<controls:ExtendedWebView
VerticalOptions="FillAndExpand" Grid.RowSpan="2"
x:Name="enView"
Opacity="1"
Source="{Binding CZ, Mode=TwoWay}"/>
private static HtmlWebViewSource htmlSourceExplanation = new HtmlWebViewSource();
public HtmlWebViewSource Cz
{
get { return _cz; }
set
{
_cz = value;
NotifyPropertyChanged(nameof(Cz));
}
}
private void SetExplanationDetail(string text, string text2)
{
htmlSourceExplanation.Html = _style + "<div class=\"text\"><div>" + text + "</div><div>" + text2 + "</div></div>";
_cz = htmlSourceExplanation;
NotifyPropertyChanged("Cz");
}
I expect the value to change once to user cliks the button. `

Save data from fragment to custom session

I am creating a project in which I am using navigation drawer and on navigation item click it opens a login page and after login it movies to my main activity. Now, I want to save my login details and all data in my custom shared preference from the fragment. After that it on app restarts and I go to navigation login items it should check if the user is already logged in then it should move to an activity otherwise it should run my login fragment
my login fragment
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
CDSMainViewModel =
ViewModelProviders.of(this).get(CDP_MainViewModel.class);
View root = inflater.inflate(R.layout.fragment_cdplogin, container, false);
context = container.getContext();
context = getActivity().getApplicationContext();
session = new Session(context);
if (session.isLoggedIn()) {
Intent itra = new Intent(getActivity().getApplicationContext(), Verification_Activity.class);
startActivity(itra);
getActivity().finish();
}
else{
login_button = root.findViewById(R.id.button_click_login);
edit1 = root.findViewById(R.id.input_username);
edit2 = root.findViewById(R.id.input_password);
layout_1 = root.findViewById(R.id.usnamelayout);
layout_2 = root.findViewById(R.id.password_layout);
login_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
return root;
}
private void Login_data() {
String URL = "http://117.240.196.238:8080/api/cdp/getAuth";
Log.i("response", URL);
StringRequest jsonObjRequest = new StringRequest(
Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("response_login", response);
parseData1(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("volley", "Error: " + error.getMessage());
showServerConnectionError();
}
}) {
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("AuthID", name);
params.put("AuthPwd", password);
return params;
}
};
RequestQueue queue = SingletonRequestQueue.getInstance(getActivity().getApplicationContext()).getRequestQueue();
queue.add(jsonObjRequest);
}
private void parseData1(String response){
try {
JSONObject json = new JSONObject(response);
int success = json.getInt("success");
String msg = json.getString("message");
if(success == 1){
Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
JSONArray recData = json.getJSONArray("data");
for (int i = 0; i < recData.length(); i++) {
JSONObject c = recData.getJSONObject(i);
String uname = name;
String upass = password;
String emp_id = c.getString("emp_id");
String empname = c.getString("EmpName");
String office = c.getString("OfficeNameFull");
String desig = c.getString("DesignationName");
String mobile = c.getString("EmpMobile");
String office_code = c.getString("OfficeCode");
String OfficeType = c.getString("OfficeType");
String district = c.getString("DistrictCode");
String DistrictName = c.getString("DistrictName");
String designationCode = c.getString("designationCode");
String DesignationName1 = c.getString("DesignationName1");
String DesigShortName = c.getString("DesigShortName");
Log.i("session",district);
//Here my loginsession is not working its not saving my data in my session..
Session.getInstance(getContext()).loginsession(emp_id,uname,upass,empname,office,desig,mobile,office_code,OfficeType,district,DistrictName,designationCode,DesignationName1,DesigShortName);
// String email = SessionManager.getInstance(context).getUserEmail();
// session.loginsession(emp_id,uname,upass,empname,office,desig,mobile,office_code,OfficeType,district,DistrictName,designationCode,DesignationName1,DesigShortName);
Intent its12 = new Intent(getActivity().getApplicationContext(), Verification_Activity.class);
startActivity(its12);
getActivity().overridePendingTransition(R.anim.from_right, R.anim.slide_to_left);
getActivity().finish();
}
} else {
Toast.makeText(context,msg, Toast.LENGTH_LONG).show();
}
}catch(Exception ex){
}
}
}
//Session manager class
package com.example.agridept.domain;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import com.example.agridept.ui.CDP_login.CDP_MainFragment;
public class Session {
private static Session jInstance;
SharedPreferences preferences;
SharedPreferences.Editor editor;
Context context;
int PRIVATE_MODE = 0;
private static final String IS_LOGIN = "IsLoggedIn";
private static final String PREF_NAME = "AndroidHivePref";
String emp_id1,username1,password1 ,empname1 , office1 , desig1, mobile1, office_code1, OfficeType1 , district1 ,DistrictName1 , designationCode1, DesignationName11 , DesigShortName1;
public Session(Context context){
this.context = context;
preferences = context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
editor = preferences.edit();
}
public void loginsession(String emp_id,String username,String password11 ,String empname ,String office ,String desig,String mobile,String office_code,String OfficeType ,String district ,String DistrictName ,String designationCode,String DesignationName1 ,String DesigShortName){
editor.putBoolean(IS_LOGIN, true);
editor.putString(emp_id1,emp_id);
editor.putString(username1,username);
editor.putString(password1,password11);
editor.putString(empname1,empname);
editor.putString(office1,office);
editor.putString(desig1,desig);
editor.putString(mobile1,mobile);
editor.putString(office_code1,office_code);
editor.putString(OfficeType1,OfficeType);
editor.putString(district1,district);
editor.putString(DistrictName1,DistrictName);
editor.putString(designationCode1,designationCode);
editor.putString(DesignationName11,DesignationName1);
editor.putString(DesigShortName1,DesigShortName);
}
public boolean isLoggedIn() {
return preferences.getBoolean(IS_LOGIN, false);
}
public void logoutUser() {
// Clearing all data from Shared Preferences
editor.clear();
editor.commit();
// After logout redirect user to Loing Activity
Intent i = new Intent(context, CDP_MainFragment.class);
// Closing all the Activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Add new Flag to start new Activity
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Staring Login Activity
context.startActivity(i);
}
public void clearinfo() {
// Clearing all data from Shared Preferences
editor.clear();
editor.commit();
}
public SharedPreferences getPreferences() {
return preferences;
}
public void setPreferences(SharedPreferences preferences) {
this.preferences = preferences;
}
public SharedPreferences.Editor getEditor() {
return editor;
}
public void setEditor(SharedPreferences.Editor editor) {
this.editor = editor;
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public int getPRIVATE_MODE() {
return PRIVATE_MODE;
}
public void setPRIVATE_MODE(int PRIVATE_MODE) {
this.PRIVATE_MODE = PRIVATE_MODE;
}
public static String getIsLogin() {
return IS_LOGIN;
}
public static String getPrefName() {
return PREF_NAME;
}
public String getEmp_id1() {
return emp_id1;
}
public void setEmp_id1(String emp_id1) {
this.emp_id1 = emp_id1;
}
public String getPassword1() {
return password1;
}
public void setPassword1(String password1) {
this.password1 = password1;
}
public String getEmpname1() {
return empname1;
}
public void setEmpname1(String empname1) {
this.empname1 = empname1;
}
public String getOffice1() {
return office1;
}
public void setOffice1(String office1) {
this.office1 = office1;
}
public String getDesig1() {
return desig1;
}
public void setDesig1(String desig1) {
this.desig1 = desig1;
}
public String getMobile1() {
return mobile1;
}
public void setMobile1(String mobile1) {
this.mobile1 = mobile1;
}
public String getOffice_code1() {
return office_code1;
}
public void setOffice_code1(String office_code1) {
this.office_code1 = office_code1;
}
public String getOfficeType1() {
return OfficeType1;
}
public void setOfficeType1(String officeType1) {
OfficeType1 = officeType1;
}
public String getDistrict1() {
return district1;
}
public void setDistrict1(String district1) {
this.district1 = district1;
}
public String getDistrictName1() {
return DistrictName1;
}
public void setDistrictName1(String districtName1) {
DistrictName1 = districtName1;
}
public String getDesignationCode1() {
return designationCode1;
}
public void setDesignationCode1(String designationCode1) {
this.designationCode1 = designationCode1;
}
public String getDesignationName11() {
return DesignationName11;
}
public void setDesignationName11(String designationName11) {
DesignationName11 = designationName11;
}
public String getDesigShortName1() {
return DesigShortName1;
}
public void setDesigShortName1(String desigShortName1) {
DesigShortName1 = desigShortName1;
}
public static synchronized Session getInstance(Context context) {
if (jInstance != null) {
return jInstance;
} else {
jInstance = new Session(context);
return jInstance;
}
}
}

Xamarin Firebase and Syncfusion DataGrid. How do I listen for Firebase changes?

I'm having trouble with the coding to properly listen for Firebase add or update events. My attempt below has the data loading into the Syncfusion Datagrid, but there is a weird glitch where when I click the mouse on the Datagrid and pull-down, the first record in my 4 record set gets added to the bottom of the Datagrid, showing a 5th record... if I update an element in the Datagrid, the change is not reflected in Firebase. If I add or change a value in firebase, it does not update in Datagrid. Any help to steer me in the right direction to get this to work would be appreciated. Here's the code:
the VisualStudio 2019
CookPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Chart_sample"
xmlns:gauge="clr-namespace:Syncfusion.SfGauge.XForms;assembly=Syncfusion.SfGauge.XForms"
xmlns:Syncfusion="clr-namespace:Syncfusion.SfDataGrid.XForms;assembly=Syncfusion.SfDataGrid.XForms"
mc:Ignorable="d"
x:Class="Chart_sample.Views.CookPage">
<StackLayout>
<Syncfusion:SfDataGrid x:Name="sfGrid">
</Syncfusion:SfDataGrid>
</StackLayout>
</ContentPage>
CookPage.xaml.cs
using Chart_sample.Services;
using Syncfusion.SfDataGrid.XForms;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Chart_sample.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CookPage : ContentPage
{
FirebaseHelper firebaseHelper = new FirebaseHelper();
public CookPage()
{
InitializeComponent();
// for Syncfusion DataGrid
firebaseHelper.listenForEvents();
sfGrid.ItemsSource = ViewProgramModel._returnedEvents;
sfGrid.ColumnSizer = ColumnSizer.Star;
sfGrid.AllowEditing = true;
sfGrid.NavigationMode = NavigationMode.Cell;
sfGrid.SelectionMode = Syncfusion.SfDataGrid.XForms.SelectionMode.Single;
}
}
}
FirebaseHelper.cs
using Firebase.Database;
using Firebase.Database.Query;
using System;
using System.Linq;
namespace Chart_sample.Services
{
public class FirebaseHelper
{
internal ViewProgramModel ViewProgramModel { get; set; }
FirebaseClient firebase = new FirebaseClient("https://pelletpirate.firebaseio.com/");
private readonly string ChildProgram = "ControllerData/Pellet_Pirate_1/Program";
public static IDisposable returnedEvents;
public async void listenForEvents()
{
ViewProgramModel._returnedEvents.Clear();
var programs = await firebase.Child(ChildProgram).OnceAsync<ViewProgramModel>();
for (int i = 0; i < programs.Count; i++)
{
ViewProgramModel._returnedEvents.Add(programs.ElementAt(i).Object);
}
returnedEvents = firebase.Child(ChildProgram).OrderByKey().AsObservable<ViewProgramModel>()
.Subscribe(eventReceived =>
{
if (eventReceived.EventType == Firebase.Database.Streaming.FirebaseEventType.InsertOrUpdate)
{
var found = ViewProgramModel._returnedEvents.FirstOrDefault(i => i._KEY == eventReceived.Key);
if (found == null)
{
// not in observable collection, add it
ViewProgramModel._returnedEvents.Add(eventReceived.Object);
}
else
{
// event was updated
int tempIndex = ViewProgramModel._returnedEvents.IndexOf(found);
ViewProgramModel._returnedEvents[tempIndex] = eventReceived.Object;
}
}
});
}
}
}
ViewProgrammodel.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace Chart_sample
{
public class ViewProgramModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _KEy;
private string MOde;
private int TArget;
private string TRigger;
private int TRiggerVAlue;
public string _KEY
{
get { return _KEy; }
set
{
this._KEy = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("_KEY"));
}
}
public string MODE
{
get { return MOde; }
set
{
this.MOde = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MODE"));
}
}
public int TARGET
{
get { return TArget; }
set
{
this.TArget = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TARGET"));
}
}
public string TRIGGER
{
get { return TRigger; }
set
{
this.TRigger = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TRIGGER"));
}
}
public int TRIGGERVALUE
{
get { return TRiggerVAlue; }
set
{
this.TRiggerVAlue = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TRIGGERVALUE"));
}
}
public static ObservableCollection<ViewProgramModel> _returnedEvents = new ObservableCollection<ViewProgramModel>();
}
}
I edit your demo, I achieve the update, Add, delete function.
Here is running GIF.
I change your ViewProgramModel like following code. Just move the _returnedEvents to the FirebaseHelper.cs
namespace Chart_sample
{
public class ViewProgramModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _KEy;
private string MOde;
private int TArget;
private string TRigger;
private int TRiggerVAlue;
public string _KEY
{
get { return _KEy; }
set
{
this._KEy = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("_KEY"));
}
}
public string MODE
{
get { return MOde; }
set
{
this.MOde = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MODE"));
}
}
public int TARGET
{
get { return TArget; }
set
{
this.TArget = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TARGET"));
}
}
public string TRIGGER
{
get { return TRigger; }
set
{
this.TRigger = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TRIGGER"));
}
}
public int TRIGGERVALUE
{
get { return TRiggerVAlue; }
set
{
this.TRiggerVAlue = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TRIGGERVALUE"));
}
}
}
Here is FirebaseHelper.cs, Note: I achieve the update function just for the TARGET Column, I suggest your to add a Primary-key(Auto-increase) for every record in your database to achieve your search function.
public class FirebaseHelper
{
public ObservableCollection<ViewProgramModel> _returnedEvents { get; set; }
public FirebaseHelper()
{
_returnedEvents = new ObservableCollection<ViewProgramModel>();
}
// internal ViewProgramModel MyViewProgramModel { get; set; }
FirebaseClient firebase = new FirebaseClient("https://xxxxxxxxxx.firebaseio.com/");
private readonly string ChildProgram = "ControllerData/xxxxxx_Pirate_1/Program";
public static IDisposable returnedEvents;
public async Task AddViewProgramModel()
{
//new ViewProgramModel() { MODE="test", TARGET=122, TRIGGER="122", TRIGGERVALUE=333, }
await firebase
.Child(ChildProgram)
.PostAsync( new ViewProgramModel() { MODE = "test", TARGET = 122, TRIGGER = "122", TRIGGERVALUE = 333, });
GetAllData();
}
public async Task UpdateViewProgramModel(ViewProgramModel viewProgramModel , string oldValue)
{
var toUpdatePerson = (await firebase
.Child(ChildProgram)
.OnceAsync<ViewProgramModel>()).FirstOrDefault(a => a.Object.TARGET == Convert.ToInt32( oldValue));
await firebase
.Child(ChildProgram)
.Child(toUpdatePerson.Key)
.PutAsync(viewProgramModel);
GetAllData();
}
public async Task DeleteViewProgramModel(string mode)
{
var toDeletePerson = (await firebase
.Child(ChildProgram)
.OnceAsync<ViewProgramModel>()).FirstOrDefault(a => a.Object.MODE == mode);
await firebase.Child(ChildProgram).Child(toDeletePerson.Key).DeleteAsync();
GetAllData();
}
public async void GetAllData()
{
_returnedEvents.Clear();
var programs = await firebase.Child(ChildProgram).OnceAsync<ViewProgramModel>();
for (int i = 0; i < programs.Count; i++)
{
_returnedEvents.Add(programs.ElementAt(i).Object);
}
}
public async void listenForEvents()
{
_returnedEvents.Clear();
var programs = await firebase.Child(ChildProgram).OnceAsync<ViewProgramModel>();
for (int i = 0; i < programs.Count; i++)
{
_returnedEvents.Add(programs.ElementAt(i).Object);
}
//returnedEvents = firebase.Child(ChildProgram).OrderByKey().AsObservable<ViewProgramModel>()
// .Subscribe(eventReceived =>
// {
// if (eventReceived.EventType == Firebase.Database.Streaming.FirebaseEventType.InsertOrUpdate)
// {
// var found = _returnedEvents.FirstOrDefault(i => i._KEY == eventReceived.Key);
// if (found == null)
// {
// // not in observable collection, add it
// _returnedEvents.Add(eventReceived.Object);
// }
// else
// {
// // event was updated
// int tempIndex = _returnedEvents.IndexOf(found);
// _returnedEvents[tempIndex] = eventReceived.Object;
// }
// }
//});
}
}
}
Here is CookPage.xaml
<StackLayout>
<Button Text="add" Clicked="Button_Clicked"></Button>
<Button Text="delete" Clicked="Button_Clicked_1"></Button>
<Syncfusion:SfDataGrid x:Name="sfGrid" ItemsSource="{Binding _returnedEvents, Mode=TwoWay} " >
</Syncfusion:SfDataGrid>
</StackLayout>
Here is code about CookPage.cs.
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CookPage : ContentPage
{
FirebaseHelper firebaseHelper = new FirebaseHelper();
public CookPage()
{
InitializeComponent();
// for Syncfusion DataGrid
firebaseHelper.listenForEvents();
//sfGrid.ItemsSource = ViewProgramModel._returnedEvents;
BindingContext= firebaseHelper;
sfGrid.ColumnSizer = ColumnSizer.Star;
sfGrid.AllowEditing = true;
sfGrid.NavigationMode = NavigationMode.Cell;
sfGrid.AllowLoadMore = true;
sfGrid.AutoGenerateColumns = true;
//sfGrid.AutoGenerateColumnsMode= AutoGenerateColumnsMode.
sfGrid.SelectionMode = Syncfusion.SfDataGrid.XForms.SelectionMode.Single;
sfGrid.AllowPullToRefresh = true;
sfGrid.CurrentCellEndEdit += SfGrid_CurrentCellEndEdit; ;
}
private async void SfGrid_CurrentCellEndEdit(object sender, GridCurrentCellEndEditEventArgs e)
{
//throw new System.NotImplementedException();
var selectObj = sender as SfDataGrid;
RowColumnIndex index = e.RowColumnIndex;
int selectColumnIndex = index.ColumnIndex; //2
int selectRowIndex = index.RowIndex; //3
var ob=firebaseHelper._returnedEvents;
ViewProgramModel selectObject =ob[selectRowIndex-1];
var newVale = e.NewValue.ToString();
var oldeValue = e.OldValue.ToString();
//Here just judge TARGET Column, you should judge all Columns
if (selectColumnIndex == 2)
{
selectObject.TARGET = Convert.ToInt32(newVale);
}
//If you want to achieve the all Grid change function, you should judge the selectRowIndex for every change
//if (selectRowIndex==1)
//{
// selectObject.MODE = newVale;
//}else if (selectRowIndex==2)
//{
// selectObject.TARGET = Convert.ToInt32( newVale);
//}else if (selectRowIndex == 3)
//{
// selectObject.TRIGGER = newVale;
//}else if (selectRowIndex == 4)
//{
// selectObject.TRIGGERVALUE = Convert.ToInt32(newVale);
//}
await firebaseHelper.UpdateViewProgramModel(selectObject, oldeValue);
}
private async void Button_Clicked(object sender, System.EventArgs e)
{
await firebaseHelper.AddViewProgramModel();
}
private async void Button_Clicked_1(object sender, System.EventArgs e)
{
await firebaseHelper.DeleteViewProgramModel("test");
}
}

Xamarin Forms pedometer application foreground service problem on android oreo 8.1 and android pie 9.0

I am using foreground service if OS version >= 8.0. On android 8.1 and 9.0 when my pedometer app is open or on the background it is counting steps, but not when the app is closed. Also after closing the app notification icon disappearing from the phone screen. Tested on Oreo 8.0 using foreground service, it is working fine and counting steps when the app is closed. Tested also on android Nougat 7.0 with background service and working with no problems.
BootReceiver.cs
[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true)]
[IntentFilter(new string[] { Intent.ActionBootCompleted, Intent.ActionLockedBootCompleted, "android.intent.action.QUICKBOOT_POWERON", "com.htc.intent.action.QUICKBOOT_POWERON" })]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var stepServiceIntent = new Intent(context, typeof(StepService));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
context.StartForegroundService(stepServiceIntent);
}
else
{
context.StartService(stepServiceIntent);
}
}
}
StepServiceBinder.cs
public class StepServiceBinder : Binder
{
StepService stepService;
public StepServiceBinder(StepService service)
{
this.stepService = service;
}
public StepService StepService
{
get { return stepService; }
}
}
StepServiceConnection.cs
public class StepServiceConnection : Java.Lang.Object, IServiceConnection
{
MainActivity activity;
public StepServiceConnection(MainActivity activity)
{
this.activity = activity;
}
public void OnServiceConnected(ComponentName name, IBinder service)
{
var serviceBinder = service as StepServiceBinder;
if (serviceBinder != null)
{
activity.Binder = serviceBinder;
activity.IsBound = true;
}
}
public void OnServiceDisconnected(ComponentName name)
{
activity.IsBound = false;
}
}
*Manifest.xml *
<manifest android:versionName="1.1" package="com.PedometerApp" android:installLocation="internalOnly" android:versionCode="11">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="27" />
<application android:label="My Pedometer" android:icon="#drawable/logo"> </application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
</manifest>
StepService.cs
[Service(Enabled = true)]
[IntentFilter(new String[] { "com.PedometerApp.StepService" })]
public class StepService : Service, ISensorEventListener, INotifyPropertyChanged
{
private SensorManager sManager;
private bool isRunning;
private long stepsToday = 0;
public bool WarningState
{
get;
set;
}
public long StepsToday
{
get { return stepsToday; }
set
{
if (stepsToday == value)
return;
stepsToday = value;
OnPropertyChanged("StepsToday");
Settings.CurrentDaySteps = value;
MessagingCenter.Send<object, long>(this, "Steps", Settings.CurrentDaySteps);
}
}
public const string PRIMARY_NOTIF_CHANNEL = "exampleChannel";
public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
RegisterForService();
var warning = false;
if (intent != null)
warning = intent.GetBooleanExtra("warning", false);
Startup();
return StartCommandResult.Sticky;
}
private void RegisterForService()
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channel = new NotificationChannel(PRIMARY_NOTIF_CHANNEL, "Pedometer Service Channel", NotificationImportance.Low)
{
Description = "Foreground Service Channel"
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
var notification = new Notification.Builder(this, PRIMARY_NOTIF_CHANNEL)
.SetContentTitle("Service")
.SetContentText("Running")
.SetSmallIcon(Resource.Drawable.ic_stat_name)
.SetContentIntent(BuildIntentToShowMainActivity())
.SetOngoing(true)
.Build();
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
}
else
{
BuildIntentToShowMainActivity();
}
}
PendingIntent BuildIntentToShowMainActivity()
{
var alarmManager = ((AlarmManager)ApplicationContext.GetSystemService(AlarmService));
var intent2 = new Intent(this, typeof(StepService));
intent2.PutExtra("warning", WarningState);
var stepIntent = PendingIntent.GetService(ApplicationContext, 200, intent2, PendingIntentFlags.UpdateCurrent);
alarmManager.Set(AlarmType.Rtc, Java.Lang.JavaSystem
.CurrentTimeMillis() + 1000 * 60 * 60, stepIntent);
return stepIntent;
}
public override void OnTaskRemoved(Intent rootIntent)
{
base.OnTaskRemoved(rootIntent);
UnregisterListeners();
var intent = new Intent(this, typeof(StepService));
intent.PutExtra("warning", WarningState);
((AlarmManager)GetSystemService(AlarmService)).Set(AlarmType.Rtc, Java.Lang.JavaSystem
.CurrentTimeMillis() + 500,
PendingIntent.GetService(this, 201, intent, 0));
}
private void Startup(bool warning = false)
{
CrunchDates(true);
if (!isRunning)
{
RegisterListeners();
WarningState = warning;
}
isRunning = true;
}
public override void OnDestroy()
{
base.OnDestroy();
UnregisterListeners();
isRunning = false;
CrunchDates();
}
void RegisterListeners()
{
sManager = GetSystemService(SensorService) as SensorManager;
sManager.RegisterListener(this, sManager.GetDefaultSensor(SensorType.StepCounter), SensorDelay.Ui);
}
void UnregisterListeners()
{
if (!isRunning)
return;
try
{
var sensorManager = (SensorManager)GetSystemService(Context.SensorService);
sensorManager.UnregisterListener(this);
isRunning = false;
}
catch (Exception ex)
{
}
}
StepServiceBinder binder;
public override Android.OS.IBinder OnBind(Android.Content.Intent intent)
{
binder = new StepServiceBinder(this);
return binder;
}
public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy)
{
//do nothing here
}
public void AddSteps(long count)
{
if (lastSteps == 0)
{
lastSteps = count;
}
newSteps = count - lastSteps;
if (newSteps < 0)
newSteps = 1;
else if (newSteps > 100)
newSteps = 1;
lastSteps = count;
CrunchDates();
Settings.TotalSteps += newSteps;
StepsToday = Settings.TotalSteps - Settings.StepsBeforeToday;
}
long newSteps = 0;
long lastSteps = 0;
public void OnSensorChanged(SensorEvent e)
{
if (lastSteps < 0)
lastSteps = 0;
var count = (long)e.Values[0];
WarningState = false;
AddSteps(count);
}
private void CrunchDates(bool startup = false)
{
if (!Utils.IsSameDay)
{
var yesterday = Settings.CurrentDay;
var dayEntry = StepEntryManager.GetStepEntry(yesterday);
if (dayEntry == null || dayEntry.Date.DayOfYear != yesterday.DayOfYear)
{
dayEntry = new StepEntry();
}
dayEntry.Date = yesterday;
dayEntry.Steps = Settings.CurrentDaySteps;
Settings.CurrentDay = DateTime.Today;
Settings.CurrentDaySteps = 0;
Settings.StepsBeforeToday = Settings.TotalSteps;
StepsToday = 0;
try
{
StepEntryManager.SaveStepEntry(dayEntry);
}
catch (Exception ex)
{
Console.WriteLine("Error {0}", ex.Message);
}
}
else if (startup)
{
StepsToday = Settings.TotalSteps - Settings.StepsBeforeToday;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
MainActivity.cs
[Activity(Label = "My Pedometer", Icon = "#mipmap/icon", Theme = "#style/MainTheme", LaunchMode = LaunchMode.SingleTask, MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public bool IsBound { get; set; }
private StepServiceBinder binder;
private bool registered;
private Handler handler;
private bool firstRun = true;
private StepServiceConnection serviceConnection;
public StepServiceBinder Binder
{
get { return binder; }
set
{
binder = value;
if (binder == null)
return;
HandlePropertyChanged(null, new System.ComponentModel.PropertyChangedEventArgs("StepsToday"));
if (registered)
binder.StepService.PropertyChanged -= HandlePropertyChanged;
binder.StepService.PropertyChanged += HandlePropertyChanged;
registered = true;
}
}
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Forms.Forms.Init(this, savedInstanceState);
StartStepService();
handler = new Handler();
handler.PostDelayed(() => UpdateUI(), 500);
LoadApplication(new App());
}
private void StartStepService()
{
try
{
var service = new Intent(this, typeof(StepService));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
StartForegroundService(service);
}
else
{
StartService(service);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception {0}.", ex.Message);
}
}
protected override void OnStop()
{
base.OnStop();
if (IsBound)
{
UnbindService(serviceConnection);
IsBound = false;
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if (IsBound)
{
UnbindService(serviceConnection);
IsBound = false;
}
}
protected override void OnStart()
{
base.OnStart();
if (!firstRun)
StartStepService();
if (IsBound)
return;
var serviceIntent = new Intent(this, typeof(StepService));
serviceConnection = new StepServiceConnection(this);
BindService(serviceIntent, serviceConnection, Bind.AutoCreate);
}
protected override void OnPause()
{
base.OnPause();
if (registered && binder != null)
{
binder.StepService.PropertyChanged -= HandlePropertyChanged;
registered = false;
}
}
protected override void OnResume()
{
base.OnResume();
if (!firstRun)
{
if (handler == null)
handler = new Handler();
handler.PostDelayed(() => UpdateUI(), 500);
}
firstRun = false;
if (!registered && binder != null)
{
binder.StepService.PropertyChanged += HandlePropertyChanged;
registered = true;
}
}
void HandlePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName != "StepsToday")
return;
UpdateUI();
}
private void UpdateUI()
{
RunOnUiThread(() =>
{
long steps = 0;
var showWaring = false;
if (Binder == null)
{
if (Utils.IsSameDay)
steps = Settings.CurrentDaySteps;
}
else
{
steps = Binder.StepService.StepsToday;
showWaring = binder.StepService.WarningState;
}
Settings.CurrentDaySteps = steps;
});
}
}

How can i integrate QR-reader in Weex App?

React.Native has plugins like react-native-qrcode-scanner.
How can I do that on Weex?
Here comes a solution named EMAS. like weex-market, there are a lot of components and modules. One of these is the scan component which meets your requirement.
But the portal website is only in the Chinese language now.
Here is an android demo using ZXing to do qrcode. Copy this and register as a scan component. Have a look at this Demo.
public class WXQRCodeScannerComponent extends WXComponent<ZXingScannerView> implements ZXingScannerView.ResultHandler{
private static final String VF_WIDTH = "vfWidth";
private static final String VF_HEIGHT = "vfHeight";
private static final String VF_TOP_MARGIN = "vfTopMargin";
private static final String AUTO_STOP = "autoStop";
private static final String ON_SCAN = "scan";
private static final String TAG = "scan";
private boolean isAutoStop = false;
private boolean hasScanned = false;
private Handler mHandler = new Handler(Looper.getMainLooper());
private static final int CAMERA_PERMISSION_REQUEST_CODE = 0x1001;
private OnRequestPermissionCallback mPermissionCallback = new OnRequestPermissionCallback() {
#Override
public void onPermissionGranted() {
ZXingScannerView hostView = getHostView();
if(hostView != null) {
hostView.startCamera();
}
}
#Override
public void onPermissionDenied() {
// nope
}
};
public WXQRCodeScannerComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {
super(instance, dom, parent);
}
public WXQRCodeScannerComponent(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, int type) {
super(instance, dom, parent, type);
}
#Override
protected ZXingScannerView initComponentHostView(#NonNull Context context) {
requestPermissionIfNeeded();
ZXingScannerView qrCodeView = new ZXingScannerView(context);
qrCodeView.setSquareViewFinder(true);
qrCodeView.setResultHandler(this); // Register ourselves as a handler for scan results.
return qrCodeView;
}
private void requestPermissionIfNeeded() {
Context c = getContext();
if(c != null && c instanceof Activity) {
if(ContextCompat.checkSelfPermission(c, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) c, Manifest.permission.CAMERA)) {
Toast.makeText(c, "请授予相机权限以用于扫码", Toast.LENGTH_LONG).show();
}
LocalBroadcastManager.getInstance(c)
.registerReceiver(new InnerReceiver(mPermissionCallback), new IntentFilter(WXModule.ACTION_REQUEST_PERMISSIONS_RESULT));
ActivityCompat.requestPermissions((Activity) c,
new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
} else {
//Nope
}
}
}
static class InnerReceiver extends BroadcastReceiver{
private OnRequestPermissionCallback mCallback;
InnerReceiver(OnRequestPermissionCallback callback) {
this.mCallback = callback;
}
#Override
public void onReceive(Context context, Intent intent) {
int code = intent.getIntExtra(WXModule.REQUEST_CODE, 0);
int[] grantResults = intent.getIntArrayExtra(WXModule.GRANT_RESULTS);
String[] permissions = intent.getStringArrayExtra(WXModule.PERMISSIONS);
if(code == CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限申请成功
if(mCallback != null) {
mCallback.onPermissionGranted();
}
} else {
Toast.makeText(context, "相机权限申请失败!将无法使用扫码功能!", Toast.LENGTH_SHORT).show();
if(mCallback != null) {
mCallback.onPermissionDenied();
}
}
}
LocalBroadcastManager.getInstance(context).unregisterReceiver(this);
}
}
interface OnRequestPermissionCallback {
void onPermissionGranted();
void onPermissionDenied();
}
#Override
protected boolean setProperty(String key, Object param) {
switch (key) {
case VF_WIDTH:
Float width = WXUtils.getFloat(param,null);
if(width != null) {
setVfWidth(width);
}
return true;
case VF_HEIGHT:
Float height = WXUtils.getFloat(param,null);
if(height != null) {
setVfHeight(height);
}
return true;
case VF_TOP_MARGIN:
Float topMargin = WXUtils.getFloat(param,null);
if(topMargin != null) {
setVfTopMargin(topMargin);
}
return true;
case AUTO_STOP:
Boolean autoStop = WXUtils.getBoolean(param, false);
if(autoStop != null) {
setAutoStop(autoStop);
}
return true;
}
return super.setProperty(key, param);
}
#Override
protected void onHostViewInitialized(ZXingScannerView host) {
super.onHostViewInitialized(host);
ZXingScannerView hostView = getHostView();
if(hostView != null) {
hostView.startCamera();
}
}
#WXComponentProp(name = VF_WIDTH)
public void setVfWidth(float width) {
float finalWidth = WXViewUtils.getRealSubPxByWidth(width,getInstance().getInstanceViewPortWidth());
if(getHostView() != null) {
// ScanBoxView scanBoxView = getHostView().getScanBox();
// if(scanBoxView != null) {
// scanBoxView.setRectWidth((int) finalWidth);
// }
}
}
#WXComponentProp(name = VF_HEIGHT)
public void setVfHeight(float height) {
float finalHeight = WXViewUtils.getRealSubPxByWidth(height,getInstance().getInstanceViewPortWidth());
if(getHostView() != null) {
// ScanBoxView scanBoxView = getHostView().getScanBox();
// if(scanBoxView != null) {
// scanBoxView.setRectHeight((int) finalHeight);
// }
}
}
#WXComponentProp(name = VF_TOP_MARGIN)
public void setVfTopMargin(float topMargin) {
float finalTopMargin = WXViewUtils.getRealSubPxByWidth(topMargin,getInstance().getInstanceViewPortWidth());
if(getHostView() != null) {
// ScanBoxView scanBoxView = getHostView().getScanBox();
// if(scanBoxView != null) {
// scanBoxView.setTopOffset((int) finalTopMargin);
// }
}
}
#WXComponentProp(name = AUTO_STOP)
public void setAutoStop(boolean autoStop) {
this.isAutoStop = autoStop;
}
#Override
public void onActivityResume() {
super.onActivityResume();
ZXingScannerView hostView = getHostView();
if(hostView != null) {
hostView.startCamera();
}
}
#Override
public void onActivityPause() {
super.onActivityPause();
ZXingScannerView hostView = getHostView();
if(hostView != null) {
hostView.stopCamera(); // Stop camera on pause
}
}
#Override
public void onActivityDestroy() {
if(mHandler != null) {
ZXingScannerView hostView = getHostView();
if(hostView != null) {
hostView.stopCamera();
}
mHandler.removeCallbacksAndMessages(null);
}
}
#Override
public void handleResult(Result result) {
if(isAutoStop && hasScanned) {
resumeCameraPreviewDelayed();
return;
}
fireEventByResult(result);
resumeCameraPreviewDelayed();
hasScanned = true;
}
private void fireEventByResult(Result result) {
if(result == null || TextUtils.isEmpty(result.getText())) {
Map<String,Object> callback = new HashMap<>(4);
callback.put("result","failed");
fireEvent(ON_SCAN,callback);
if(WXEnvironment.isApkDebugable()) {
WXLogUtils.d(TAG, "scan failed");
}
} else {
Map<String,String> data = new HashMap<>(4);
data.put("timestamp", System.currentTimeMillis()+"");
data.put("code", result.getText());
Map<String,Object> callback = new HashMap<>(4);
callback.put("result","success");
callback.put("data", data);
fireEvent(ON_SCAN,callback);
if(WXEnvironment.isApkDebugable()) {
WXLogUtils.d(TAG, "scan success: " + result.getText());
}
}
}
private void resumeCameraPreviewDelayed() {
if(mHandler == null) {
return;
}
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
ZXingScannerView hostView = getHostView();
if(hostView != null) {
hostView.resumeCameraPreview(WXQRCodeScannerComponent.this);
}
}
}, 1000);
}
}

Resources