Php obtains the apk package information. php obtains the apk package.
Sometimes, when using php to upload an android apk package, we need to obtain the information in the android apk package. This article describes how php obtains the apk package information in the form of an instance. The specific implementation method is as follows:
<? Php/* parses the compressed XML file in the android apk package, and restores and reads XML content dependencies. The function requires the support of the php zip Package function. */Include ('. /Apkparser. php '); $ appObj = new Apkparser (); $ targetFile = a.apk; // path of the apk $ res = $ appObj-> open ($ targetFile ); $ appObj-> getAppName (); // Application name $ appObj-> getPackage (); // application package name $ appObj-> getVersionName (); // version name $ appObj-> getVersionCode (); // version code?>
The following is the Apkparser class package. Copy the following code and save it as Apkparser. php to execute the above Code.
<? Php // example // Apkparser class package start // EXAMPLE class ApkParser {// -------------------- // public function for external calls // -------------------- public function open ($ apk_file, $ xml_file = 'androidmanifest. xml') {$ zip = new \ ZipArchive; if ($ zip-> open ($ apk_file) = TRUE) {$ xml = $ zip-> getFromName ($ xml_file); $ zip-> close (); if ($ xml) {try {return $ this-> parseString ($ xml);} catch (E Xception $ e) {}}return false;} public function parseString ($ xml) {$ this-> xml = $ xml; $ this-> length = strlen ($ xml); $ this-> root = $ this-> parseBlock (self: AXML_FILE); return true ;} public function getXML ($ node = NULL, $ lv =-1) {if ($ lv =-1) $ node = $ this-> root; if (! $ Node) return ''; if ($ node ['type'] = self: END_TAG) $ lv --; $ xml = @ ($ node ['line'] = 0 | $ node ['line'] = $ this-> line )? '':" \ N ". str_repeat ('', $ lv); $ xml. = $ node ['tag']; $ this-> line = @ $ node ['line']; foreach ($ node ['child '] as $ c) {$ xml. = $ this-> getXML ($ c, $ lv + 1);} return $ xml;} public function getPackage () {return $ this-> getAttribute ('manifest ', 'package');} public function getVersionName () {return $ this-> getAttribute ('manifest ', 'android: versionname');} public function getVersionCode () {return $ this-> get Attribute ('manifest ', 'android: versioncode');} public function getAppName () {return $ this-> getAttribute ('manifest/application', 'android: name ');} public function getMainActivity () {for ($ id = 0; true; $ id ++) {$ act = $ this-> getAttribute ("manifest/application/activity [{$ id}]/intent-filter/action", 'android: name'); if (! $ Act) break; if ($ act = 'android. intent. action. MAIN ') return $ this-> getActivity ($ id);} return NULL;} public function getActivity ($ idx = 0) {$ idx = intval ($ idx ); return $ this-> getAttribute ("manifest/application/activity [{$ idx}]", 'android: name');} public function getAttribute ($ path, $ name) {$ r = $ this-> getElement ($ path); if (is_null ($ r) return NULL; if (isset ($ r ['attrs']) {foreach ($ r ['attrs'] S $ a) {if ($ a ['ns _ name'] ==$ name) return $ this-> getAttributeValue ($ a) ;}} return NULL ;} // ---------------------- // type constant definition // define const AXML_FILE = 0x00080003; const STRING_BLOCK = 0x001C0001; const RESOURCEIDS = 0x00080180; const START_NAMESPACE = 0x00100100; const END_NAMESPACE = 0x00100101; const START_TAG = 0x00100102; const END_TAG = 0x00100103; const TEXT = 0x00100104; cons T TYPE_NULL = 0; const TYPE_REFERENCE = 1; const TYPE_ATTRIBUTE = 2; const TYPE_STRING = 3; const TYPE_FLOAT = 4; const TYPE_DIMENSION = 5; const TYPE_FRACTION = 6; const TYPE_INT_DEC = 16; const TYPE_INT_HEX = 17; const TYPE_INT_BOOLEAN = 18; const frequency = 28; const frequency = 29; const TYPE_INT_COLOR_ARGB4 = 30; const frequency = 31; const UNIT_MASK = 15; private static $ RA DIX_MULTS = array (0.00390625, 3.051758E-005, 1.192093E-007, 4.656613E-010); private static $ DIMENSION_UNITS = array ("px", "dip", "sp ", "pt", "in", "mm", "", ""); private static $ FRACTION_UNITS = array ("%", "% p ","", "", ""); private $ xml = ''; private $ length = 0; private $ stringCount = 0; private $ styleCount = 0; private $ stringTab = array (); private $ styleTab = array (); private $ resourceIDs = array (); Private $ ns = array (); private $ cur_ns = NULL; private $ root = NULL; private $ line = 0; // ---------------------- // internal private function // ------------------------ private function getElement ($ path) {if (! $ This-> root) return NULL; $ ps = explode ('/', $ path); $ r = $ this-> root; foreach ($ ps as $ v) {if (preg_match ('/([^ \ [] +) \ [([0-9] +) \] $/', $ v, $ ms )) {$ v = $ ms [1]; $ off = $ ms [2];} else {$ off = 0 ;} foreach ($ r ['child '] as $ c) {if ($ c ['type'] = self :: START_TAG & $ c ['ns _ name'] =$ v) {if ($ off = 0) {$ r = $ c; continue 2 ;} else {$ off -- ;}}// node return NULL not found;} return $ r;} private function parseB Lock ($ need = 0) {$ o = 0; $ type = $ this-> get32 ($ o); if ($ need & $ type! = $ Need) throw new Exception ('block Type error', 1); $ size = $ this-> get32 ($ o ); if ($ size <8 | $ size> $ this-> length) throw new Exception ('block Size error', 2 ); $ left = $ this-> length-$ size; $ props = false; switch ($ type) {case self: AXML_FILE: $ props = array ('line' => 0, 'tag' => '<? Xml version = "1.0" encoding = "UTF-8"?> '); Break; case self: STRING_BLOCK: $ this-> stringCount = $ this-> get32 ($ o ); $ this-> styleCount = $ this-> get32 ($ o); $ o + = 4; $ strOffset = $ this-> get32 ($ o ); $ styOffset = $ this-> get32 ($ o); $ strListOffset = $ this-> get32array ($ o, $ this-> stringCount ); $ styListOffset = $ this-> get32array ($ o, $ this-> styleCount); $ this-> stringTab = $ this-> stringCount> 0? $ This-> getStringTab ($ strOffset, $ strListOffset): array (); $ this-> styleTab = $ this-> styleCount> 0? $ This-> getStringTab ($ styOffset, $ styListOffset): array (); $ o = $ size; break; case self: RESOURCEIDS: $ count = $ size/4-2; $ this-> resourceIDs = $ this-> get32array ($ o, $ count); break; case self: START_NAMESPACE: $ o + = 8; $ prefix = $ this-> get32 ($ o); $ uri = $ this-> get32 ($ o ); if (empty ($ this-> cur_ns) {$ this-> cur_ns = array (); $ this-> ns [] = & $ this-> cur_ns ;} $ this-> cur_ns [$ uri] = $ prefix; break; cas E self: END_NAMESPACE: $ o + = 8; $ prefix = $ this-> get32 ($ o); $ uri = $ this-> get32 ($ o ); if (empty ($ this-> cur_ns) break; unset ($ this-> cur_ns [$ uri]); break; case self: START_TAG: $ line = $ this-> get32 ($ o); $ o + = 4; $ attrs = array (); $ props = array ('line' => $ line, 'ns' => $ this-> getNameSpace ($ this-> get32 ($ o )), 'name' => $ this-> getString ($ this-> get32 ($ o), 'flag' => $ this-> get32 ($ o ), 'Count' => $ this-> Get16 ($ o), 'id' => $ this-> get16 ($ o)-1, 'class' => $ this-> get16 ($ o)-1, 'style' => $ this-> get16 ($ o)-1, 'attrs' => & $ attrs ); $ props ['ns _ name'] = $ props ['ns']. $ props ['name']; for ($ I = 0; $ I <$ props ['Count']; $ I ++) {$ a = array ('ns' => $ this-> getNameSpace ($ this-> get32 ($ o )), 'name' => $ this-> getString ($ this-> get32 ($ o), 'val _ str' => $ this-> get32 ($ o ), 'val _ type' => $ this-> get32 ($ o), 'val _ data' => $ this-> Get32 ($ o); $ a ['ns _ name'] = $ a ['ns']. $ a ['name']; $ a ['val _ type'] >>= 24; $ attrs [] = $ ;} // process the TAG string $ tag = "<{$ props ['ns _ name']}"; foreach ($ this-> cur_ns as $ uri => $ prefix) {$ uri = $ this-> getString ($ uri); $ prefix = $ this-> getString ($ prefix); $ tag. = "xmlns: {$ prefix }=\" {$ uri} \ "";} foreach ($ props ['attrs'] as $ a) {$ tag. = "{$ a ['ns _ name']} = \"". $ this-> getAttributeValue ($ ). '"';} $ tag. = '> '; $ Props ['tag'] = $ tag; unset ($ this-> cur_ns); $ this-> cur_ns = array (); $ this-> ns [] = & $ this-> cur_ns; $ left =-1; break; case self: END_TAG: $ line = $ this-> get32 ($ o); $ o + = 4; $ props = array ('line' => $ line, 'ns' => $ this-> getNameSpace ($ this-> get32 ($ o )), 'name' => $ this-> getString ($ this-> get32 ($ o ))); $ props ['ns _ name'] = $ props ['ns']. $ props ['name']; $ props ['tag'] = "</{$ props ['ns _ name']}>"; if (cou Nt ($ this-> ns)> 1) {array_pop ($ this-> ns); unset ($ this-> cur_ns ); $ this-> cur_ns = array_pop ($ this-> ns); $ this-> ns [] = & $ this-> cur_ns;} break; case self: TEXT: $ o + = 8; $ props = array ('tag' => $ this-> getString ($ this-> get32 ($ o); $ o + = 8; break; default: throw new Exception ('block Type error', 3); break;} $ this-> skip ($ o); $ child = array (); while ($ this-> length> $ left) {$ c = $ this-> parseBlock (); If ($ props & $ c) $ child [] = $ c; if ($ left =-1 & $ c ['type'] = self :: END_TAG) {$ left = $ this-> length; break ;}} if ($ this-> length! = $ Left) throw new Exception ('block Overflow error', 4); if ($ props) {$ props ['type'] = $ type; $ props ['SIZE'] = $ size; $ props ['child '] = $ child; return $ props;} else {return false ;}} private function getAttributeValue ($ a) {$ type = & $ a ['val _ type']; $ data = & $ a ['val _ data']; switch ($ type) {case self: TYPE_STRING: return $ this-> getString ($ a ['val _ str']); case self: TYPE_ATTRIBUTE: return sprintf ('? % S % 08X ', self: _ getPackage ($ data), $ data); case self: TYPE_REFERENCE: return sprintf (' @ % s % 08X ', self :: _ getPackage ($ data), $ data); case self: TYPE_INT_HEX: return sprintf ('0x % 08x', $ data); case self: TYPE_INT_BOOLEAN: return ($ data! = 0? 'True': 'false'); case self: TYPE_INT_COLOR_ARGB8: case self: TYPE_INT_COLOR_RGB8: case self: TYPE_INT_COLOR_ARGB4: case self: TYPE_INT_COLOR_RGB4: return sprintf ('# % 08X', $ data); case self: TYPE_DIMENSION: return $ this-> _ complexToFloat ($ data ). self: $ DIMENSION_UNITS [$ data & self: UNIT_MASK]; case self: TYPE_FRACTION: return $ this-> _ complexToFloat ($ data ). self: $ FRACTION_UNITS [$ data & self: UNIT_MA SK]; case self: TYPE_FLOAT: return $ this-> _ int2float ($ data);} if ($ type >=self: TYPE_INT_DEC & $ type <self :: TYPE_INT_COLOR_ARGB8) {return (string) $ data;} return sprintf ('<0x % X, type 0x % 02X>', $ data, $ type );} private function _ complexToFloat ($ data) {return (float) ($ data & 0xFFFFFF00) * self: $ RADIX_MULTS [($ data> 4) & 3];} private function _ int2float ($ v) {$ x = ($ v & (1 <23)-1) + (1 <2 3) * ($ v> 31 | 1); $ exp = ($ v> 23 & 0xFF)-127; return $ x * pow (2, $ exp-23);} private static function _ getPackage ($ data) {return ($ data> 24 = 1 )? 'Android: ': '';} private function getStringTab ($ base, $ list) {$ tab = array (); foreach ($ list as $ off) {$ off + = $ base; $ len = $ this-> get16 ($ off); $ mask = ($ len> 0x8) & 0xFF; $ len = $ len & 0xFF; if ($ len = $ mask) {if ($ off + $ len> $ this-> length) throw new Exception ('string Table overflow', 11); $ tab [] = substr ($ this-> xml, $ off, $ len );} else {if ($ off + $ len * 2> $ this-> length) throw new Exce Ption ('string Table overflow', 11); $ str = substr ($ this-> xml, $ off, $ len * 2 ); $ tab [] = mb_convert_encoding ($ str, 'utf-8', 'ucos-2le') ;}return $ tab;} private function getString ($ id) {if ($ id>-1 & $ id <$ this-> stringCount) {return $ this-> stringTab [$ id] ;}else {return '';}} private function getNameSpace ($ uri) {for ($ I = count ($ this-> ns); $ I> 0 ;) {$ ns = $ this-> ns [-- $ I]; if (isset ($ ns [$ uri])) {$ Ns = $ this-> getString ($ ns [$ uri]); if (! Empty ($ ns) $ ns. = ':'; return $ ns ;}} return '';} private function get32 (& $ off) {$ int = unpack ('V ', substr ($ this-> xml, $ off, 4); $ off + = 4; return array_shift ($ int);} private function get32array (& $ off, $ size) {if ($ size <= 0) return NULL; $ arr = unpack ('v * ', substr ($ this-> xml, $ off, 4 * $ size )); if (count ($ arr )! = $ Size) throw new Exception ('array Size error', 10); $ off + = 4 * $ size; return $ arr;} private function get16 (& $ off) {$ int = unpack ('V', substr ($ this-> xml, $ off, 2); $ off + = 2; return array_shift ($ int );} private function skip ($ size) {$ this-> xml = substr ($ this-> xml, $ size); $ this-> length-= $ size ;}} // --------------------- // end of the Apkparser class package // ---------------------?>
If you are interested, you can debug and run the example in this article. I believe it will inspire your php program development.
How does php obtain an http package?
$ _ POST is an Array, and echo $ _ POST is an Array of course. You can use var_dump ($ _ POST) to check the parameters and values in the Array. If the pass-through parameter is a and the value is hello, you can use $ _ POST ['a'] to obtain it. Do you like the GET method welcome. php? A = hello
Echo $ _ GET ['a'];
On the php page, can I specify to send a message to an android apk program that accesses it?
Your current practice is the only feasible practice. You can only refresh the APK regularly, unless the APK and the server are continuously connected, or the server's PHP is used to find the APK, because your APK is not a server, it cannot be executed in turn.
To reduce the server pressure, you must make your APK a server, listen on a network port, and allow other devices on the network to connect. However, this project will be very large, and the logic of APK and PHP will become very complicated, because PHP will come to the APK when needed. If the phone is shut down, it will have to be delayed again, in order to wait for PHP to connect, APK should work as a service and be on standby at any time.