SERVICE_NOT_AVAIBLE on GCM Android - android

I am having an issue with a terminal.
The point is that, I am able to connect with every devices but that one, and I don't understand why it is not working only with that device when there is Google_services installed and the internet connection is working properly......
This is my Manifest
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="es.pruebas.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="es.pruebas.permission.C2D_MESSAGE" />
<application
android:name="es.pruebas.Aplicacion"
android:allowBackup="true"
android:icon="#drawable/ic_app"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="es.pruebas.ui.activities.SplashScreenActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<receiver
android:name="es.pruebas.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="es.pruebas" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="es.pruebas" />
</intent-filter>
</receiver>
<service android:name="es.pruebas.GcmIntentService" />
</application>
Accordig to Google documentation, it tells me that I have to retry, and I retry 10 times with a difference of 1 sec each one, but anyway, this is only happening with this device, and not with the others I have been trying.
The terminal which is giving me problem is a Sony Ericson Xperia LT 26E, Android version 4.0.4...
Thnaks a lot for your help!

I just found the solution!
According to what I saw, Google has problems detecting the date and the time on terminals without SIM card and with "Automatic dates & time" activated, so when this is happening, I show a dialog to the user telling him to deactivate "Automatic dates & time" so that Google can get the time and the date from the system and the registration can continue without any problems.

Related

OUTDATED DEVICE: Parse Push Notification to Android devices

Hi have worked with parse for saving data. But notification is something i am stuck with. I am not able figure out what's going wrong.
I have done all the receiver registrations and so my device also gets registered in the installation table but while sending push from web console it says "push sent 0" looking into the description of each push it shows that "OUTDATED DEVICE - The records on this installation are outdated, the user might have uninstalled the app." But I just did the registration.
I am going mad with this...no clue in what am I doing wrong, I am using eclipse IDE, Can anyone please suggest me any Solution??
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.parsecomlogin"
android:versionCode="1"
android:versionName="1.0" >
<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.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.example.parsecomlogin.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.parsecomlogin.permission.C2D_MESSAGE" />
<permission
android:name="com.example.parsecomlogin.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.parsecomlogin.permission.MAPS_RECEIVE" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application
android:name=".ParseApp"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Added for Parse push notifications -->
<!-- My custom receiver -->
<receiver
android:name=".ParseReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="com.example.parsecomlogin.RECEIVE_PUSH" />
</intent-filter>
</receiver>
<!-- END my custom receiver -->
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver
android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false" >
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver
android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.parsecomlogin" />
</intent-filter>
</receiver>
<activity
android:name=".Welcome"
android:label="#string/title_activity_welcome" >
</activity>
<activity
android:name=".LoginActivity"
android:label="#string/title_login" >
</activity>
<activity
android:name=".LoginSignupActivity"
android:label="#string/title_activity_login_signup" >
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyDZ5TG28QJnN5zMyIdezPllvrfrwg7ElQs" />
</application>
</manifest>
I faced exactly the same problem and I fixed it a few minutes ago by coincidence. I hope the problem can be solved with the same touch-up for you as well.
In my situation, I used one of the older projects I worked and I have changed manifest package name manually in a way. In AndroidManifest.xml file, the manifest package name was changed to "com.myprojectname". There was no problem and app can run without any error with this package name. Also, all of Parse features run problem-free except push notification service. Then I checked other paths with Ctrl + Shift + R and searched whether R.java uses the same name. Unsurprisingly, the package name was identical in this file but I realized that in the lines below R.java uses the pattern of "net.myprojectname.app" instead of "com.myprojectname". I replaced "com.myprojectname" with "net.myprojectname.app" in all files by using Ctrl + Shift + R again. I think it was not the cause of the problem but I tried to send a last push notification desperately. It is hard to believe but it is worked. I got the notification successfully after all.
I answered the question in a highly informal and non-technical way but I have no idea about the underlying cause, I just want to help. Maybe it works for you. Good luck.

Activity doesn't open when the user taps on the notification

In my app main activity doesn't open when the user taps on the notification
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mx.com.eluniversal.test.pruebapushtags">
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="17" />
<permission android:name="mx.com.eluniversal.test.pruebapushtags.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="mx.com.eluniversal.test.pruebapushtags.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:theme="#style/AppTheme">
<activity android:name="mx.com.eluniversal.test.pruebapushtags.ActivityPrincipal" android:label="#string/app_name" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="mx.com.eluniversal.test.pruebapushtags.ActivityPrincipal.NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="com.worklight.wlclient.ui.UIActivity" />
<service android:name="com.worklight.wlclient.push.GCMIntentService" />
<receiver android:name="com.worklight.wlclient.push.WLBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="mx.com.eluniversal.test.pruebapushtags" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="mx.com.eluniversal.test.pruebapushtags" />
</intent-filter>
</receiver>
</application>
</manifest>
It doesn't open if the app is on the background and doesn't update the information in the activity while in the foreground when a new push notification arrives.
You can take a look at the following Native Android sample application that demonstrates implementing Tag-based push notifications: https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-7-0/notifications/push-notification-native-android-applications/tag-based-notifications/
Compare its files with yours (AndroidManifest.xml, strings.xml, ...).
Since you are not responding in the comments, that's the best that can be done at this time.
Note: This application is based on MobileFirst Platform 7.0, so you cannot open the project file in previous releases. However, you can still extract the .zip file and look at the source files from the file system.

App is not available on Play Store in some tablet devices mostly with Android version 4.1.1

App is not available on Play Store in some tablet devices.
I searched about this issue but no solution solved my problem. I can't figure out why my app is not available on Play Store on some tablet devices. But when I try to search it in Google Play website using the browser, it is available and I was able to install it. I tried adding tag and android:required="false" attribute as what others recommend but this doesn't solve the problem. This is the manifest of my app.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.companyname.appname"
android:versionCode="30"
android:versionName="1.0.20" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="20" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" >
</uses-feature>
<uses-feature
android:name="android.hardware.telephony"
android:required="false" >
</uses-feature>
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcer"
android:label="#string/app_name"
android:theme="#android:style/Theme.Light.NoTitleBar" >
<activity
android:name="com.companyname.appname.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|stateHidden" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.companyname.appname.ViewLogFragment"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|stateHidden" />
<receiver android:name="com.companyname.background.BootCompleteReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.companyname.background.ShutDownReceiver" >
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.companyname.background.TimeChangeReceiver" >
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.companyname.background.DateChangeReceiver" >
<intent-filter>
<action android:name="android.intent.action.DATE_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.companyname.background.TimeZoneChangeReceiver" >
<intent-filter>
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name="com.companyname.background.SyncAndUpdateService" />
<service android:name="com.companyname.background.AutoSendBackUpService" />
</application>
</manifest>
Actually there's no error on the manifest. It just took 3 days for all the devices to see my app. When I uploaded my app on the Google Play, after 2-3 hours it is already available for some devices but it took 3 days for other devices. There's no issue on the android version or on the manifest. Just make sure you check out Filters on Google Play before uploading your app on the Play Store as what SirChristian123 adviced.
I actually does not seems something wrong with the code, You should be careful with the camera feature like Henry said because Google is not going to show it if a device does not support a camera. Sometimes it can confuses Google though.
Check this out and see if something in your code that you did not posted here is the problem:
This is the official information about Filters in Google Play:
http://developer.android.com/google/play/filters.html

WakefulReceiver fires on all versions but 4.0.3

I've got a WakefulReceiver and an IntentService set up for push notifications, just the way they are shown in the GCM tutorial.
I've gotten the notifications without issue in most devices version on Android versions 4.1.x and up (.2, .3, .4) no problem.
However on version 4.0.3 my wakeful receiver is not even firing. I've gone over the permissions since that's what I've seen on the net, but I've thrice checked the permissions and they seem to be fine.
Is there a known issue with 4.0.3 or some other lead?
Here's my Android manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.companyname.mobile.appname"
android:versionCode="1"
android:versionName="0.2" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<permission
android:name="com.companyname.appname.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.companyname.appname.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/myLauncherIcon"
android:label="#string/launcher_name"
android:largeHeap="true"
android:logo="#drawable/myLogo"
android:theme="#style/Theme.MyAppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="com.companyname.appname.activity.LoginActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="#android:style/Theme.Holo.Light.NoActionBar"
android:windowSoftInputMode="stateHidden|adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.companyname.appname.activity.HomeActivity"
android:configChanges="keyboardHidden"
android:windowSoftInputMode="stateHidden" >
</activity>
<receiver
android:name="com.companyname.appname.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.companyname.appname" />
</intent-filter>
</receiver>
<service android:name="com.companyname.appname.GcmIntentService" />
</application>

How to track GCM Problems?

I have a problem I`m just not getting any GCM Messages. I dont want Pop Ups or sounds playing, it doesnt even fire the onReceive() Method in the Broadcast Reciever, which is, to my understanding, the first point the Application handles a message.
My biggest problem is I dont get any error messages or Hints. When I send a message, I get the message ID, a multicast ID and a "success=1" message. I also get a "Device registrated on any device and a Reg ID, a "already registered" running the app a second time. The Devices are also logged into Google Play, same account as on the Google API Console. But nothing happens on the Device when I send a GCM Message.
I post my complete android manifest, please let me know if you need more code. This is driving my crazy.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lottoapplicationandroid"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto"
>
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="9" />
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:resizeable="true"
android:anyDensity="true" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<permission android:name="com.lottoapplicationandroid.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.lottoapplicationandroid.permission.C2D_MESSAGE" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- ZXing activities -->
<activity android:name="com.google.zxing.client.android.CaptureActivity"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter>
<action android:name="com.phonegap.plugins.barcodescanner.SCAN"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.google.zxing.client.android.encode.EncodeActivity" android:label="#string/share_name">
<intent-filter>
<action android:name="com.phonegap.plugins.barcodescanner.ENCODE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.lottoapplicationandroid" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
EDIT
I dont need a solution for this if not possible. I´d be very thankful for hints how to find out what`s going wrong. E.g. I found out I have to have an open Port 5228. Does anybody know how to check if the devices is listening on that port?
The Issue is solved.
I had to turn Wi-Fi off.
WiFi / Telephone-Network
off / off : not working
on / off : not working
on / on : not working
off / on : working
Aren't you missing some intent filters for the receiver ?
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.lottoapplicationandroid" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.lottoapplicationandroid" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="packagename.permission.C2D_MESSAGE" />
<receiver
android:name=".MyBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="packagename" />
</intent-filter>
</receiver>
<service android:name="Packagename.MyIntentService" >
</service>
Try it hope so it works.

Categories

Resources