I. Summary
For a long time did not write blog, before the change of a company. The work is more combat-fighting, but unfortunately there is no time to write articles. In this period of time in fact encountered a lot of problems, but all are recorded, and did not take the time to study the solution. But there's no way I can move on this week. Must be recorded. To be used by posterity. Not much to say, into the subject.
Second, the premise
1. Understanding of GA (Google for yourself)
2, to the Campaigntrackingreceiver class Understanding, he is when downloaded from the GP and installs the completion of an app, send a broadcast, will carry some data in the intent, is generally refer value, here can distinguish from where to download , a simple example: A application is a application I need to post to GP, but we may be promoting a on various channels, so we may need to add a channel number to the statistics, so this time we need a campaigntrackingreceiver broadcast receiver in a application, Then processing the received broadcast of the content of the intent, parse out the specific channel number, to escalate. So it's strange that GP sends this broadcast, he sends this broadcast, and then when we install a and run it, we can receive the broadcast, which is equal to the broadcast, and he waits for a receiver to accept him.
3, this article needs to use the tool: http://download.csdn.net/detail/jiangwei0910410003/8679153, after downloading, first should look at the TXT document in the description.
Third, the problem description
The project has access to GA statistics (an SDK for Google's app stats), but we may need to count the statistics the app downloads from GP (this is usually a campaigntrackingreceiver broadcast), But the problem is that the GA SDK already contains the Campaigntrackingreceiver class, when the time to get into a misunderstanding: that is, if the app wants to receive this broadcast. The package name of the broadcast receiver must be: Com.google.analytics.tracking.android, class name: Campaigntrackingreceiver, similar to the following registration code:
<receiverandroid:name= "Com.google.analytics.tracking.android.CampaignTrackingReceiver" android:exported= " True "><intent-filter> <action android:name=" Com.android.vending.INSTALL_REFERRER "/></ Intent-filter></receiver>
But then found that do not need this, as long as the package name can be, in fact, the mechanism of sending broadcasts from Android can be known. The class name is not related, but there is no way to test this thing (need to publish a test app to GP, time is not allowed, can only listen to predecessors). Finally also published a test app test to know, do not need the same class name, this is a kind of harvest, then since the class name is different, here is no problem. will not be duplicated with the classes in Ga. But I have solved this problem in a different way before explaining the misunderstanding. Now that we have this broadcast-receiving class in GA, we can't define it, we can insert a piece of code in the broadcast class in its SDK: send a broadcast and bring the data out of the intent. Ideas have, the following look at the specific operation:
Iv. introduction of Technology
The following content is based on the above misunderstanding is not explained in the case, and the focus is not to explain the misunderstanding. But how to modify the contents of the jar
Let's start by talking about the three roles in this process:Jar,dex,smali
Four tools: Dx.bat,dex2jar.bat,baksmali.jar,smali.jar
The diagram is as follows:
We need to modify the code in the jar here,
First, there are a number of ways to modify the code in the jar:
1. Open the class file in the jar directly with the Compress package tool to modify it (unless you are familiar with the instruction set, I do not want to try anyway)
2, using the Jd-gui tool to open the jar directly, to modify (although this can read the code, but there is a problem is that if the code is confused, the difficulty is not as good as the first method, so there is no attempt)
OK, so the third way is to modify the Smali file, the advantage of this file is: The instruction is simple, and if confused, it is not related. For instructions on Smail, you can Google it yourself. It's easy to explain here.
So the question is, how do you turn the jar into Smali? There is no direct conversion tool between the two of them, so the way to the salvation of the curve is done.
First, the Jar==>dex==>smali
Then modify the content in the Smail
After modification, it becomes a jar.
Smail==>dex==>jar
The equivalent of Dex is the transit point.
v. Project Presentation
After the technical implementation instructions are complete, here's a look at the demo:
Receiverlib Engineering
1, Btnreceiver.java
Package Com.example.receiverdemo;import Android.content.broadcastreceiver;import Android.content.context;import Android.content.intent;import Android.util.log;public class Btnreceiver extends Broadcastreceiver{private String Action = "Demo.action.myreceiver"; @Overridepublic void OnReceive (context context, Intent Intent) {log.i ("demo", "Action : "+intent.getaction ());}}
receive the broadcast and print the log .
2, Myreceiver.java
Package Com.example.receiverdemo;import Android.content.broadcastreceiver;import Android.content.context;import Android.content.intent;import Android.util.log;public class Myreceiver extends Broadcastreceiver{private String Action = "Demo.action.myreceiver"; @Overridepublic void OnReceive (context context, Intent Intent) {log.i ("demo", "Action : "+intent.getaction ());}}
3, Utils.java
Package Com.example.receiverdemo;import Android.content.context;import Android.content.intent;public class Utils { public static void Sendbroadcast (Context context,string action) {Intent Intent = new Intent (); Intent.setaction (action); Context.sendbroadcast (intent);}}
Description: Btnreceiver is an analog broadcast sent after clicking the button, equivalent to the Campaigntrackingreceiver class that needs to be changed above, Myreceiver is the broadcast receiver we need to add ourselves.
Project Download: http://download.csdn.net/detail/jiangwei0910410003/8679113
Receiverdemo Project (requires import of receiverlib exported jar)
Package Com.example.receiverdemo;import Android.os.bundle;import Android.support.v7.app.actionbaractivity;import Android.view.view;import Android.view.view.onclicklistener;public class Mainactivity extends ActionBarActivity { Private String action = "Demo.action.btnreceiver"; @Overrideprotected void OnCreate (Bundle savedinstancestate) { Super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Findviewbyid (R.ID.BTN). Setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View v) {utils.sendbroadcast ( Mainactivity.this, action);}});}}
simulate sending a broadcast
Project Download: http://download.csdn.net/detail/jiangwei0910410003/8679123
Effect:
After clicking on the button, the broadcast is sent, and the Btnreceiver is received.
So here's the beginning of inserting code in Btnreceiver.java, sending a myreceiver
First use the DX command to turn the jar we exported above receiverlib into a dex file:
How DX commands are used: DX--dex--output C:\receiver.dex receiver.jar
Then convert the Receiver.dex into a smali:
How to use Baksmali.jar: Java-jar baksmali-2.0.5.jar-o C:\classout/c:\receiver.dex
We can look at the Smali file and we'll focus on the Btnreceiver.smali file as we'll insert the code here:
. class public lcom/example/receiverdemo/btnreceiver;. Super Landroid/content/broadcastreceiver;. SOURCE "Btnreceiver.java" # Direct Methods.method Public Constructor <init> () v. Registers 1. Prologue. Line 8 Invoke-direct {P0}, landroid/content/broadcastreceiver;-><init> () V return-void.end method# virtual method S.method public OnReceive (Landroid/content/context; Landroid/content/intent;) v. Registers 7. param P1, "context" # Landroid/content/context; . param P2, "intent" # landroid/content/intent; . Prologue line Invoke-virtual {P2}, landroid/content/intent;->getaction () ljava/lang/string; Move-result-object v0. Local v0, "action": ljava/lang/string; Const-string v1, "demo" New-instance v2, Ljava/lang/stringbuilder; Const-string v3, "action:" Invoke-direct {v2, v3}, Ljava/lang/stringbuilder;-><init> (ljava/lang/string;) V I Nvoke-virtual {v2, v0}, Ljava/lang/stringbuilder;->append (ljava/lang/string;) Ljava/lang/stringbuilder; Move-result-object v2 invoke-virtual {v2}, ljava/lang/stringbuilder;->tostring () ljava/lang/string; Move-result-object v2 invoke-static {v1, v2}, Landroid/util/log;->i (ljava/lang/string; ljava/lang/string;) I const-string v4, "Demo.action.myreceiver" invoke-static {p1, v4}, Lcom/example/receiverdemo/uti Ls;->sendbroadcast (Landroid/content/context; ljava/lang/string;) V const-string v5, "Sendbroadcast" invoke-static {v1, v5}, Landroid/util/log;->i (Ljava/lang/St Ring ljava/lang/string;) I. Line Return-void.end method
About the Smali command on-line self-search, very simple, we need to insert a line of code is:
Utils.sendbroadcast Method:
There's no difficulty in this process, so don't explain.
Here we need to revert to a jar:
Use the Smali.jar tool to turn Samli into Dex
Usage: Java-jar smali-2.0.5.jar c:\classout/-o c:\receiver.dex
Then use the Dex2jar command to turn Dex into a jar
Usage: Dex2jar Receiver.dex
At this point we produce the modified jar, we replace the jar with the jar in Receiverdemo and run the result:
The success shows. Our Myreceiver received a broadcast from Btnreceiver.
Problem:
There may be problems when you use some commands in this process:
This is the class version number is incorrect, you need to modify the Java compiler version in Eclipse in the compilation export jar.
Other questions I have not met here. If you encounter problems in the development process, remember to reply to the message, I try to answer ~ ~
Vi. Summary
1, about the above mentioned problem, is the GA package class duplication problem, again in the explanation, that is a misunderstanding, we have to customize a receiver is also possible, do not need the class name must be: Campaigntrackingreceiver, so there are students if use this class, Be sure to remember, do not enter this misunderstanding.
2, about modifying the contents of the jar, in fact, the use is still a lot of, but is not a formal solution, this is a bit biased in the direction of the crack, this is not in line with the development principle, here is to explain a solution to a problem, and a knowledge of the reverse domain to supplement, This content is still very useful for the reverse domain.
3, the use of this method with all Java programming, this may be biased to the Android mobile, but if you encounter such a problem in Javaweb, you can also use this way to solve, not only limited to the Android direction.
How to modify the contents of a jar in Java