React Native: 'android.bluetooth.bluetoothadapter.isEnabled()' on a null reference - reactjs

I am working on a React-Native app that relies on Bluetooth for some of its functionality and as far as I understand, Android Studio's emulator does not support Bluetooth. The package I am using is react-native-eddystone which is used to work with Bluetooth low energy devices. When I start the app on my phone it prompts me to allow the usage of Bluetooth and works fine but when I use the emulator it crashes from the start. Here is the AndroidManifets.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
</manifest>
And here is a screenshot of the error:
Edit: The error occurs here in EddystoneModule.java:
#ReactMethod
public void startScanning() {
ScanFilter serviceFilter = new ScanFilter.Builder().setServiceUuid(SERVICE_UUID).build();
ScanFilter configurationFilter = new ScanFilter.Builder().setServiceUuid(CONFIGURATION_UUID).build();
final List<ScanFilter> filters = new ArrayList<>();
filters.add(serviceFilter);
filters.add(configurationFilter);
ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
if (!bluetoothAdapter.isEnabled()) { // <--- here bluethoothAdapter is null
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
getCurrentActivity().startActivityForResult(enableBtIntent, 8123);
}
// start scanning
scanner = bluetoothAdapter.getBluetoothLeScanner();
scanner.startScan(filters, settings, scanCallback);
}

Related

Easy way to implement splash screen in React Native application

I am new to React-Native development. I try to implement a splash screen in my app. I tried a lot of options from the web but not get success because some of the code is outdated and some process is very confusing.
Use react-native-splash-screen Sample code is below
import SplashScreen from 'react-native-splash-screen'
export default class WelcomePage extends Component {
componentDidMount() {
// do stuff while splash screen is shown
// After having done stuff (such as async tasks) hide the splash screen
SplashScreen.hide();
}
}
To learn more see examples
To make full screen
On MainActivity.java, just like that:
#Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this, R.style.SplashTheme); // Add theme here
super.onCreate(savedInstanceState);
}
IN res/values/styles.xml
<resources>
<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>
</resources>
launch_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="#drawable/launch_screen" android:scaleType="centerCrop" />
</RelativeLayout>
I recommend react-native-bootsplash since it's still actively maintained.
Before implementing any library that asks you to add code to the Swift and Java bridge files it's a good idea to familiarize yourself with the RN folder structure. Once you understand the folder structure and some of the main files it becomes much easier to debug your app and you will be able to develop apps faster.

Why cannot write log to files when WPF application publishing as a single file

I use Microsoft.Extensions.Hosting and NLog.Web.AspNetCore in WPF. The application run correctly with Debug and Release mode, But when I publish the app as a single file, I found File target does not work when fileName using relative path.
NLog version: 4.6.8
Platform: .NET Core 3
NLog config
<nlog>
<targets>
<default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>
<target xsi:type="File" name="file" fileName="logs/${level}-${shortdate}.log" encoding="utf-8"
layout="${longdate}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="file" final="true"/>
</rules>
</nlog>
I use AddNLog to apply this configuration:
public App()
{
_host = new HostBuilder()
.ConfigureLogging(logBuilder =>
{
logBuilder.ClearProviders()
.SetMinimumLevel(LogLevel.Debug)
.AddNLog("NLog.config");
})
.ConfigureServices((hostContext, services) =>
{
//...
}).Build();
}
Show the MainWindow when application startup:
private void Application_Startup(object sender, StartupEventArgs e)
{
using var serviceScope = _host.Services.CreateScope();
var serviceProvider = serviceScope.ServiceProvider;
_logger = serviceProvider.GetRequiredService<ILogger<App>>();
SetupExceptionHandling();
MainWindow mainWindow = serviceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
_logger.LogInformation($"Application startup at {DateTime.Now} successfully");
}
Publishing as a single file and run it, the log of successful startup is not written to the file, But when i change fileName to an absolute path like /logs/${level}-${shortdate}.log or ${level}-${shortdate}.log, the log can be written.
I try to configure it in code:
var config = new LoggingConfiguration();
var file = new FileTarget("file")
{
FileName = "logs/${shortdate}-${level}.log",
Layout = "${longdate}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}"
};
config.AddRule(LogLevel.Info, LogLevel.Fatal, new BufferingTargetWrapper(file));
return config;
But the result is still the same.
Am I writing something wrong? thanks for your help.
NLog will automatically prefix relative fileName-path with the ${basedir}-layout. See also https://github.com/nlog/nlog/wiki/Basedir-Layout-Renderer
Sadly enough Microsoft decided not to fix AppDomain.BaseDirectory when doing Single File Publish in NetCore 3.1
https://github.com/dotnet/aspnetcore/issues/12621
https://github.com/dotnet/core-setup/issues/7491
The work-around is to explictly specify ${basedir:fixTempDir=true}:
<nlog>
<targets>
<default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>
<target xsi:type="File" name="file" fileName="${basedir:fixtempdir=true}/logs/${level}-${shortdate}.log" encoding="utf-8"
layout="${longdate}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="file" final="true"/>
</rules>
</nlog>
Hopefully Microsoft will fix the illusion with NetCore5

Codenameone: AppArg is null on Android Device

I set the recommended build-hints for my Codenameone app to be called from other apps as a share target. But the AppArg in my App is always null on android (8.0.0) when calling my App as a share-target from within another App.
I used this build-hints:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
<data android:mimeType="application/octet-stream" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
<data android:mimeType="application/octet-stream" />
</intent-filter>
The app can be selected as a share target on my HUAWEI P-Smart with Android 8.0.0 (and within the android simulator from android studio with Android 8.0.0) - but the parameter send to my app cannot be fetched:
disp.getProperty("AppArg", null);
returns always null. Regardless if I select a text in the browser and share this text with my app - or if I share a text-file with my App.
In the log of Android Studio I can see, that a selected text is passed to the app:
2020-03-20 10:57:50.031 1655-2542/? I/ActivityManager: START u0 {act=android.intent.action.SEND typ=text/plain flg=0xb080001 cmp=de.zeitkuenstlervoll.gtd.gui/.AppStartStub clip={text/plain T:Erkrankung} (has extras)} from uid 10052
The text I sent is here: clip={text/plain T:Erkrankung}
I also set the build hint
android.activity.launchMode = singleTask
Do you have any idea what the reason could be? (By the way: The AppArg ist not null on my iOS-Devices)

Writing assembly version on splash screen

I followed Kent Boogaart's excellent article on how to add dynamic content to the splash screen. Things work in the sense that I can see version number on the splash screen now. The problem however is that the article uses $(Version) property, which in my case is 1.0.0.0.
I am using shared AssemblyInfo.vb and need to get next major/minor/build/revision numbers from this file to draw them on the splash screen. The shared AssemblyInfo file contains a version number like 2.5.*. I need the actual number that will be generated by MSBuild (2.5.abc.xyz).
I thought about using Reflection inside the UsingTask to get version number from the assembly, but since this task is run before the build process, the assembly doesn't yet have the version number that will be generated in the following build. Moreover the assembly simply may not exist (e.g. a Clean command before build) at that point.
I installed MSBuild Community Tasks but cannot see anything except SvnVersion task.
Can someone help me with sending the to-be-generated version number to my UsingTask?
Finally! For anyone else trying to do the same, here are the steps, assuming that you're using shared AssemblyInfo that resides in solution directory (it can work for default AssemblyInfo too, but you'll need to adjust paths and filenames accordingly):
Download and install MSBuild Community Tasks on your machine.
Add a targets file (a simple XML file with .targets extension) to your project.
Add UsingTask presented in Kent Boogaart's article I linked in the question to this file. This will perform actual version writing on the splash image.
Use <Version>, <FileUpdate> and <AddTextToImage> tasks (first two are available in MSBuild, third one is from the UsingTask we added in step 3) to write new version number to your shared AssemblyInfo file and splash image.
The final .targets file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="AddTextToImage" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<InputPath ParameterType="System.String" Required="true" />
<OutputPath ParameterType="System.String" Required="true" />
<TopMiddlePoint ParameterType="System.String" Required="true" />
<Text1 ParameterType="System.String" Required="true" />
<Text2 ParameterType="System.String" Required="false" />
<Text3 ParameterType="System.String" Required="false" />
</ParameterGroup>
<Task>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Xaml" />
<Using Namespace="System" />
<Using Namespace="System.Globalization" />
<Using Namespace="System.IO" />
<Using Namespace="System.Windows" />
<Using Namespace="System.Windows.Media" />
<Using Namespace="System.Windows.Media.Imaging" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var originalImageSource = BitmapFrame.Create(new Uri(InputPath));
var visual = new DrawingVisual();
using (var drawingContext = visual.RenderOpen())
{
drawingContext.DrawImage(originalImageSource, new Rect(0, 0, originalImageSource.PixelWidth, originalImageSource.PixelHeight));
var typeFace = new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal);
var formattedText = new FormattedText(Text1, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, 18, Brushes.Red);
var topMiddlePoint = Point.Parse(TopMiddlePoint);
var point = new Point(topMiddlePoint.X - (formattedText.Width / 2), topMiddlePoint.Y);
drawingContext.DrawText(formattedText, point);
if(!string.IsNullOrEmpty(Text2))
{
formattedText = new FormattedText(Text2, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, 18, Brushes.Red);
topMiddlePoint.Y += formattedText.Height + 5;
point = new Point(topMiddlePoint.X - (formattedText.Width / 2), topMiddlePoint.Y);
drawingContext.DrawText(formattedText, point);
}
if(!string.IsNullOrEmpty(Text3))
{
formattedText = new FormattedText(Text3, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, 18, Brushes.Red);
topMiddlePoint.Y += formattedText.Height + 5;
point = new Point(topMiddlePoint.X - (formattedText.Width / 2), topMiddlePoint.Y);
drawingContext.DrawText(formattedText, point);
}
drawingContext.Close();
}
var renderTargetBitmap = new RenderTargetBitmap(originalImageSource.PixelWidth, originalImageSource.PixelHeight, originalImageSource.DpiX, originalImageSource.DpiY, PixelFormats.Pbgra32);
renderTargetBitmap.Render(visual);
var bitmapFrame = BitmapFrame.Create(renderTargetBitmap);
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(bitmapFrame);
using (var stream = File.OpenWrite(OutputPath))
{
encoder.Save(stream);
stream.Close();
}
]]>
</Code>
</Task>
</UsingTask>
<PropertyGroup>
<MajorVersion>2</MajorVersion>
<MinorVersion>5</MinorVersion>
</PropertyGroup>
<Target Name="BeforeBuild">
<Version BuildType="Automatic" RevisionType="Automatic" Major="$(MajorVersion)" Minor="$(MinorVersion)">
<Output TaskParameter="Major" PropertyName="Major" />
<Output TaskParameter="Minor" PropertyName="Minor" />
<Output TaskParameter="Build" PropertyName="Build" />
<Output TaskParameter="Revision" PropertyName="Revision" />
</Version>
<FileUpdate Files="$(SolutionDir)SharedAssemblyInfo.vb"
Regex="Assembly: AssemblyVersion\("\d+\.\d+((\.\*)|(\.\d+\.\d+))?"\)"
ReplacementText="Assembly: AssemblyVersion("$(Major).$(Minor).$(Build).$(Revision)")" />
<FileUpdate Files="$(SolutionDir)SharedAssemblyInfo.vb"
Regex="Assembly: AssemblyFileVersion\("\d+\.\d+((\.\*)|(\.\d+\.\d+))?"\)"
ReplacementText="Assembly: AssemblyFileVersion("$(Major).$(Minor).$(Build).$(Revision)")" />
<SvnVersion LocalPath=".">
<Output TaskParameter="Revision" PropertyName="SvnRevision" />
</SvnVersion>
<AddTextToImage InputPath="$(ProjectDir)Resources\Splash.png"
OutputPath="$(ProjectDir)Resources\SplashWithVersion.png"
TopMiddlePoint="250,150"
Text1="$(Major).$(Minor).$(Build).$(Revision)"
Text2="SVN Version: $(SvnRevision)" />
<Message Text="Updated version number on splash screen to: $(Major).$(Minor).$(Build).$(Revision)" Importance="high"/>
</Target>
</Project>
This will update your AssemblyInfo and the output image. Note that you must mark your output image as SplashScreen (as Build Action) in Visual Studio. Also note that I'm writing both assembly version as well as SVN Revision number on the splash screen. You may want to adjust yours according to your needs.

write log to file instead of console in postsharp

I know this question may be ridiculous but I could not find the answer. The Post sharp writes the logs in console by System.Diagnostics but I need to write the logs in a separate file. Is there any way to do so?
Thanks in advance
I found also I can do this in the app.config as the following:
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\\log.txt" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
You need to use System.Diagnostics.Trace.Listeners property to register your own listener. You would need code like this in your app's entry point:
using (StreamWriter sw = new StreamWriter("file.txt"))
using (TextWriterTraceListener tl = new TextWriterTraceListener(sw))
{
Trace.Listeners.Add(tl);
try
{
// execute your program here
}
finally
{
Trace.Listeners.Remove(tl);
}
}

Resources