Hello, this is Chris talking, your fellow Time Keeper (yeah, I was nicknamed) and this is my tutorial on how to build a simple, lightweight analog clock!
______________________________________________________________
This guide assumes that you have successfully set up the Android SDK, ADT, Eclipse, some basic Java knowledge and image editing skills.
_______________________________________________________________
Let's start!
Go to the menu bar and click File > New > Android Project
Give your project a name, such as "XDA Devs Clock". Anything you prefer. This isn't going to affect the final app.
Next, select Android 1.6 as the build target. Analog clocks don't require anything special.
Now it's time to create the package name. I usually make mine like "com.xda.clock.chris".
Untick the "Create Activity" checkbox.
Info: We don't need to create an Activity because we are making a widget. Widgets don't have Activities, otherwise, they would be shown in the app drawer.
Click Finish and Eclipse will set up the project.
{
"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"
}
________________________________________________________________
Next up, you need to make 3 images for the clock:
The dial (which is the clock's background)
The hour's hand
The minute's hand
Use your incredible Photoshop/GIMP/Illustrator skills to make your awesome clock!
Few tips:
Make the canvas 300*300 pixels
Make the dial with 10% padding
To easily make the hands, keep the dial background and draw the hour's and minute's hand as they were at position zero (Hour at 12 o'clock and minute at zero). Erase the dial and save each hand image
Save with a .png extension. So, in the end, you will have 3 images. Name them:
hand_dial.png
hand_minute.png
hand_hour.png
All lower case. It is extremely important or else you will get an error!
Also, create an app icon. You need to make 3 different ones for every screen size.
HDPI - 72*72 px
MDPI - 48*48 px
LDPI - 36*36 px
Save them with the name "ic_launcher.png" and overwrite the images that are already in the project's respective folders.
________________________________________________________________
Following, we gotta put them to our app.
So, first, right-click res > New > New folder and name it "drawable".
Drag your images you created previously into there.
Now, let's make the layout of the clock.
Go to res > layout > main.xml
Go to the main.xml tab (at the bottom) and delete the TextView block. Next, change the layout from Linear to Relative.
Now, we will add the clock's code.
Code:
<AnalogClock
android:id="@+id/analogClock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:dial="@drawable/hand_dial"
android:hand_minute="@drawable/hand_minute"
android:hand_hour="@drawable/hand_hour"/>
So, what did we do there?
We gave the item an id
We put it in the middle of the screen
We redirected the drawables to the respective hand and dial
The final xml is this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<AnalogClock
android:id="@+id/analogClock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:dial="@drawable/hand_dial"
android:hand_minute="@drawable/hand_minute"
android:hand_hour="@drawable/hand_hour"/>
</RelativeLayout>
_______________________________________________________________
Next, we need to tell Android that what we are actually doing is a widget.
Right click res and create a folder named "xml".
Right clock xml > New > Android XML file
Change the Resource Type to AppWidgetProvider and give it a name such as "widget_config.xml". Lower case!
Delete everything and paste this in:
Code:
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="140dip"
android:minHeight="140dip"
android:updatePeriodMillis="0"
android:initialLayout="@layout/main"/>
There we set how many rows the widget will take. The calculation method is
74 * [number of rows] - 4
We want the widget to be 2*2 so the width is 146dip and the height is also 146dip. But we'll change it to 140 to make it a little bigger.
Then we set an update period... which actually doesn't work below 30 minutes. It's a bug in Android and last, we gave it a layout, which we made previously (main.xml).
____________________________________________________________
Now, we must declare the widget in the manifest.xml with a <receiver> element.
Open the manifest xml and delete the <activity> block. As said previously, we won't have any activity.
Inside the <application> add this piece of code:
Code:
<receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
</receiver>
The android:name is the class we are going to create in a few minutes.
The label is the name that will be shown in the widget picker of your homescreen. Then we specified the update and linked the widget_config.xml
The final xml is:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xda.clock.chris"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
</receiver>
</application>
</manifest>
_______________________________________________________________
Now it's time to create the Clock_Actions class.
Right click the package > New > Class
Give it the above name.
Delete everything and paste this in:
Code:
package com.xda.clock.chris;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.widget.RemoteViews;
public class Clock_Actions extends AppWidgetProvider{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
PendingIntent pendingIntent;
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
{
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.main);
pendingIntent = PendingIntent.getActivity(context, 0,getAlarmPackage(context), 0);
views.setOnClickPendingIntent(R.id.analogClock1, pendingIntent);
AppWidgetManager
.getInstance(context)
.updateAppWidget(
intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS),
views);
}
}
public Intent getAlarmPackage(Context context)
{
PackageManager packageManager = context.getPackageManager();
Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
String clockImpls[][] = {
{ "Standard Alarm", "com.android.alarmclock",
"com.android.alarmclock.AlarmClock" },
{ "HTC Alarm ClockDT", "com.htc.android.worldclock",
"com.htc.android.worldclock.WorldClockTabControl" },
{ "Standard Alarm ClockDT", "com.android.deskclock",
"com.android.deskclock.AlarmClock" },
{ "Froyo Nexus Alarm ClockDT",
"com.google.android.deskclock",
"com.android.deskclock.DeskClock" },
{ "Moto Blur Alarm ClockDT",
"com.motorola.blur.alarmclock",
"com.motorola.blur.alarmclock.AlarmClock" },
{ "Samsung Galaxy S", "com.sec.android.app.clockpackage",
"com.sec.android.app.clockpackage.ClockPackage" } };
boolean foundClockImpl = false;
for (int i = 0; i < clockImpls.length; i++)
{
String packageName = clockImpls[i][1];
String className = clockImpls[i][2];
try
{
ComponentName cn = new ComponentName(packageName, className);
packageManager.getActivityInfo(cn,PackageManager.GET_META_DATA);
AlarmClockIntent.setComponent(cn);
foundClockImpl = true;
} catch (NameNotFoundException nf)
{
}
}
if (foundClockImpl)
{
return AlarmClockIntent;
}
else
{
return null;
}
}
}
Change the package name to your own after pasting.
So here, we set up the update, the remote views and the pending intent which redirects you to the Desk Clock app. Because different phones have different Desk Clock package names, we set up a method to handle that.
Many thanks to sndytime. Got the code from his post here.
____________________________________________________________
Next up...nothing! Our clock is done! We just have to export it.
Right click the project > Android tools > Export signed application
Choose next, select Create new keystore > click browse and give it a name.
Create a password and click next.
In alias put whatever you want. I usually put "chris95x8"
Enter your password again and put, like, 100 year for validity. You get the rest.
Click Next, browse and enter a name for the apk.
Click Finish and congrats on your first analog clock! Yay!
If you have done everything right it should work. Otherwise, comment here on the thread.
*Sorry for big images
______________________________________________________________
I hope to see some clock on the Themes & Apps section soon. Good luck everyone!
Exelent guide buddy
Another score for successful guides
W!LßSO @ XDA
Thanks Chris.
Will come in handy.
-----------------
- Swift -, formerly known as IrishStuff09
Thank you Chris !
Sent from my X8 using xda premium
great tutorial buddy!
getting right to do the job!
I made one sometime ago but all ended when started to add settings
Anything didnt work anymore from then on
Lol interesting, thanks.
Too fun ! Thank you dude !
Great Job Chriss, nice and clear. However I still menaged to get stuck.
Now it's time to create the Clock_Actions class.
Right click the package > New > Class
Click to expand...
Click to collapse
Where/what should I right click?
For now I created in in src folder in (default package), but I get 3 errors, so I assume I did it wrong.
Anyway tutorial looks great
Chris95X8 said:
Hello, this is Chris talking, your fellow Time Keeper (yeah, I was nicknamed) and this is my tutorial on how to build a simple, lightweight analog clock!
______________________________________________________________
This guide assumes that you have successfully set up the Android SDK, ADT, Eclipse, some basic Java knowledge and image editing skills.
_______________________________________________________________
Let's start!
Go to the menu bar and click File > New > Android Project
Give your project a name, such as "XDA Devs Clock". Anything you prefer. This isn't going to affect the final app.
Next, select Android 1.6 as the build target. Analog clocks don't require anything special.
Now it's time to create the package name. I usually make mine like "com.xda.clock.chris".
Untick the "Create Activity" checkbox.
Info: We don't need to create an Activity because we are making a widget. Widgets don't have Activities, otherwise, they would be shown in the app drawer.
Click Finish and Eclipse will set up the project.
________________________________________________________________
Next up, you need to make 3 images for the clock:
The dial (which is the clock's background)
The hour's hand
The minute's hand
Use your incredible Photoshop/GIMP/Illustrator skills to make your awesome clock!
Few tips:
Make the canvas 300*300 pixels
Make the dial with 10% padding
To easily make the hands, keep the dial background and draw the hour's and minute's hand as they were at position zero (Hour at 12 o'clock and minute at zero). Erase the dial and save each hand image
Save with a .png extension. So, in the end, you will have 3 images. Name them:
hand_dial.png
hand_minute.png
hand_hour.png
All lower case. It is extremely important or else you will get an error!
Also, create an app icon. You need to make 3 different ones for every screen size.
HDPI - 72*72 px
MDPI - 48*48 px
LDPI - 36*36 px
Save them with the name "ic_launcher.png" and overwrite the images that are already in the project's respective folders.
________________________________________________________________
Following, we gotta put them to our app.
So, first, right-click res > New > New folder and name it "drawable".
Drag your images you created previously into there.
Now, let's make the layout of the clock.
Go to res > layout > main.xml
Go to the main.xml tab (at the bottom) and delete the TextView block. Next, change the layout from Linear to Relative.
Now, we will add the clock's code.
Code:
<AnalogClock
android:id="@+id/analogClock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:dial="@drawable/hand_dial"
android:hand_minute="@drawable/hand_minute"
android:hand_hour="@drawable/hand_hour"/>
So, what did we do there?
We gave the item an id
We put it in the middle of the screen
We redirected the drawables to the respective hand and dial
The final xml is this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<AnalogClock
android:id="@+id/analogClock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:dial="@drawable/hand_dial"
android:hand_minute="@drawable/hand_minute"
android:hand_hour="@drawable/hand_hour"/>
</RelativeLayout>
_______________________________________________________________
Next, we need to tell Android that what we are actually doing is a widget.
Right click res and create a folder named "xml".
Right clock xml > New > Android XML file
Change the Resource Type to AppWidgetProvider and give it a name such as "widget_config.xml". Lower case!
Delete everything and paste this in:
Code:
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="146dip"
android:updatePeriodMillis="0"
android:initialLayout="@layout/main"/>
There we set how many rows the widget will take. The calculation method is
74 * [number of rows] - 4
We want the widget to be 2*2 so the width is 146dip and the height is also 146dip.
Then we set an update period... which actually doesn't work below 30 minutes. It's a bug in Android and last, we gave it a layout, which we made previously (main.xml).
____________________________________________________________
Now, we must declare the widget in the manifest.xml with a <receiver> element.
Open the manifest xml and delete the <activity> block. As said previously, we won't have any activity.
Inside the <application> add this piece of code:
Code:
<receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
</receiver>
The android:name is the class we are going to create in a few minutes.
The label is the name that will be shown in the widget picker of your homescreen. Then we specified the update and linked the widget_config.xml
The final xml is:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xda.clock.chris"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
</receiver>
</application>
</manifest>
_______________________________________________________________
Now it's time to create the Clock_Actions class.
Right click the package > New > Class
Give it the above name.
Delete everything and paste this in:
Code:
package com.xda.clock.chris;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.widget.RemoteViews;
public class Clock_Actions extends AppWidgetProvider{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
PendingIntent pendingIntent;
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
{
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.main);
pendingIntent = PendingIntent.getActivity(context, 0,getAlarmPackage(context), 0);
views.setOnClickPendingIntent(R.id.analogClock1, pendingIntent);
AppWidgetManager
.getInstance(context)
.updateAppWidget(
intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS),
views);
}
}
public Intent getAlarmPackage(Context context)
{
PackageManager packageManager = context.getPackageManager();
Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
String clockImpls[][] = {
{ "Standard Alarm", "com.android.alarmclock",
"com.android.alarmclock.AlarmClock" },
{ "HTC Alarm ClockDT", "com.htc.android.worldclock",
"com.htc.android.worldclock.WorldClockTabControl" },
{ "Standard Alarm ClockDT", "com.android.deskclock",
"com.android.deskclock.AlarmClock" },
{ "Froyo Nexus Alarm ClockDT",
"com.google.android.deskclock",
"com.android.deskclock.DeskClock" },
{ "Moto Blur Alarm ClockDT",
"com.motorola.blur.alarmclock",
"com.motorola.blur.alarmclock.AlarmClock" },
{ "Samsung Galaxy S", "com.sec.android.app.clockpackage",
"com.sec.android.app.clockpackage.ClockPackage" } };
boolean foundClockImpl = false;
for (int i = 0; i < clockImpls.length; i++)
{
String packageName = clockImpls[i][1];
String className = clockImpls[i][2];
try
{
ComponentName cn = new ComponentName(packageName, className);
packageManager.getActivityInfo(cn,PackageManager.GET_META_DATA);
AlarmClockIntent.setComponent(cn);
foundClockImpl = true;
} catch (NameNotFoundException nf)
{
}
}
if (foundClockImpl)
{
return AlarmClockIntent;
}
else
{
return null;
}
}
}
Change the package name to your own after pasting.
So here, we set up the update, the remote views and the pending intent which redirects you to the Desk Clock app. Because different phones have different Desk Clock package names, we set up a method to handle that.
Many thanks to sndytime. Got the code from his post here.
____________________________________________________________
Next up...nothing! Our clock is done! We just have to export it.
Right click the project > Android tools > Export signed application
Choose next, select Create new keystore > click browse and give it a name.
Create a password and click next.
In alias put whatever you want. I usually put "chris95x8"
Enter your password again and put, like, 100 year for validity. You get the rest.
Click Next, browse and enter a name for the apk.
Click Finish and congrats on your first analog clock! Yay!
If you have done everything right it should work. Otherwise, comment here on the thread.
*Sorry for big images
______________________________________________________________
I hope to see some clock on the Themes & Apps section soon. Good luck everyone!
Click to expand...
Click to collapse
U awe from me a thanks and a beer.. N1 bro.. :beer::thumbup:
Sent from my GT-S6102 using xda premium
west1988 said:
Great Job Chriss, nice and clear. However I still menaged to get stuck.
Where/what should I right click?
For now I created in in src folder in (default package), but I get 3 errors, so I assume I did it wrong.
Anyway tutorial looks great
Click to expand...
Click to collapse
Stupid me. It shouldn't be a default package, but a one with my unique name that I needed to create
Great lesson and I have my very own clock now
west1988 said:
Stupid me. It shouldn't be a default package, but a one with my unique name that I needed to create
Great lesson and I have my very own clock now
Click to expand...
Click to collapse
Will you post it?
Sent from my HTC One S
It is just a photo of my old friends and me as a dial of the clock, so nothing fancy
Hi,How to add second to it?
Hello.Thank you for this great tutorial.I'm beginner and i have problem with clock.When i use clock with some of launchers Go Launcher,Apex launcher.. when restert phone i get error-Problem loading widget.Pleace help me.Sorry for my English
so how to add date & weather to it ?
Cant find main xml
First off, wonderful tutorial! Thanks :good:
So, forgive my n00bness please. I've never fully taken on the world of designing apps or widgets so much of this is new to me. I set everything up according to directions but have gotten stuck looking for the main xml file. After an hour or so of looking, and looking... and looking, I CAN NOT for the life of me seem to locate it anywhere. I have downloaded the most recent ADT package ( build: v21.0.0-519525 ) and it's running Eclipse 3.8. I've included a screenshot. Not sure if I've done something wrong or what, but I'm guessing it's most likely in plain sight. I am just not sure where to begin to look! Any help would be awesome, I have a slew of custom new clocks I feel the Android community would love :fingers-crossed:
EDIT: I've gone through and manually added an Android XML Layout file to the layout folder with the name of main.xml. After doing this I've gone through and followed step by step everything to the T. Everything checks out in the end after exporting, and even installs correctly. However, it does not show up in my widgets list or App drawer, and when trying to launch it from a file manager it says it cannot be launched.
Help!
WORKING!
D4RRYLJ4RVIS said:
First off, wonderful tutorial! Thanks :good:
So, forgive my n00bness please. I've never fully taken on the world of designing apps or widgets so much of this is new to me. I set everything up according to directions but have gotten stuck looking for the main xml file. After an hour or so of looking, and looking... and looking, I CAN NOT for the life of me seem to locate it anywhere. I have downloaded the most recent ADT package ( build: v21.0.0-519525 ) and it's running Eclipse 3.8. I've included a screenshot. Not sure if I've done something wrong or what, but I'm guessing it's most likely in plain sight. I am just not sure where to begin to look! Any help would be awesome, I have a slew of custom new clocks I feel the Android community would love :fingers-crossed:
EDIT: I've gone through and manually added an Android XML file to the layout folder with the name of main.xml. After doing this I've gone through and followed step by step everything to the T. Everything checks out in the end after exporting, and even installs correctly. However, it does not show up in my widgets list or App drawer, and when trying to launch it from a file manager it says it cannot be launched.
Help!
Click to expand...
Click to collapse
NEVERMIND! Ran into the same problem as West1988. Changed the package name to the unique name selected in the beginning of the project and, voila! LAZR CLOCK! I'll be posting this on the Play store soon for anyone to download. Thanks Chris!
Oh, glad you sorted it out. And my God! Awesome clock man!!!
Sent from my HTC One S using xda app-developers app
Thanks for this tut Chris!
I made one but I was really bored to make good graphs...but it works!!!!
Sent from my X8 using xda premium
I am attempting to replace the data an app* stores in an XML resource, and I can't figure out how to make it work. I followed the tutorial, but it only covers things like "drawable" (and the simple types like string and integer)
I have tried various combinations of compiled or textual XML, with the file in res/xml or res/raw, and so far have not found anything that had any effect on the app, while my module never reports any errors! (at least not in any log I've found)
*The app is Swype, I'm attempting to replace one of the English keyboard layouts (qwerty, azerty, or qwertz) with a completely new one I saw that's actually good for the sliding entry method instead of a slide left on the top row being at least 14 different possible words (Seriously, I made a list) including some very commonly needed ones like it, or, out, and our. The layouts are** stored in xml files such as res/xml/kbd_azerty_panlatin.xml but even attempting a single letter swap hasn't done anything yet.
So, what do I need to do to make a line like
Code:
resParam.res.setReplacement(resParam.packageName, "xml", "kbd_azerty_panlatin", xrf);
actually work? (xrf is from
Code:
XResForwarder xrf = modRes.fwd(R.raw.kbd_azerty_panlatin);
as of my last attempt. modRes is as per the tutorial) and that file is in the last attempt compiled by creating a new Swype apk with the modification via apktool then just grabbing it from there.)
**Note that actually attempting to run recompiled Swype APKs -- modded or not -- fails with a crash when the keyboard would appear, so I can't actually confirm that I'm right about the location of the layouts I need to change, but it seems to be reasonable that they are where I think. I also have No idea how to link them to the language options, so I can't see a way to create a new one instead of replacing an existing.
bump, I'm curious too
edit: if you scroll down on the tutroial page, it covers modifying xml layouts
ssojyeti2 said:
... if you scroll down on the tutroial page, it covers modifying xml layouts
Click to expand...
Click to collapse
It doesn't give much detail and since layouts are a separate type, it might not apply anyway.
I really hope it's not right about me needing to include All the xml files in the app just to make one work. I suppose I should try it anyway.
ok i was able to successfully replace an xml file in snapchat using xposed, although it caused snapchat to fc, but i think thats on the app itself. i basically copied the code on the tutorial word for word lol
Code:
package com.joss.geofilter;
import android.content.res.XModuleResources;
import de.robv.android.xposed.IXposedHookInitPackageResources;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam;
public class GeoResize implements IXposedHookZygoteInit, IXposedHookInitPackageResources {
private static String MODULE_PATH = null;
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
MODULE_PATH = startupParam.modulePath;
}
@Override
public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable {
if (!resparam.packageName.equals("com.snapchat.android"))
return;
XModuleResources modRes = XModuleResources.createInstance(MODULE_PATH, resparam.res);
resparam.res.setReplacement("com.snapchat.android", "layout", "battery_view", modRes.fwd(R.raw.battery_view));
}
}
because i put it in /raw, i had to compile the xml first using apktool and swap it into the xposed module using 7zip afterwards
I'm late, but i think you've misunderstand some things. For example, you can't mod Swype, not like you do here.
I give you an example. I've this xml file:
Code:
<resources>
<color name="white">#ff000000</color>
<color name="common_signin_btn_default_background">#ff000000</color>
</resources>
(taken from Twitter app)
I want to change that values. You can't replace the entire xml, but you can create an xml, name it like you want (xda.xml will work) and put in it:
Code:
<resources>
<color name="white">THE COLOR YOU WANT</color>
<color name="common_signin_btn_default_background">THE OTHER COLOR YOU WANT</color>
</resources>
and you put that file into res/values of your Xposed app. You've not to write all entries, you write only those you want to change. Now, you have to write the code that does the magic:
Code:
import android.content.res.XModuleResources;
import de.robv.android.xposed.IXposedHookInitPackageResources;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam;
public class Main implements IXposedHookZygoteInit, IXposedHookInitPackageResources {
private static String MODULE_PATH = null;
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
MODULE_PATH = startupParam.modulePath;
}
@Override
public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable {
if (!resparam.packageName.equals("com.twitter.android"))
return;
XModuleResources modRes = XModuleResources.createInstance(MODULE_PATH, resparam.res);
resparam.res.setReplacement("com.twitter.android", "color", "white", modRes.fwd(R.color.white));
resparam.res.setReplacement("com.twitter.android", "color", "faint_transparent_white", modRes.fwd(R.color.faint_transparent_white));
}
}
So, into 'resparam.res.setReplacement' you don't put the xml name, but you put the resource name. In this case, the color's name. So, if in your xml you have:
Code:
<resources>
<color name="forum">THE COLOR YOU WANT</color>
</resources>
you will use:
Code:
resparam.res.setReplacement("com.twitter.android", "color", "white", modRes.fwd(R.color.forum));
And that changes the color 'white' of Twitter app, into the color 'forum', that you've defined into your xlm xda.xml ('THE COLOR YOU WANT' here).
For layout, that is a bit different...
Ok sorry, my last post here is not totally correct. The way used in the first post should work, but it doesn't. Has someone find a solution?
P.S. The example of snapchat is a bit different, probably, because it uses 'layout'.
P.S.2 This thread should be moved in the 'Xposed' section...
robertogl said:
I'm late, but i think you've misunderstand some things. For example, you can't mod Swype, not like you do here.
I give you an example. I've this xml file:
Code:
<resources>
<color name="white">#ff000000</color>
<color name="common_signin_btn_default_background">#ff000000</color>
</resources>
(taken from Twitter app)
I want to change that values. You can't replace the entire xml, but you can create an xml, name it like you want (xda.xml will work) and put in it:
Code:
<resources>
<color name="white">THE COLOR YOU WANT</color>
<color name="common_signin_btn_default_background">THE OTHER COLOR YOU WANT</color>
</resources>
and you put that file into res/values of your Xposed app. You've not to write all entries, you write only those you want to change. Now, you have to write the code that does the magic:
Code:
import android.content.res.XModuleResources;
import de.robv.android.xposed.IXposedHookInitPackageResources;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam;
public class Main implements IXposedHookZygoteInit, IXposedHookInitPackageResources {
private static String MODULE_PATH = null;
@Override
public void initZygote(StartupParam startupParam) throws Throwable {
MODULE_PATH = startupParam.modulePath;
}
@Override
public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable {
if (!resparam.packageName.equals("com.twitter.android"))
return;
XModuleResources modRes = XModuleResources.createInstance(MODULE_PATH, resparam.res);
resparam.res.setReplacement("com.twitter.android", "color", "white", modRes.fwd(R.color.white));
resparam.res.setReplacement("com.twitter.android", "color", "faint_transparent_white", modRes.fwd(R.color.faint_transparent_white));
}
}
So, into 'resparam.res.setReplacement' you don't put the xml name, but you put the resource name. In this case, the color's name. So, if in your xml you have:
Code:
<resources>
<color name="forum">THE COLOR YOU WANT</color>
</resources>
you will use:
Code:
resparam.res.setReplacement("com.twitter.android", "color", "white", modRes.fwd(R.color.forum));
And that changes the color 'white' of Twitter app, into the color 'forum', that you've defined into your xlm xda.xml ('THE COLOR YOU WANT' here).
For layout, that is a bit different...
Click to expand...
Click to collapse
what about editing strings? in an apps xml?
devzeus_ke said:
what about editing strings? in an apps xml?
Click to expand...
Click to collapse
Too many years have passed to remember that
robertogl said:
Too many years have passed to remember that
Click to expand...
Click to collapse
Oww. I am actually getting started with android development and i am also learning how the system itself works. However i haven't found an example to edit a string resource in an app. I only find examples on how to edit systemui resources. Any help with finding that?
devzeus_ke said:
Oww. I am actually getting started with android development and i am also learning how the system itself works. However i haven't found an example to edit a string resource in an app. I only find examples on how to edit systemui resources. Any help with finding that?
Click to expand...
Click to collapse
Note that this 'replacement' only works with the Xposed framework.
robertogl said:
Note that this 'replacement' only works with the Xposed framework.
Click to expand...
Click to collapse
actually i meant over writing. Like changing string values
Introduction
When you integrate Nearby Service into your apps, they'll be able to transmit files between smart devices without using mobile data. The service uses Huawei's own protocols, and the integration process is quick and easy.
Many mobile apps need to transmit files between devices. Social networking apps transmit images, files, and chat records; file management apps transmit files, data backups, and cloned phone data; and audio and video apps transmit songs and videos. To achieve this, these apps have to rely on web disks and cloud servers, which means users have to either use their own mobile data or be connected to Wi-Fi. Previously, implementing near-field data transmissions backed by Bluetooth or Wi-Fi required complex network protocols and hardware devices, and the transmission rate was average. Now, thanks to Nearby Service, this is easier and more effective than ever.
Advantages of Using Nearby Service
1. Easy integration: You only need two file transmission APIs to integrate Nearby Service, and it doesn't require any complex network protocols.
2. Ultra-fast transmission: It achieves file transmission rate of up to 60 MB/s, so transmitting a 1 GB file takes only 20 seconds.
3. Offline transmission: Nearby Service doesn't require routers or any other network devices. Data is transmitted through Bluetooth and Wi-Fi, so it doesn't consume the user's mobile data.
4. Platform support: The service supports all Android platforms, and will work with other platforms soon.
Demo (NearbyTransfer)
Here, take NearbyTransfer as an example. You can see how NearbyTransfer uses QR codes to transmit files between devices. NearbyTransfer has integrated with Nearby Service and Scan Kit.
NearbyTransfer Development
You can find the open source code for NearbyTransfer on GitHub.
Now, I'll show you how to create the demo based on the source code, so that you can better understand the implementation process.
Preparations
Tools
1. Two Huawei phones (recommended)
2. Android Studio (3.X or later)
Register as a Developer
Register as a Huawei developer.
Create an App
Create an app on Huawei AppGallery. For details, please refer to HUAWEI Developers-App Development.
Create a Demo
• Import the source code to Android Studio (3.X or Later).
• Download the agconnect-services.json file for the new demo, and save it on your local computer in the app directory (\app) of the sample code.
Run the Demo
3. Install the demo on test devices A and B.
4. Tap Send File on device A and select the file you want to transmit. A QR code will be generated.
5. Tap Receive File on device B.
6. Wait until the file transmission is complete.
Let's see the demo effect!
https://www.reddit.com/r/HMSCore/comments/jj1o9z/how_to_implement_highspeed_datafree_file/
Code Development
Add Huawei Maven Repository to the Project-Level build.gradle File of Your Project
Add the following Maven address to the build.gradle file in the root directory of your Android Studio project:
HTML:
buildscript {
repositories {
maven { url 'http://developer.huawei.com/repo/'}
} }allprojects {
repositories {
maven { url 'http://developer.huawei.com/repo/'}
}}
Add SDK Dependencies to the App-Level build.gradle File
HTML:
dependencies {
implementation 'com.huawei.hms:nearby:5.0.2.300'
implementation 'com.huawei.hms:scan:1.2.3.300'
}
Declare the System Permission in the AndroidManifest.xml File
Nearby Service is implemented based on Bluetooth, Wi-Fi, storage, and location information, so the corresponding permissions need to be declared. (The barcode scanning permission is to be added.)
HTML:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--Camera permission-->
<uses-permission android:name="android.permission.CAMERA" />
The ACCESS_FINE_LOCATION, WRITE_EXTERNAL_STORAGE, and READ_EXTERNAL_STORAGE permissions are dangerous system permissions, so you need to apply for them dynamically. If your app does not have these permissions, Nearby Service will not let it broadcast or scan.
Key Code
Main code path: com\huawei\hms\simpleNearbyDemo\MainActivity.java
If you want to integrate Nearby Service's file transmission function, take MainActivity for reference and integrate nearbyAgent.sendFile() and nearbyAgent.receiveFile() into your app.
1. Sending a file.
The sender selects a file and calls nearbyAgent.sendFile(uri) to send the file.
[HTML @override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case FILE_SELECT_CODE:
if (resultCode == RESULT_OK) {
// Get the URI of the selected file.
Uri uri = data.getData();
nearbyAgent.sendFile(uri);
}
break;
case NearbyAgent.REQUEST_CODE_SCAN_ONE:
nearbyAgent.onScanResult(data);
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
[/HTML]
2. Receiving a file.
The receiver calls nearbyAgent.onScanResult(data) to receive a file.
HTML:
recvBtn.setOnClickListener(new View.OnClickListener() {
[user=439709]@override[/user]
public void onClick(View v) {
nearbyAgent.receiveFile();
}
});
References
Official Huawei Developers website:
https://developer.huawei.com/consumer/en/hms/huawei-pushkit
Development Guide:
https://developer.huawei.com/consum...-Guides/service-introduction-0000001050040060
Official HMS Core community on Reddit:
https://www.reddit.com/r/HuaweiDevelopers/
Demo and sample code:
https://github.com/HMS-Core
Discussions on Stack Overflow:
https://stackoverflow.com/questions/tagged/huawei-mobile-services?tab=Newest
If you have any needs or suggestions, please contact us:
[email protected]