Since the Xaml property of the RichTextbox is not a dependency property I have created a customized RichTextbox where I can interact with its xaml property:
Code:
<local:RichTextUserControl RtfXaml="{Binding Path=Text, Converter={StaticResource RichTextBoxContentConverter}}" />
and I am Binding the following text to the xaml property and it is working fine:
Code:
<Section xml:space=\"preserve\" HasTrailingParagraphBreakOnPaste=\"False\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">
<Paragraph FontSize=\"20\" FontFamily=\"Segoe WP\" Foreground=\"#FFFFFFFF\" FontWeight=\"Normal\" FontStyle=\"Normal\" FontStretch=\"Normal\" TextAlignment=\"Left\">
<Run Text=\"Some text without formatting\" />
<Italic>Some italic text</Italic>
<Underline>I am UnderLined</Underline>
</Paragraph>
</Section>
I am binding with it trough a converter, where I search for smiley characters (for example , , so on...) and replacing them with images, and if I insert the following code somewhere in-between the paragraph text it crashes:
Code:
<InlineUIContainer>
<Image Source="ApplicationIcon.png"/>
</InlineUIContainer>
It is only exception when it is with binding.
thanks in advance
Related
I'm stuck. I am building a custom Settings.apk for a new tablet and I've run across an error I can't find.
Any dialog that displays a SeekBar or variation simply FC's with a null pointer exception. I have a reference source tree that is a virgin copy from the android git. If I compile the stock Settings.apk, it does the same thing at the same places as my custom version.
The error occurs in the BrightnessPreference.java and the RingerVolumePreference.java files any time the dialog containing a SeekBar or Volumizer tries to display.
Here's an example of the code:
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mSeekBar = getSeekBar(view);
mSeekBar.setMax(MAXIMUM_BACKLIGHT - mMinBrightness); <-- errors here
It errors at setMax with a null pointer error, like the setMax method doesn't exist. My build environment seems fine. Everything I've built runs on the target devices, but this one has me stumped. Has anyone else tried building a Settings.apk lately, and does it display the volume (in sound) and brightness (in Display) dialogs?
BTW, the target is Froyo
Thanks,
--- Jem
Are you sure the mMinBrightness variable is defined? BrightnessPreference.java as shown here instead uses MINIMUM_BACKLIGHT and is defined as:
Code:
private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
It is then used to set the seekbar max:
Code:
mSeekBar.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);
You can also look at the onBindDialogView in RingerVolumePreference.java here. If you want to check whether the java files change from the version I linked(2.2.1 Froyo), just use the arrows on either side of the currently listed version.
I appreciate the response. Yes it is defined and initialized earlier as referenced below.
=== Code ===
private int mMinBrightness;
private boolean mAutomaticAvailable;
// Backlight range is from 0 - 255. Need to make sure that user
// doesn't set the backlight to 0 and get stuck
private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
public BrightnessPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mAutomaticAvailable = context.getResources().getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available);
setDialogLayoutResource(R.layout.preference_dialog_brightness);
setDialogIcon(R.drawable.ic_settings_display);
mMinBrightness = MINIMUM_BACKLIGHT;
if (Settings.System.getInt(context.getContentResolver(),
Settings.System.LIGHT_SENSOR_CUSTOM, 0) != 0) {
mMinBrightness = Settings.System.getInt(context.getContentResolver(),
Settings.System.LIGHT_SCREEN_DIM, mMinBrightness);
}
}
=== code ===
Thanks,
--- Jem
It might be useful to rule out an issue with mMinBrightness not getting set or getting set incorrectly by either replacing it with MINIMUM_BACKLIGHT in the setMax line or using a toast message to display the value of mMinBrightness before setMax. If that doesn't reveal anything, could you paste the relevant logcat output for the error/fc and also upload your BrightnessPreference.java file somewhere so it could be downloaded.
I saved the dir's with my modified package and blew away the entire repo structure. I then reloaded the official Android tree from kernel.org. I have compiled the Settings.apk app ALL STOCK, and I get the same errors in the brightness and volume areas. A copy of the brightnesspreference.java and a log screenshot of the error tracking can be found at:
mlsoft dot sytes dot net/brightness.zip (I can't post the direct link)
The only change in the error is the line number (same call though).
At this point, I am wondering if anyone can build the Settings.apk from the repo and get it to display a seekbar or variant in brightness or volume settings using 2.2.1 (froyo). I am comfortable at this point thinking that it is in the tree structure and not my build environment. At least I have a place to hunt if you can reproduce the error on your end.
I really appreciate your help.
--- Jem
android:id="@*android
Yeah, same thing happened to me and I found answer.
I hope this might help.
You will find that two xml files using "@*android".
"It gives access to internal resources for platform apps.
It is NOT safe to build apps with such declarations unless you are building a bundled app within a full system image."
- from stackoverflow
"What is the purpose of the star in the ID string?"
Sorry that I can not post URL. I'm new user.
Sorry about not yet having built and tested the Settings.apk on my end but I haven't found the time to do so yet. Your issue could very well be what You Kim posted about and I'm sure I wouldn't have noticed that for awhile if at all. Here's the link to the stack overflow topic You Kim referenced. The two xml files in the Settings package this occurs in are res/layout/preference_dialog_brightness.xml and res/layout/preference_dialog_ringervolume.xml. That part looks like this:
Code:
<!-- In brightness layout -->
<[COLOR="Red"]SeekBar android:id="@*android:id/seekbar"[/COLOR]
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dip" />
<!-- In ringervolume layout -->
<!-- Used for the ring volume. This is what the superclass VolumePreference uses. -->
<[COLOR="red"]SeekBar android:id="@*android:id/seekbar"[/COLOR]
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="2dip"
android:paddingLeft="20dip"
android:paddingRight="20dip" />
Thank you both. I have been through those files more than once and didn't notice the declarations. Outstanding work guys. I'm off to edit/recompile/test.
Thanks again,
--- Jem
Unfortunately, these changes didn't stop the null pounter errors. Something, somewhere HAS to be uninitialized, but damned if I can find it in the absseekbar, progressbar, or any other class in the seekbar hierarchy. I even tried setting a value of 255 in setMax to rule out variable problems, but that produces the same error at the same line.
I know there is a fix, Settings works on millions of Android devices, so it has to be something stupid I'm overlooking.
--- Jem
Well, it's almost 3am, but I fixed the problem in the brightness preference. SeekBarPreference handles the getSeekBar function, but it doesn't work as expected.
It assigns a static system res ID that obviously doesn't work as intended. So, I overrode the routine just above the call to onBindDialogView. Here is the routine in the seekbarpreference file:
(at sign)Override
protected static SeekBar getSeekBar(View dialogView) {
return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar);
}
Overridden in the brightnes preference file to this:
(at sign)Override
protected static SeekBar getSeekBar(View dialogView) {
return (SeekBar) dialogView.findViewById(R.id.seekbar);
}
I'll go back and write the original to accept a res ID as an argument later. For now at least the brightness control works. Tomorrow I'll go after the volume controls.
--- Jem
I have a listbox, with custom items. Code:
Code:
<ListBox Height="600" HorizontalAlignment="Left" Margin="7,6,0,0" Name="friendList" VerticalAlignment="Top" Width="449" ItemsSource="{Binding Friends}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="5,0">
<Image Height="120" HorizontalAlignment="Left" Name="image" Stretch="Fill" VerticalAlignment="Top" Width="120" Source="{Binding ImageUri}" GotFocus="image_GotFocus"/>
<CheckBox Height="78" HorizontalAlignment="Left" Margin="65,63,0,0" x:Name="selectedChckbox" VerticalAlignment="Top" Width="55" IsChecked="{Binding Selected, Mode=TwoWay}"/>
<TextBlock Height="58" HorizontalAlignment="Left" Margin="0,122,0,0" x:Name="nameTextBlck" VerticalAlignment="Top" Text ="{Binding Title}" Width="120" TextWrapping="Wrap" GotFocus="name_GotFocus"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I've created a veiwmodel for the values for binding, and when I click on one item I want to change the checkbox state like so:
Code:
friendSelectionViewModel.Friends[_selectFriendContent.friendList.SelectedIndex].Selected = !friendSelectionViewModel.Friends[_selectFriendContent.friendList.SelectedIndex].Selected;
But the only way the listbox gets the values updated, if I set the datacontext to null and than assign the viewmodel aggain like so:
Code:
_selectFriendContent.DataContext = null;
_selectFriendContent.DataContext = friendSelectionViewModel;
But this takes about 5-10 seconds to refresh the list. I know there is a better solution, I just cant figure out how.
Thanks in advance!
I don't know what datatype your collection 'friends' is from what you've posted, but I assume it's some kind of collection of objects of type 'Friend' class, and if so you can achieve what you want as long as the 'Friend' class itself is also a viewmodel (i.e. implements INotifyPropertyChanged) and has a property on it called 'Selected'. It's that class that any bindings in your datatemplate will look to as a viewmodel.
Taking the above to be true; what you need is to bind your ListBox's SelectedItem property, e.g.:
<ListBox
x:Name="lbFriendsList"
SelectedItem="{Binding SelectedFriend, Mode=TwoWay}"
...
in your 'friendSelectionViewModel', when an item in the list is selected it will trigger code in the 'SelectedFriend' property's "set" method, where you will have access to the Friend object that has been selected, and you will be able to do whatever you want to it, e.g. to always have it 'checked' when it is tapped, you might have this kind of code in your friendSelectionViewModel (assuming you've got the xaml in place that I've written above):
public Friend SelectedFriend
{
get
{
...
}
set
{
if(value != null)
value.Selected = true;
}
}
As long as you've set up the class Friend as a viewmodel too, and code a 'Selected' property in the Friend class (and as with most properties in viewmodels you set it up to call the typical OnPropertyChanged("Selected "); in its 'set' method) then that will trigger the update of the checkbox that you've set up in the datatemplate (because you've already got that bound to the property 'Selected' in your Xaml).
Hope that's clear and helps
Ian
yes that was the problem, and I missed to implement INotifyPropertyChanged for the TempFriends Class
thanks
Author: Apriorit (Device Team)
Permanent link: www(dot)apriorit(dot)com/our-company/dev-blog/130-development-for-android
In this article I’ve described:
• How to develop simple Java service for the Android Devices;
• How to communicate with a service from the other processes and a remote PC;
• How to install and start the service remotely from the PC.
1. Java Service Development for the Android Devices
Services are long running background processes provided by Android. They could be used for background tasks execution. Tasks can be different: background calculations, backup procedures, internet communications, etc. Services can be started on the system requests and they can communicate with other processes using the Android IPC channels technology. The Android system can control the service lifecycle depending on the client requests, memory and CPU usage. Note that the service has lower priority than any process which is visible for the user.
Let’s develop the simple example service. It will show scheduled and requested notifications to user. Service should be managed using the service request, communicated from the simple Android Activity and from the PC.
First we need to install and prepare environment:
• Download and install latest Android SDK from the official web site http://developer.android.com);
• Download and install Eclipse IDE (http://www.eclipse.org/downloads/);
• Also we’ll need to install Android Development Tools (ADT) plug-in for Eclipse.
After the environment is prepared we can create Eclipse Android project. It will include sources, resources, generated files and the Android manifest.
1.1 Service class development
First of all we need to implement service class. It should be inherited from the android.app.Service (http://developer.android.com/reference/android/app/Service.html) base class. Each service class must have the corresponding <service> declaration in its package's manifest. Manifest declaration will be described later. Services, like the other application objects, run in the main thread of their hosting process. If you need to do some intensive work, you should do it in another thread.
In the service class we should implement abstract method onBind. Also we override some other methods:
onCreate(). It is called by the system when the service is created at the first time. Usually this method is used to initialize service resources. In our case the binder, task and timer objects are created. Also notification is send to the user and to the system log:
Code:
01.public void onCreate()
02.{
03. super.onCreate();
04. Log.d(LOG_TAG, "Creating service");
05. showNotification("Creating NotifyService");
06.
07. binder = new NotifyServiceBinder(handler, notificator);
08. task = new NotifyTask(handler, notificator);
09. timer = new Timer();
10.}
onStart(Intent intent, int startId). It is called by the system every time a client explicitly starts the service by calling startService(Intent), providing the arguments it requires and the unique integer token representing the start request. We can launch background threads, schedule tasks and perform other startup operations.
Code:
1.public void onStart(Intent intent, int startId)
2.{
3. super.onStart(intent, startId);
4. Log.d(LOG_TAG, "Starting service");
5. showNotification("Starting NotifyService");
6.
7. timer.scheduleAtFixedRate(task, Calendar.getInstance().getTime(), 30000);
8.}
onDestroy(). It is called by the system to notify a Service that it is no longer used and is being removed. Here we should perform all operations before service is stopped. In our case we will stop all scheduled timer tasks.
Code:
1.public void onDestroy()
2.{
3. super.onDestroy();
4. Log.d(LOG_TAG, "Stopping service");
5. showNotification("Stopping NotifyService");
6.
7. timer.cancel();
8.}
onBind(Intent intent). It will return the communication channel to the service. IBinder is the special base interface for a remotable object, the core part of a lightweight remote procedure call mechanism. This mechanism is designed for the high performance of in-process and cross-process calls. This interface describes the abstract protocol for interacting with a remotable object. The IBinder implementation will be described below.
Code:
1.public IBinder onBind(Intent intent)
2.{
3. Log.d(LOG_TAG, "Binding service");
4. return binder;
5.}
To send system log output we can use static methods of the android.util.Log class (http://developer.android.com/reference/android/util/Log.html). To browse system logs on PC you can use ADB utility command: adb logcat.
The notification feature is implemented in our service as the special runnable object. It could be used from the other threads and processes. The service class has method showNotification, which can display message to user using the Toast.makeText call. The runnable object also uses it:
Code:
01.public class NotificationRunnable implements Runnable
02.{
03. private String message = null;
04.
05. public void run()
06. {
07. if (null != message)
08. {
09. showNotification(message);
10. }
11. }
12.
13. public void setMessage(String message)
14. {
15. this.message = message;
16. }
17.}
Code will be executed in the service thread. To execute runnable method we can use the special object android.os.Handler. There are two main uses for the Handler: to schedule messages and runnables to be executed as some point in the future; and to place an action to be performed on a different thread than your own. Each Handler instance is associated with a single thread and that thread's message queue. To show notification we should set message and call post() method of the Handler’s object.
1.2 IPC Service
Each application runs in its own process. Sometimes you need to pass objects between processes and call some service methods. These operations can be performed using IPC. On the Android platform, one process can not normally access the memory of another process. So they have to decompose their objects into primitives that can be understood by the operating system , and "marshall" the object across that boundary for developer.
The AIDL IPC mechanism is used in Android devices. It is interface-based, similar to COM or Corba, but is lighter . It uses a proxy class to pass values between the client and the implementation.
AIDL (Android Interface Definition Language) is an IDL language used to generate code that enables two processes on an Android-powered device to communicate using IPC. If you have the code in one process (for example, in Activity) that needs to call methods of the object in another process (for example, Service), you can use AIDL to generate code to marshall the parameters.
Service interface example showed below supports only one sendNotification call:
Code:
1.interface INotifyService
2.{
3.void sendNotification(String message);
4.}
The IBinder interface for a remotable object is used by clients to perform IPC. Client can communicate with the service by calling Context’s bindService(). The IBinder implementation could be retrieved from the onBind method. The INotifyService interface implementation is based on the android.os.Binder class (http://developer.android.com/reference/android/os/Binder.html):
Code:
01.public class NotifyServiceBinder extends Binder implements INotifyService
02.{
03. private Handler handler = null;
04. private NotificationRunnable notificator = null;
05.
06. public NotifyServiceBinder(Handler handler, NotificationRunnable notificator)
07. {
08. this.handler = handler;
09. this.notificator = notificator;
10. }
11.
12. public void sendNotification(String message)
13. {
14. if (null != notificator)
15. {
16. notificator.setMessage(message);
17. handler.post(notificator);
18. }
19. }
20.
21. public IBinder asBinder()
22. {
23. return this;
24. }
25.}
As it was described above, the notifications could be send using the Handler object’s post() method call. The NotificaionRunnable object is passed as the method’s parameter.
On the client side we can request IBinder object and work with it as with the INotifyService interface. To connect to the service the android.content.ServiceConnection interface implementation can be used. Two methods should be defined: onServiceConnected, onServiceDisconnected:
Code:
01.ServiceConnection conn = null;
02.…
03.conn = new ServiceConnection()
04.{
05. public void onServiceConnected(ComponentName name, IBinder service)
06. {
07. Log.d("NotifyTest", "onServiceConnected");
08. INotifyService s = (INotifyService) service;
09. try
10. {
11. s.sendNotification("Hello");
12. }
13. catch (RemoteException ex)
14. {
15. Log.d("NotifyTest", "Cannot send notification", ex);
16. }
17. }
18.
19. public void onServiceDisconnected(ComponentName name)
20. {
21. }
22.};
The bindService method can be called from the client Activity context to connect to the service:
1. Context.bindService(new Intent(this, NotifyService.class),
2.conn, Context.BIND_AUTO_CREATE);
The unbindService method can be called from the client Activity context to disconnect from the service:
1.Context.unbindService(conn);
1.3 Remote service control
Broadcasts are the way applications and system components can communicate. Also we can use broadcasts to control service from the PC. The messages are sent as Intents, and the system handles dispatching them, including starting receivers.
Intents can be broadcasted to BroadcastReceivers, allowing messaging between applications. By registering a BroadcastReceiver in application’s AndroidManifest.xml (using <receiver> tag) you can have your application’s receiver class started and called whenever someone sends you a broadcast. Activity Manager uses the IntentFilters, applications register to figure out which program should be used for a given broadcast.
Let’s develop the receiver that will start and stop notify service on request. The base class android.content.BroadcastReceiver should be used for these purposes (http://developer.android.com/reference/android/content/BroadcastReceiver.html):
Code:
01.public class ServiceBroadcastReceiver extends BroadcastReceiver
02.{
03.…
04. private static String START_ACTION = "NotifyServiceStart";
05. private static String STOP_ACTION = "NotifyServiceStop";
06.…
07. public void onReceive(Context context, Intent intent)
08. {
09. …
10. String action = intent.getAction();
11. if (START_ACTION.equalsIgnoreCase(action))
12. {
13. context.startService(new Intent(context, NotifyService.class));
14. }
15. else if (STOP_ACTION.equalsIgnoreCase(action))
16. {
17. context.stopService(new Intent(context, NotifyService.class));
18. }
19.
20. }
21.}
To send broadcast from the client application we use the Context.sendBroadcast call. I will describe how to use receiver and send broadcasts from the PC in chapter 2.
1.4 Android Manifest
Every application must have an AndroidManifest.xml file in its root directory. The manifest contains essential information about the application to the Android system, the system must have this information before it can run any of the application's code. The core components of an application (its activities, services, and broadcast receivers) are activated by intents. An intent is a bundle of information (an Intent object) describing a desired action — including the data to be acted upon, the category of component that should perform the action, and other pertinent instructions. Android locates an appropriate component to respond to the intent, starts the new instance of the component if one is needed, and passes it to the Intent object.
We should describe 2 components for our service:
• NotifyService class is described in the <service> tag. It will not start on intent. So the intent filtering is not needed.
• ServiceBroadcastReceived class is described in the <receiver> tag. For the broadcast receiver the intent filter is used to select system events:
Code:
01.<application android:icon="@drawable/icon" android:label="@string/app_name">
02.…
03. <service android:enabled="true" android:name=".NotifyService"
04.android:exported="true">
05. </service>
06. <receiver android:name="ServiceBroadcastReceiver">
07. <intent-filter>
08. <action android:name="NotifyServiceStart"></action>
09. <action android:name="NotifyServiceStop"></action>
10. </intent-filter>
11. </receiver>
12.…
2. Java service remote installation and start
2.1 Service installation
Services like the other applications for the Android platform can be installed from the special package with the .apk extension. Android package contains all required binary files and the manifest.
Before installing the service from the PC we should enable the USB Debugging option in the device Settings-Applications-Development menu and then connect device to PC via the USB.
On the PC side we will use the ADB utility which is available in the Android SDK tools directory. The ADB utility supports several optional command-line arguments that provide powerful features, such as copying files to and from the device. The shell command-line argument lets you connect to the phone itself and issue rudimentary shell commands.
We will use several commands:
• Remote shell command execution: adb shell <command> <arguments>
• File send operation: adb push <local path> <remote path>
• Package installation operation: adb install <package>.apk
I’ll describe the package installation process in details. It consists of several steps which are performed by the ADB utility install command:
• First of all the .apk package file should be copied to the device. The ADB utility connects to the device and has limited “shell” user privileges. So almost all file system directories are write-protected for it. The /data/local/tmp directory is used as the temporary storage for package files. To copy package to the device use the command:
adb push NotifyService.apk /data/local/tmp
• Package installation. ADB utility uses special shell command to perform this operation. The “pm” (Package Manager?) utility is present on the Android devices. It supports several command line parameters which are described in the Appendix I. To install the package by yourself execute the remote shell command:
adb shell pm install /data/local/tmp/NotifyService.apk
• Cleanup. After the package is installed, ADB removes the temporary file stored in /data/local/tmp folder using the “rm” utility:
adb shell rm /data/local/tmp/NotifyService.apk.
• To uninstall package use the “pm” utility:
adb shell pm uninstall <package>
2.2 Remote service control
To be able to start and stop the NotifyService from the PC we can use the “am” (Activity Manager?) utility which is present on the Android device. The command line parameters are described in the Appendix II. The “am” utility can send system broadcast intents. Our service has the broadcast receiver which will be launched by the system request.
To start NotifyService we can execute remote shell command:
adb shell am broadcast –a NotifyServiceStart
To stop the NotifyService we can execute remote shell command:
adb shell am broadcast –a NotifyServiceStop
Note, that the NotifyServiceStart and NotifyServiceStop intents were described in the manifest file inside the <receiver> … <intent-filter> tag. Other requests will not start the receiver.
Appendix I. PM Usage (from Android console)
Code:
01.pm [list|path|install|uninstall]
02.pm list packages [-f]
03.pm list permission-groups
04.pm list permissions [-g] [-f] [-d] [-u] [GROUP]
05.pm path PACKAGE
06.pm install [-l] [-r] PATH
07.pm uninstall [-k] PACKAGE
08.
09.The list packages command prints all packages.
10.Use the -f option to see their associated file.
11.The list permission-groups command prints all known permission groups.
12.The list permissions command prints all known permissions, optionally
13.only those in GROUP.
14.
15.Use the -g option to organize by group.
16.Use the -f option to print all information.
17.Use the -s option for a short summary.
18.Use the -d option to only list dangerous permissions.
19.Use the -u option to list only the permissions users will see.
20.
21.The path command prints the path to the .apk of a package.
22.
23.The install command installs a package to the system. Use the -l option to
24. install the package with FORWARD_LOCK. Use the -r option to reinstall an
25.exisiting app, keeping its data.
26.The uninstall command removes a package from the system. Use the -k option
27.to keep the data and cache directories around after the package removal.
Appendix II. AM Usage (from Android console)
Code:
01.am [start|broadcast|instrument]
02.am start -D INTENT
03.am broadcast INTENT
04.am instrument [-r] [-e <ARG_NAME> <ARG_VALUE>] [-p <PROF_FILE>] [-w] <COMPONENT>
05.
06.INTENT is described with:
07. [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
08. [-c <CATEGORY> [-c <CATEGORY>] ...]
09. [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
10. [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
11. [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
12. [-n <COMPONENT>] [-f <FLAGS>] [<URI>]
13.
14.<h2>
Sources of the Sample Project can be downloaded at the article official page www(dot)apriorit(dot)com/our-company/dev-blog/130-development-for-android
All articles, code pieces, example project sources and other materials are the intellectual property of Apriorit Inc. and their authors.
All materials are distributed under the Creative Commons BY-NC License.
In this post I will be explaining you guys that 'How to make a push notification app through GCM Service on PushBots'
Code is necessary for the implementation can be copied from here and watch the video below for the detail explanation of the implementation. Video will be uploaded soon
Android SDK integration
go to your module build.gradle file add PushBots dependency along with android support library v4:
Step 1: Import the Pushbots library into your project:
Code:
compile 'com.pushbots:pushbots-lib:[email protected]'
compile 'com.android.support:support-v4:21.0.0'
Re-build your project and wait for gradle to finish.
Step 2: Update AndroidManifest.xml file:
Add the following permessions and change com.example.sampleapp with your app identifier.
Code:
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission android:name="com.example.sampleapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.example.sampleapp.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive dataf message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
The following intent-filter in your main activity:
Code:
<intent-filter>
<action android:name="com.example.sampleapp.MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Add the following activity, reciever and service before the end of your application tag, and in all of the above code change com.example.sampleapp with your app identifier.
Code:
<receiver
android:name="com.pushbots.google.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.sampleapp" />
</intent-filter>
</receiver>
<receiver android:name="com.pushbots.push.DefaultPushHandler" />
<service android:name="com.pushbots.push.GCMIntentService" />
Step 3: Creating pushbots.xml config file:
Go to Res folder -> Values --> Right click and new Resource File and name it pushbots with this content. Change your app ID and Sender ID.
Code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Pushbots Application ID -->
<string name="pb_appid">548ef5901d0ab1</string>
<!-- GCM Sender ID -->
<string name="pb_senderid">48849973</string>
<!-- Pushbots Log Level log Tag "PB2" -->
<string name="pb_logLevel">DEBUG</string>
</resources>
Step 4: Add required code:
in your main Activity add this line:
Code:
Pushbots.sharedInstance().init(this);
That's pretty much it. Run your application now, if all goes well, your device should be registered and ready to recieve push notifications.
Step 5: Custom handler for notifications (Optional):
5.1. Create customHandler class.
Code:
public class customHandler extends BroadcastReceiver
{
private static final String TAG = "customHandler";
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
Log.d(TAG, "action=" + action);
// Handle Push Message when opened
if (action.equals(PBConstants.EVENT_MSG_OPEN)) {
//Check for Pushbots Instance
Pushbots pushInstance = Pushbots.sharedInstance();
if(!pushInstance.isInitialized()){
Log.d("Initializing Pushbots.");
Pushbots.sharedInstance().init(context.getApplicationContext());
}
//Clear Notification array
if(PBNotificationIntent.notificationsArray != null){
PBNotificationIntent.notificationsArray = null;
}
HashMap<?, ?> PushdataOpen = (HashMap<?, ?>) intent.getExtras().get(PBConstants.EVENT_MSG_OPEN);
Log.w(TAG, "User clicked notification with Message: " + PushdataOpen.get("message"));
//Report Opened Push Notification to Pushbots
if(Pushbots.sharedInstance().isAnalyticsEnabled()){
Pushbots.sharedInstance().reportPushOpened( (String) PushdataOpen.get("PUSHANALYTICS"));
}
//Start lanuch Activity
String packageName = context.getPackageName();
Intent resultIntent = new Intent(context.getPackageManager().getLaunchIntentForPackage(packageName));
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK);
resultIntent.putExtras(intent.getBundleExtra("pushData"));
Pushbots.sharedInstance().startActivity(resultIntent);
// Handle Push Message when received
}else if(action.equals(PBConstants.EVENT_MSG_RECEIVE)){
HashMap<?, ?> PushdataOpen = (HashMap<?, ?>) intent.getExtras().get(PBConstants.EVENT_MSG_RECEIVE);
Log.w(TAG, "User Received notification with Message: " + PushdataOpen.get("message"));
}
}
}
5.2. Open AndroidManifest.xml and replace DefaultPushHandler with your custom Handler class.
Code:
<receiver android:name="PACKAGE_NAME.customHandler" />
5.3. Set your customHandler class in MainActivity.
Code:
Pushbots.sharedInstance().setCustomHandler(customHandler.class);
Pls hit the thanks button if i helped you :angel:
For more information-Visit: http://androidtechfreakat.blogspot.in
http://androidtechxdaat,weebly.com
http://advaitt17.github.io
XDA:DevDB Information
[GUIDE]To make a Push Notificaton App via GCM Service by AdvaitT17, App for all devices (see above for details)
Contributors
AdvaitT17, PushBots Developers
Source Code: www.pushbots.com
Version Information
Status: Stable
Created 2016-04-06
Last Updated 2016-05-20
Reserved
If there are any doubts about this process yoi can PM me on Xda
Hello everybody,
I've been watching thenewboston's Android App Development series on youtube and its been pretty helpful, but I've had several situations where I'll get some sort of error and I have no idea what to do. I've tried searching forums, downloading more components with jdk, all to no avail.
My most recent issue is upon initiating a new activity, I get an error saying RelativeLayout needs LayoutHeight and LayoutWidth to be defined; but they are defined in the xml file.
I'm posting from my phone right now, tomorrow I'll follow up with a screen shot.
It really gets me down when I'm trying to be excited about learning something new and on my own, but I experience so many road bumps that I have no idea how to fix or solve. :crying:
Details of the issue
Error Displayed:
Rendering Problems NOTE: One or more layouts are missing the layout_width or layout_height attributes. These are required in most layouts. <RelativeLayout> does not set the required layout_width attribute: ****Set to wrap_content, Set to match_parent <RelativeLayout> does not set the required layout_height attribute: ****Set to wrap_content, Set to match_parent Or: Automatically add all missing attributes
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns="http//schemasandroidcom/apk/res/android"
xmlns:app="http//schemasandroidcom/apk/res-auto"
xmlns:tools="http//schemasandroidcom/tools"
xmlns:android="AndroidDomInspection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
androidaddingBottom="@dimen/activity_vertical_margin"
androidaddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="comeric522.facebook.example2.MainActivity"
tools:showIn="@layout/activity_main" />
</RelativeLayout>
Other notes: automatically add all missing attributes doesn't work; wrap_content or match_parent doesn't work either.
'.' and ':' removed in between schemasandroidcom because I'm getting flagged for spam
I'm also getting these errors on the xml, and I don't understand why; I haven't done anything yet it's system generated:
Element RelativeLayout doesn't have required attribute layout_height Element RelativeLayout doesn't have required attribute layout_width 'layout_height' attribute should be defined less... (Ctrl+F1)
Validates resource references inside Android XML files.
'layout_width' attribute should be defined less... (Ctrl+F1)
Validates resource references inside Android XML files.