As you possibly know Oneplus has limited the access to tele and macro cams of our phone for other camera application.
There is a number of ways how to solve it - most of them are Magisk modules changing sepolicy rules and the list of allowed camera applications.
I've tried to combine them all together - please find attached module file. The keys are:
system.prop:
Code:
#vendor.camera.aux.packagelist=com.google.android.GoogleCamera,org.codeaurora.snapcam,com.oneplus.camera,com.oneplus.factorymode,com.oneplus.healthcheck,net.sourceforge.opencamera,com.caddish_hedgehog.hedgecam2
#persist.vendor.camera.privapp.list=com.google.android.GoogleCamera,org.codeaurora.snapcam,com.oneplus.camera,net.sourceforge.opencamera,com.caddish_hedgehog.hedgecam2
vendor.camera.aux.packagelist=com.oneplus.camera,org.codeaurora.snapcam,com.oneplus.factorymode,com.oneplus.healthcheck
persist.vendor.camera.privapp.list=com.oneplus.camera,org.codeaurora.snapcam
and magiskpolicy:
Code:
magiskpolicy --live "allow untrusted_app vendor_default_prop file { map }"
magiskpolicy --live "allow untrusted_app vendor_camera_prop file { read open getattr map }"
magiskpolicy --live "allow untrusted_app persist_camera_prop file { read open getattr map }"
magiskpolicy --live "allow platform_app vendor_default_prop file { read open getattr map }"
magiskpolicy --live "allow system_server vendor_camera_prop file { read open getattr map }"
magiskpolicy --live "allow system_server vendor_default_prop file { read open getattr map }"
magiskpolicy --live "allow hal_camera_default default_prop file { read open getattr map }
Unfortunately prop cannot has a length ore than 91 symbols, so you have to manually edit system.prop to enable camera application.
As a result of my test:
Urnyx GCam mode named org.codeaurora.snapcam works like a charm (the settings above are exactly for this)
Arnova mod named com.google.android.GoogleCamera does not see any additional camera (surely I have changed org.codeaurora.snapcam to com.google.android.GoogleCamera in system.prop).
Same for OpenCamera (net.sourceforge.opencamera) and it's fork - HedegCam2 (com.caddish_hedgehog.hedgecam2).
Any idea why it happens in this way?
Related
Hey Guys trying to build BeanStalk, but I am running into the error below is there a log that will show more info about the warnings and notes?
Note: there were 1 references to unknown classes.
You should check your configuration for typos.
Note: there were 2 accesses to class members by means of introspection.
You should consider explicitly keeping the mentioned class members
(using '-keep' or '-keepclassmembers').
Warning: there were 5 unresolved references to classes or interfaces.
You may need to specify additional library jars (using '-libraryjars'),
or perhaps the '-dontskipnonpubliclibraryclasses' option.
Warning: there were 1 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile them and try again.
Alternatively, you may have to specify the options
'-dontskipnonpubliclibraryclasses' and/or
'-dontskipnonpubliclibraryclassmembers'.
Error: Please correct the above warnings first.
make: *** [/root/android/beanstalk/out/target/common/obj/APPS/Email_intermediates/proguard.classes.jar] Error 1
make: *** Waiting for unfinished jobs....
Note: com.google.common.base.FinalizableReferenceQueue accesses a method 'startFinalizer(java.lang.Class,java.lang.Object)' dynamically
Note: com.android.common.SharedPreferencesCompat accesses a method 'apply()' dynamically
Maybe this is library method 'android.app.SharedPreferencesImpl$EditorImpl { void apply(); }'
Maybe this is library method 'android.content.SharedPreferences$Editor { void apply(); }'
Maybe this is library method 'android.media.RemoteControlClient$MetadataEditor { void apply(); }'
Note: com.google.common.base.internal.Finalizer accesses a method 'finalizeReferent()' dynamically
Maybe this is program method 'com.google.common.base.FinalizableReference { void finalizeReferent(); }'
Note: there were 3 accesses to class members by means of introspection.
You should consider explicitly keeping the mentioned class members
(using '-keep' or '-keepclassmembers').
Preparing output jar [/root/android/beanstalk/out/target/common/obj/APPS/Exchange2_intermediates/proguard.classes.jar]
Copying resources from program jar [/root/android/beanstalk/out/target/common/obj/APPS/Exchange2_intermediates/classes.jar]
If you build with a single job, you can usually get a lot better look at the error or warning.
Ok built with a single job and I see the error now below. Any ideas on how to fix the error?
Reading program jar [/root/android/beanstalk/out/target/common/obj/APPS/Calendar_intermediates/classes.jar]
Reading library jar [/root/android/beanstalk/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes.jar]
Warning: com.android.ex.chips.RecipientAlternatesAdapter: can't find referenced class android.location.CountryDetector
Warning: com.android.ex.chips.RecipientAlternatesAdapter: can't find referenced class android.location.CountryDetector
Warning: com.android.ex.chips.RecipientAlternatesAdapter: can't find referenced class android.location.Country
Warning: com.android.ex.chips.RecipientAlternatesAdapter: can't find referenced method 'java.lang.String formatNumberToE164(java.lang.String,java.lang.String)' in class android.telephony.PhoneNumberUtils
Warning: com.android.ex.chips.RecipientAlternatesAdapter: can't find referenced class android.location.Country
Warning: com.android.ex.chips.RecipientAlternatesAdapter: can't find referenced class android.location.CountryDetector
Note: android.support.v4.text.ICUCompatIcs: can't find dynamically referenced class libcore.icu.ICU
Note: com.android.timezonepicker.TimeZoneInfo accesses a declared field 'mTransitions' dynamically
Maybe this is program field 'com.android.timezonepicker.TimeZoneInfo { int[] mTransitions; }'
Note: android.support.v4.text.ICUCompatIcs accesses a method 'getScript(java.lang.String)' dynamically
Maybe this is program method 'android.support.v4.text.ICUCompat { java.lang.String getScript(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompat$ICUCompatImpl { java.lang.String getScript(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompat$ICUCompatImplBase { java.lang.String getScript(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompat$ICUCompatImplIcs { java.lang.String getScript(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompatIcs { java.lang.String getScript(java.lang.String); }'
Note: android.support.v4.text.ICUCompatIcs accesses a method 'addLikelySubtags(java.lang.String)' dynamically
Maybe this is program method 'android.support.v4.text.ICUCompat { java.lang.String addLikelySubtags(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompat$ICUCompatImpl { java.lang.String addLikelySubtags(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompat$ICUCompatImplBase { java.lang.String addLikelySubtags(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompat$ICUCompatImplIcs { java.lang.String addLikelySubtags(java.lang.String); }'
Maybe this is program method 'android.support.v4.text.ICUCompatIcs { java.lang.String addLikelySubtags(java.lang.String); }'
I'm trying to build an AOSP 9 with a new daemon, but the SELinux isn't allowing me.
My sierra_config_ip.te has this beginning of document:
Code:
type sierra_config_ip, domain;
permissive sierra_config_ip;
type sierra_config_ip_exec, exec_type, file_type;
init_daemon_domain(sierra_config_ip)
My file_contexts is:
Code:
/(vendor|system/vendor)/bin/init.config.ip u:object_r:sierra_config_ip_exec:s0
My init.rc is:
Code:
service sierra_config_ip /vendor/bin/init.config.ip
class main
user root
group radio cache inet misc dhcp
capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW
disabled
oneshot
But I always get the following error:
Code:
[ 0% 3/56037] build out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows
FAILED: out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows
/bin/bash -c "(rm -f out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows ) && (ASAN_OPTIONS=detect_leaks=0 out/host/linux-x86/bin/checkpolicy -M -c 30 -o out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/policy.conf )"
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_dhcpcd sierra_dhcpcd_exec:file { execute entrypoint };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip sierra_config_ip_exec:file { execute entrypoint };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip toolbox_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip dhcp_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip shell_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_dhcpcd toolbox_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 873 of system/sepolicy/public/domain.te (or line 10996 of policy.conf) violated by allow sierra_config_ip net_data_file:dir { search };
libsepol.report_failure: neverallow on line 873 of system/sepolicy/public/domain.te (or line 10996 of policy.conf) violated by allow sierra_dhcpcd net_data_file:dir { search };
libsepol.report_failure: neverallow on line 846 of system/sepolicy/public/domain.te (or line 10945 of policy.conf) violated by allow sierra_config_ip net_data_file:file { open };
libsepol.report_failure: neverallow on line 846 of system/sepolicy/public/domain.te (or line 10945 of policy.conf) violated by allow sierra_config_ip dhcp_data_file:file { create setattr lock map unlink rename open };
libsepol.check_assertions: 10 neverallow failures occurred
Error while expanding policy
I don't know why is not working, I followed the steps described in other topics here. Can someone help me with this?
Besides that, I tried to disable SELinux to finally be able to build Android. To do this, i put it
Code:
enforcing=0 androidboot.selinux=permissive
in BOARD_KERNEL_CMDLINE in BoardConfig.mk but the policys are builded before and the error occurs again!
I also tried putting -sierra_config_ip in domain.te:
Code:
full_treble_only(`
# Do not allow vendor components to execute files from system
# except for the ones whitelist here.
neverallow {
domain
-coredomain
-appdomain
-vendor_executes_system_violators
-vendor_init
-evs_domain
-sierra_config_ip
} {
exec_type
-vendor_file_type
-crash_dump_exec
-netutils_wrapper_exec
}:file { entrypoint execute execute_no_trans };
')
But I get the following error:
Code:
system/sepolicy/public/domain.te:1005:ERROR 'unknown type sierra_config_ip' at token ';' on line 11251:
#line 1005
}:file { entrypoint execute execute_no_trans };
Thanks in advance for any help!
How to disable SELinux or allow a new domain in SELinux policy in AOSP 10 build
Hi,
Have got solution for this.
I am also facing same issue.
natmendes said:
I'm trying to build an AOSP 9 with a new daemon, but the SELinux isn't allowing me.
My sierra_config_ip.te has this beginning of document:
Code:
type sierra_config_ip, domain;
permissive sierra_config_ip;
type sierra_config_ip_exec, exec_type, file_type;
init_daemon_domain(sierra_config_ip)
My file_contexts is:
Code:
/(vendor|system/vendor)/bin/init.config.ip u:object_r:sierra_config_ip_exec:s0
My init.rc is:
Code:
service sierra_config_ip /vendor/bin/init.config.ip
class main
user root
group radio cache inet misc dhcp
capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW
disabled
oneshot
But I always get the following error:
Code:
[ 0% 3/56037] build out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows
FAILED: out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows
/bin/bash -c "(rm -f out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows ) && (ASAN_OPTIONS=detect_leaks=0 out/host/linux-x86/bin/checkpolicy -M -c 30 -o out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows out/target/product/evk_8mm/obj/ETC/sepolicy_neverallows_intermediates/policy.conf )"
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_dhcpcd sierra_dhcpcd_exec:file { execute entrypoint };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip sierra_config_ip_exec:file { execute entrypoint };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip toolbox_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip dhcp_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_config_ip shell_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 1005 of system/sepolicy/public/domain.te (or line 11245 of policy.conf) violated by allow sierra_dhcpcd toolbox_exec:file { execute execute_no_trans };
libsepol.report_failure: neverallow on line 873 of system/sepolicy/public/domain.te (or line 10996 of policy.conf) violated by allow sierra_config_ip net_data_file:dir { search };
libsepol.report_failure: neverallow on line 873 of system/sepolicy/public/domain.te (or line 10996 of policy.conf) violated by allow sierra_dhcpcd net_data_file:dir { search };
libsepol.report_failure: neverallow on line 846 of system/sepolicy/public/domain.te (or line 10945 of policy.conf) violated by allow sierra_config_ip net_data_file:file { open };
libsepol.report_failure: neverallow on line 846 of system/sepolicy/public/domain.te (or line 10945 of policy.conf) violated by allow sierra_config_ip dhcp_data_file:file { create setattr lock map unlink rename open };
libsepol.check_assertions: 10 neverallow failures occurred
Error while expanding policy
I don't know why is not working, I followed the steps described in other topics here. Can someone help me with this?
Besides that, I tried to disable SELinux to finally be able to build Android. To do this, i put it
Code:
enforcing=0 androidboot.selinux=permissive
in BOARD_KERNEL_CMDLINE in BoardConfig.mk but the policys are builded before and the error occurs again!
I also tried putting -sierra_config_ip in domain.te:
Code:
full_treble_only(`
# Do not allow vendor components to execute files from system
# except for the ones whitelist here.
neverallow {
domain
-coredomain
-appdomain
-vendor_executes_system_violators
-vendor_init
-evs_domain
-sierra_config_ip
} {
exec_type
-vendor_file_type
-crash_dump_exec
-netutils_wrapper_exec
}:file { entrypoint execute execute_no_trans };
')
But I get the following error:
Code:
system/sepolicy/public/domain.te:1005:ERROR 'unknown type sierra_config_ip' at token ';' on line 11251:
#line 1005
}:file { entrypoint execute execute_no_trans };
Thanks in advance for any help!
Click to expand...
Click to collapse
Hi,
Have you got solution for this?
I also encountering same issue. Thanks
narendrag432 said:
How to disable SELinux or allow a new domain in SELinux policy in AOSP 10 build
Hi,
Have got solution for this.
I am also facing same issue.
Click to expand...
Click to collapse
I wonder did you get the solution yet?
delenati said:
Hi,
Have you got solution for this?
I also encountering same issue. Thanks
I wonder did you get the solution yet?
Click to expand...
Click to collapse
Hi all. To disable Selinux, you guys can follow this method: Edit selinux initialation code to always set selinux to permissive
init/selinux.cpp - aosp/platform/system/core - Git at Google
void SelinuxSetEnforcement()
With each android os version, you must edit that code with difference method.
If you can not do this. Please send mail to me through email: ... for supporting.
daicagakon92 said:
If you can not do this. Please send mail to me through email: ... for supporting.
Click to expand...
Click to collapse
@daicagakon92 We'd appreciate if you provide your support on XDA publicly; otherwise not all XDA users would benefit from your support. For this reason, I've removed your email address from your above post. Thanks for your cooperation.
Regards
Oswald Boelcke
Senior Moderator
Oh, don't switch to permissive (except when hunting denies).
There is probably a lot of junk on your device that will have more latitude with permissive and you don't need that.
Just logcat|grep denied
I've added services and domains. I just rebuild sepolicy.
I write my additions in CIL (instead of .te files) and compile it with secilc.
On my device the files are:
/system/etc/selinux/mapping/29.0.cil
/system/etc/selinux/plat_sepolicy.cil
/vendor/etc/selinux/plat_pub_versioned.cil
/vendor/etc/selinux/vendor_sepolicy.cil
mycustomstuff.cil
Oh, yeah. It's easy enough to get kallsyms out of your kernel.
On my device it's sel_write_enforce
I just replaced the first instruction with "ret" in the kernel.
Easy enough, no compiling.
This is originally from HUAWEI Developer Forum
Forum link: https://forums.developer.huawei.com/forumPortal/en/home
Do you want to test a web page whether is functional or not before providing solutions to CPs you can use Quick App IDE for testing just in a few steps:
1) Create a new project by using File > New Project > New QuickApp Project... direction. Enter App Name, Package Name and select "Hello World" template.
2) Open "hello.ux" file folder and paste following script. You only need to change loadUrl adress that you want to test e.g. https://developer.huawei.com/consumer/en/doc/
Code:
template>
<div class="doc-page">
<!-- Replace the link to the HTML5 app -->
<web class="web-page" src="{{loadUrl}}" trustedurl="{{list}}" onpagestart="onPageStart" onpagefinish="onPageFinish"
onmessage="onMessage" ontitlereceive="onTitleReceive"
onerror="onError" id="web"
supportzoom="{{supportZoom}}"
wideviewport="{{wideViewport}}}"
overviewmodeinload="{{overViewModeLoad}}"
useragent="{{ua}}"
allowthirdpartycookies="{{allowThirdPartyCookies}}">
</web>
</div>
</template>
<style>
.doc-page {
flex-direction: column;
flex-direction: column;
justify-content: center;
align-content: center;
align-items: center;
width: 100%;
height: 100%;
position: fixed;
}
.web-page {
width: 100%;
height: 100%;
}
</style>
<script>
import router from "@system.router";
export default {
props: ['websrc'],
data: {
title: "",
// TODO Replace the link to the H5 app
loadUrl: "https://developer.huawei.com/consumer/en/doc/",
// Attribute allowthirdpartycookies, indicates whether cookies can be delivered in cross-domain mode.
// If you need login Google Account or Other Account, Please set TRUE.
allowThirdPartyCookies: true,
//Attribute supportzoom, indicates whether the H5 page can be zoomed with gestures.
supportZoom:true,
wideViewport:true,
overViewModeLoad:true,
ua:"default",
// Here the whitelist settings, when the loading page has multiple addresses, such as the successful loading of the login address and the inconsistent entry address, it needs to set the whitelist to do so.
list: ["new RegExp('https?.*')"]
},
onInit() {
console.info('onInit: ');
},
onPageStart(e) {
console.info('pagestart: ' + e.url)
},
// Each page switch triggers
onPageFinish(e) {
console.info('pagefinish: ' + e.url, e.canBack, e.canForward);
},
onTitleReceive(e) {
this.title = e.title;
},
onError(e) {
console.info('pageError : ' + e.errorMsg)
},
onMessage(e) {
console.info('onmessage e = ' + e.message + ", url = " + e.url);
},
onShow: function () {
console.info(" onshow");
},
onHide: function () {
console.info(" onHide");
},
onBackPress() {
console.log('onBackPress')
this.$element('web').canBack({
callback: function (e) {
if (e) {
console.log('web back')
this.$element('web').back()
} else {
console.log('router back')
router.back()
}
}.bind(this)
})
return true
},
}
</script>
3) Put your app icon under Common folder. E.g. developer.png
4) Open manifest.json file and paste follwing script and change icon name with the file that you uploaded under Common folder.
Code:
{
"package": "com.testapp.huwei",
"name": "TestApp",
"versionName": "1.0.0",
"versionCode": 1,
"icon": "/Common/developer.png",
"minPlatformVersion": 1060,
"features": [
{
"name": "system.configuration"
},
{
"name": "system.calendar"
},
{
"name": "system.prompt"
},
{
"name": "system.router"
}
],
"permissions": [
{
"origin": "*"
}
],
"config": {},
"router": {
"entry": "Hello",
"pages": {
"Hello": {
"component": "hello"
}
}
},
"display": {
"titleBar":false
}
}
4) Create .rpk package by using Build > Run Release direction.
5) Accept IDE to create a signature file for your app.
6) com.testapp.huawei_release_1.0.0.rpk package has been generated and ready for test.
Ever wanted to send push notifications to your Android app? Yes? Well then, there's a good chance you've used a delivery service like Google Cloud Messaging or Firebase Cloud Messaging. Unfortunately, these services won't work on Huawei devices.
Luckily, Huawei has implemented its own notification delivery framework as part of HMS. If you're targeting Huawei devices with your app and need to deliver push notifications, this guide is for you. We'll be talking about receiving notifications through HMS on Android.
Preparation
First up, make sure you have a Huawei Developer Account. This process can take a couple days, and you'll need one to use this SDK, so be sure to start that as soon as possible. You can sign up at https://developer.huawei.com.
Next, you'll want to obtain the SHA-256 representation of your app's signing key. If you don't have a signing key yet, be sure to create one before continuing. To obtain your signing key's SHA-256, you'll need to use Keytool which is part of the JDK installation. Keytool is a command-line program. If you're on Windows, open CMD. If you're on Linux, open Terminal.
On Windows, you'll need to "cd" into the directory containing the Keytool executable. For example, if you have JDK 1.8 v231 installed, Keytool will be located at the following path:
Code:
C:\Program Files\Java\jdk1.8.0_231\bin\
Once you find the directory, "cd" into it:
Code:
C: #Make sure you're in the right drive
cd C:\Program Files\Java\jdk1.8.0_231\bin\
Next, you need to find the location of your keystore. Using Android's debug keystore as an example, where the Android SDK is hosted on the "E:" drive in Windows, the path will be as follows:
Code:
E:\AndroidSDK\.android\debug.keystore
(Keytool also supports JKS-format keystores.)
Now you're ready to run the command. On Windows, it'll look something like this:
Code:
keytool -list -v -keystore E:\AndroidSDK\.android\debug.keystore
On Linux, the command should be similar, just using UNIX-style paths instead.
Enter the keystore password, and the key name (if applicable), and you'll be presented with something similar to the following:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Make note of the SHA256 field.
SDK Setup
Now we're ready to add the Push Kit SDK to your Android Studio project. Go to your Huawei Developer Console and click the HUAWEI AppGallery tile. Agree to the terms of use if prompted.
Click the "My projects" tile here. If you haven't already added your project to the AppGallery, add it now. You'll be asked for a project name. Make it something descriptive so you know what it's for.
Now, you should be on a screen that looks something like the following:
Click the "Add app" button. Here, you'll need to provide some details about your app, like its name and package name.
Once you click OK, some SDK setup instructions will be displayed. Follow them to get everything added to your project. You'll also need to add the following to the "dependencies" section of your app-level build.gradle file:
Code:
implementation 'com.huawei.hms:push:4.0.4.301'
If you ever need to come back to these instructions, you can always click the "Add SDK" button after "App information" on the "Project setting" page.
Now you should be back on the "Project setting" page. Find the "SHA-256 certificate fingerprint" field under "App information," click the "+" button, and paste your SHA-256.
Go back to the Manage APIs tab on the "Project setting" page. Scroll down until you find "Push Kit" and make sure it's enabled.
Next, expand the "Growing" category in the sidebar and select "Push Kit."
You should see something similar to the following:
Click the "Enable now" button. After a few seconds, you should see this popup:
Next, go to the "Settings" tab. You should then be prompted to select a data storage location. Choose the one that's best for you.
Now, if you're using obfuscation in your app, you'll need to whitelist a few things for HMS to work properly.
For ProGuard:
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
For AndResGuard:
Code:
"R.string.hms*",
"R.string.agc*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*
Next up, you'll need to create a class extending HmsMessageService:
Code:
class MyMessageService : HmsMessageService() {
//...
}
And add it to your AndroidManifest.XML:
XML:
<service
android:name=".MyMessageService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
That's it! The Push Kit SDK should now be available in your project.
Basic Usage
To use the Push Kit SDK, you'll need to generate a token for each device using your app. The SDK can take care of this for you. Simply add the following to your AndroidManifest.xml:
XML:
<application>
<!--.....-->
<meta-data
android:name="push_kit_auto_init_enabled"
android:value="true" />
</application>
Then, inside MyMessageService, you just need to override the following method:
Code:
class MyMessageService : HmsMessageService() {
//Make sure whatever happens here takes fewer than 10 seconds.
//Otherwise, you'll run into Android's Service restrictions
//and you'll need to create a Job.
override fun onNewToken(token: String?) {
if (!token.isNullOrBlank()) {
//Send the token to your server
}
}
}
(For more advanced behavior, like manually applying for tokens, see Huawei's documentation.)
To receive messages, simply override the onMessageReceived() method:
Code:
class MyMessageService : HmsMessageService() {
//...
//A new message has been received
override fun onMessageReceived(message: RemoteMessage?) {
if (message == null) {
//The message is null. Nothing to handle.
return
}
//There is a lot of potential data contained in a message.
val collapseKey = message.collapseKey //String
val data = message.data //String
val from = message.from //String
val to = message.to //String
val messageId = message.messageId //String
val sentTime = message.sentTime //Long
val dataOfMap = message.dataOfMap //MutableMap<String, String>
val messageType = message.messageType //String
val ttl = message.ttl //Int
val token = message.token //String
//You can also get a notification template for the message
val notification = message.notification //RemoteMessage$Notification
val imageUrl = notification.imageUrl //Uri
val title = notification.title //String
val titleLocalizationKey = notification.titleLocalizationKey //String
val titleLocalizationArgs = notification.titleLocalizationArgs //Array<String>
val body = notification.body //String
val bodyLocalizationKey = notification.bodyLocalizationKey //String
val bodyLocalizationArgs = notification.bodyLocalizationArgs //Array<String>
val icon = notification.icon //String
val sound = notification.sound //String
val tag = notification.tag //String
val color = notification.color //String
val clickAction = notification.clickAction //String
val channelId = notification.channelId //String
val link = notification.link //Uri
val notifyId = notification.notifyId //Int
//Just like with onNewToken(), this method needs to complete
//within 10 seconds.
}
}
Conclusion
That's all you need to receive push notifications on Android through HMS!
To learn how you can set up message sending, and for more advanced methods of notification handling, be sure to check out Huawei's official documentation.
Overview
Did you ever gone through your vacation photos and asked yourself: What is the name of this place I visited in India? Who created this monument I saw in France? Landmark recognition can help! This technology can predict landmark labels directly from image pixels, to help people better understand and organize their photo collections.
Landmark recognition can be used in tourism scenarios. The landmark recognition service enables you to obtain the landmark name, landmark longitude and latitude, and confidence of the input image. A higher confidence indicates that the landmark in the input image is more likely to be recognized. Based on the recognized information, you can create more personalized app experience for users.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
In this article, I will show how user can get the landmark information using ML Kit Plugin.
Integrate this service into a travel app so that images taken by users are detected by ML Plugin to return the landmark name and address, and the app can provide the brief introduction and tour suggestions based on the returned information.
Create Project in Huawei Developer Console
Before you start developing an app, configure app information in App Gallery Connect.
Register as a Developer
Before you get started, you must register as a Huawei developer and complete identity verification on HUAWEI Developers. For details, refer to Registration and Verification.
Create an App
Follow the instructions to create an app Creating an App Gallery Connect Project and Adding an App to the Project. Set the data storage location to Germany
Adding an App to the Project. Set the data storage location to Germany
React Native setup
Requirements
Huawei phone with HMS 4.0.0.300 or later.
React Native environment with Android Studio, NodeJs and Visual Studio code.
Dependencies
Gradle Version: 6.3
Gradle Plugin Version: 3.5.2
React-native-hms-ml gradle dependency
React Native CLI: 2.0.1
1. Environment setup, refer below link.
Setting up the development environment · React Native
This page will help you install and build your first React Native app.
reactnative.dev
2. Create project by using this command.
Code:
react-native init project name
3. You can install react native command line interface on npm, using the install -g react-native-cli command as shown below.
Code:
npm install –g react-native-cli
Generating a Signing Certificate Fingerprint
Signing certificate fingerprint is required to authenticate your app to Huawei Mobile Services. Make sure JDK is installed. To create one, navigate to JDK directory’s bin folder and open a terminal in this directory. Execute the following command:
Code:
keytool -genkey -keystore <application_project_dir>\android\app\<signing_certificate_fingerprint_filename>.jks -storepass <store_password> -alias <alias> -keypass <key_password> -keysize 2048 -keyalg RSA -validity 36500
This command creates the keystore file in application_project_dir/android/app
The next step is obtain the SHA256 key which is needed for authenticating your app to Huawei services, for the key store file. To obtain it, enter following command in terminal:
Code:
keytool -list -v -keystore <application_project_dir>\android\app\<signing_certificate_fingerprint_filename>.jks
After an authentication, the SHA256 key will be revealed as shown below.
Adding SHA256 Key to the Huawei project in App Gallery
Copy the SHA256 key and visit AppGalleryConnect/ <your_ML_project>/General Information. Paste it to the field SHA-256 certificate fingerprint.
Enable the ML kit from ManageAPIs.
Download the agconnect-services.jsonfrom App Gallery and place the file in android/app directory from your React Native Project.
Follow the steps to integrate the ML plugin to your React Native Application.
Integrate the HMS-ML plugin
Code:
npm i @hmscore/react-native-hms-ml
Download the Plugin from the Download Link
Download ReactNative ML Plugin under node_modules/@hmscore of your React Native project, as shown in the directory tree below:
Code:
project-dir
|_ node_modules
|_ ...
|_ @hmscore
|_ ...
|_ react-native-hms-ml
|_ ...
|_ ...
Navigate to android/app/build.gradle directory in your React Native project. Follow the steps:
Add the AGC Plugin dependency.
Code:
apply plugin: 'com.huawei.agconnect'
Add to dependencies in android/app/build.gradle:
Code:
implementation project(':react-native-hms-ml')
Navigate to App level android/build.gradle directory in your React Native project. Follow the steps:
Add to buildscript/repositories
Code:
maven {url 'http://developer.huawei.com/repo/'}
Add to buildscript/dependencies
Code:
classpath 'com.huawei.agconnect:agcp:1.3.1.300’'3)
Navigate to android/settings.gradle and add the following:
Code:
include ':react-native-hms-ml'
project(':react-native-hms-ml').projectDir = new File(rootProject.projectDir, '../node_modules/@hmscore/react-native-hms-ml/android')
Use case
Huawei ML kit’s HMSLandmarkRecognition API can be integrate for different applications and to return the landmark name and address, and the app can provide the brief introduction and tour suggestions based on the returned information.
Add below under AndroidManifest.xml file.
XML:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
<meta-data
android:name="com.huawei.hms.ml.DEPENDENCY"
android:value="dsc"/>
</ application>
Set API Key:
Before using HUAWEI ML in your app, set Api key first.
Copy the api_key value in your agconnect-services.json file.
Call setApiKey with the copied value.
JavaScript:
HMSApplication.setApiKey("api_key").then((res) => {console.log(res);})
catch((err) => {console.log(err);})
Analyze Frame
Using HMSLandmarkRecognition.asyncAnalyzeFrame() recognizes landmarks in images asynchronously.
JavaScript:
async asyncAnalyzeFrame() {
try {
var result = await HMSLandmarkRecognition.asyncAnalyzeFrame(true, this.getFrameConfiguration(), this.getLandmarkAnalyzerSetting());
console.log(result);
if (result.status == HMSApplication.SUCCESS) {
result.result.forEach(element => {
this.state.landmark.push(element.landMark);
this.state.possibility.push(element.possibility);
this.state.url.push('https://en.wikipedia.org/wiki/'+element.landMark)
long = [];
lat = [];
element.coordinates.forEach(ll => {
long.push(ll.longitude);
lat.push(ll.latitude);
})
this.state.coordinates.push(lat, long);
});
this.setState({
landMark: this.state.landmark,
possibility: this.state.possibility,
coordinates: this.state.coordinates,
url:this.state.url,
});
}
else {
ToastAndroid.showWithGravity(result.message, ToastAndroid.SHORT, ToastAndroid.CENTER);
}
} catch (e) {
console.error(e);
}
}
Final Code:
JavaScript:
import React from 'react';
import {
Text,
View,
TextInput,
ScrollView,
TouchableOpacity,
Image,
ToastAndroid,
SafeAreaView
} from 'react-native';
import { styles } from '@hmscore/react-native-hms-ml/example/src/Styles';
import { HMSLandmarkRecognition, HMSApplication } from '@hmscore/react-native-hms-ml';
import { showImagePicker } from '@hmscore/react-native-hms-ml/example/src/HmsOtherServices/Helper';
import { WebView } from 'react-native-webview';
export default class App extends React.Component {
componentDidMount() { }
componentWillUnmount() { }
constructor(props) {
super(props);
this.state = {
imageUri: '',
landmark: [],
coordinates: [],
possibility: [],
url:[]
};
}
getLandmarkAnalyzerSetting = () => {
return { largestNumOfReturns: 10, patternType: HMSLandmarkRecognition.STEADY_PATTERN };
}
getFrameConfiguration = () => {
return { filePath: this.state.imageUri };
}
async asyncAnalyzeFrame() {
try {
var result = await HMSLandmarkRecognition.asyncAnalyzeFrame(true, this.getFrameConfiguration(), this.getLandmarkAnalyzerSetting());
console.log(result);
if (result.status == HMSApplication.SUCCESS) {
result.result.forEach(element => {
this.state.landmark.push(element.landMark);
this.state.possibility.push(element.possibility);
this.state.url.push('https://en.wikipedia.org/wiki/'+element.landMark)
long = [];
lat = [];
element.coordinates.forEach(ll => {
long.push(ll.longitude);
lat.push(ll.latitude);
})
this.state.coordinates.push(lat, long);
});
this.setState({
landMark: this.state.landmark,
possibility: this.state.possibility,
coordinates: this.state.coordinates,
url:this.state.url,
});
}
else {
ToastAndroid.showWithGravity(result.message, ToastAndroid.SHORT, ToastAndroid.CENTER);
}
} catch (e) {
console.error(e);
}
}
startAnalyze() {
this.setState({
landmark: [],
possibility: [],
coordinates: [],
url:[],
})
this.asyncAnalyzeFrame();
}
render() {
console.log(this.state.url.toString());
return (
<ScrollView style={styles.bg}>
<View style={styles.containerCenter}>
<TouchableOpacity onPress={() => { showImagePicker().then((result) => this.setState({ imageUri: result })) }}>
<Image style={styles.imageSelectView} source={this.state.imageUri == '' ? require('@hmscore/react-native-hms-ml/example/assets/image.png') : { uri: this.state.imageUri }} />
</TouchableOpacity>
</View>
<Text style={styles.h1}>pick the image and explore the information about place</Text>
<View style={styles.basicButton}>
<TouchableOpacity
style={styles.startButton}
onPress={this.startAnalyze.bind(this)}
disabled={this.state.imageUri == '' ? true : false} >
<Text style={styles.startButtonLabel}> Check Place </Text>
</TouchableOpacity>
</View>
<Text style={{fontSize: 20}}> {this.state.landmark.toString()} </Text>
<View style={{flex: 1}}>
<WebView
source={{uri: this.state.url.toString()}}
style={{marginTop: 20,height:1500}}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
scalesPageToFit={true}
/>
</View>
</ScrollView>
);
}
}
Run the application (Generating the Signed Apk):
1. Open project directory path in Command prompt.
2. Navigate to android directory and run the below command for signing the Apk.
Code:
gradlew assembleRelease
Output:
Tips and Tricks:
Download latest HMS ReactNativeML plugin.
Copy the api_key value in your agconnect-services.json file and set API key.
Images in PNG, JPG, JPEG, and BMP formats are supported. GIF images are not supported.
For project cleaning, navigate to android directory and run the below command.
Code:
gradlew clean
Conclusion:
In this article, we have learnt to integrate ML kit in React native project.
This service into a travel apps, so that images taken by users and detected by ML Plugin to return the landmark information, and the app can provide the brief introduction and tour suggestions to user.
Reference
https://developer.huawei.com/consum...-Guides/landmark-recognition-0000001050726194