
مع AppSpector ، يمكنك تصحيح تطبيقك عن بُعد في نفس الغرفة أو في قارة أخرى. يمكنك قياس أداء التطبيق وعرض محتوى قاعدة البيانات والسجلات وطلبات الشبكة وغيرها الكثير في الوقت الفعلي. هذه هي الأداة التي كنت تبحث عنها. لا تقصر نفسك فقط على سجلات بسيطة. لا يجب أن يكون تصحيح الأخطاء مؤلمة!
كل تطبيق تريد استخدامه مع AppSpector SDK عليك التسجيل على خدمتنا من خلال الويب (https://app.appspector.com) أو تطبيق سطح المكتب. بعد إضافة التطبيق انتقل إلى إعدادات التطبيق ونسخ مفتاح API.
apply plugin : ' com.android.application '
// Add AppSpector maven repository
repositories {
maven { url " https://maven.appspector.com/artifactory/android-sdk " }
}
dependencies {
implementation " com.appspector:android-sdk:1.+ "
}في حالة عدم رغبتك
dependencies {
debugImplementation " com.appspector:android-sdk:1.6.+ "
releaseImplementation( " com.appspector:android-sdk:1.6.+ " ) {
exclude group : ' com.appspector ' , module : ' android-core '
}
} import android . app . Application ;
import com . appspector . sdk . AppSpector ;
public class AmazingApp extends Application {
@ Override
public void onCreate () {
super . onCreate ();
// We recommend to start AppSpector from Application#onCreate method
// You can start all monitors
AppSpector
. build ( this )
. withDefaultMonitors ()
. run ( "API_KEY" );
// Or you can select monitors that you want to use
AppSpector
. build ( this )
. addPerformanceMonitor ()
. addLogMonitor ()
// Next line disables added monitor above. In our case, Log and Performace monitors.
. disableProvidedMonitors () // Disabled monitors can be enabled from Dashboard.
. addHttpMonitor ()
. addScreenshotMonitor ()
. addSQLMonitor ()
// Monitors that were not added to config will be ignored till declared here.
. run ( "API_KEY" );
}
}يقوم AppSpector SDK بجمع وتخزين بيانات المستخدم بما في ذلك السجلات ومحتوى قاعدة البيانات وحركة المرور للشبكة. كل هذا يمكن أن يحتوي على بيانات حساسة حتى لحماية خصوصيتك ، نقدم وحدة إضافية مع ميزة E2EE. يتيح لك تشفير جميع البيانات التي يرسلها AppSpector من أو إلى جهازك وتأكد من أنه يمكنك فك تشفيره فقط. لأسباب أمنية ، تتوفر جلسات مشفرة فقط في تطبيق سطح المكتب.
لاستخدام التشفير ، يجب عليك تحديد خيار Enable End-To-End encryption أثناء تسجيل تطبيقك باستخدام تطبيق سطح المكتب (لا يمكن تحديث التطبيق المسجل مسبقًا لدعم التشفير).
بعد ذلك ، تحتاج إلى إضافة وحدة android-sdk-encryption إلى إعلان التبعيات. لذلك ، يجب أن تحتوي build.gradle على مستوى التطبيق على الأسطر التالية:
apply plugin : ' com.android.application '
// Add AppSpector maven repository
repositories {
maven { url " https://maven.appspector.com/artifactory/android-sdk " }
}
dependencies {
implementation " com.appspector:android-sdk:1.+ "
implementation ' com.appspector:android-sdk-encryption:1.+ '
} أخيرًا ، تمكين التشفير عن طريق وضع enableEncryption إلى تكوين SDK. Public Key الذي يمكنك العثور عليه على شاشة إعدادات التطبيق.
AppSpector
. build ( this )
. withDefaultMonitors ()
. enableEncryption ( "CLIENT_PUBLIC_KEY" )
. run ( "API_KEY" );بناء مشروعك وشاهد كل شيء يعمل! عندما يكون التطبيق الخاص بك قيد التشغيل ، يمكنك الانتقال إلى https://app.appspector.com والاتصال بجلسة التطبيق الخاصة بك.
بعد استدعاء طريقة run ، يبدأ SDK جمع البيانات ونقل البيانات إلى خدمة الويب. من هذه النقطة ، يمكنك رؤية جلستك في عميل AppSpector.
نظرًا لأننا نوصي بإبقاء تهيئة SDK في طريقة onCreate() لتطبيقك ، يوفر SDK طرقًا لمساعدتك على التحكم في حالة AppSpector عن طريق استدعاء أساليب stopSdk() و startSdk() ثابتة. يمكنك استخدام هذه الطرق فقط بعد تهيئة AppSpector.
يخبر stop() AppSpector بتعطيل جميع جمع البيانات وإغلاق الجلسة الحالية.
AppSpector . stopSdk (); يبدأ startSdk() مرة أخرى باستخدام التكوين الذي قدمته عند التهيئة.
AppSpector . startSdk (); مع النتيجة ، سيتم إنشاء جلسة جديدة ولن يتم تتبع جميع النشاطات بين stop() و start() .
للتحقق من حالة AppSpector ، يمكنك استخدام طريقة isStarted() .
AppSpector . shared (). isStarted (); يمكنك تعيين اسم مخصص لجهازك للعثور على الجلسات المطلوبة بسهولة في قائمة الجلسات. للقيام بذلك ، يجب عليك إضافة الاسم المطلوب كقيمة لـ AppSpector.METADATA_KEY_DEVICE_NAME المفتاح إلى قاموس metadata :
AppSpector
. build ( this )
. withDefaultMonitors ()
. addMetadata ( AppSpector . METADATA_KEY_DEVICE_NAME , "YOUR_DEVICE_NAME" )
. run ( "YOUR_API_KEY" );أيضًا ، يسمح SDK بإدارة اسم الجهاز أثناء عمر التطبيق باستخدام
طريقة setMetadataValue لتغيير اسم الجهاز
AppSpector . shared (). setMetadataValue ( AppSpector . METADATA_KEY_DEVICE_NAME , "NEW_DEVICE_NAME" ); أو removeMetadataValue لإزالة اسم الجهاز المخصص الخاص بك
AppSpector . shared (). removeMetadataValue ( AppSpector . METADATA_KEY_DEVICE_NAME ); لتصفح وتشغيل استعلامات SQL في قاعدة بيانات SQLCipher ، تحتاج إلى إجراء خطوات إضافية. بادئ ذي بدء ، أضف وحدة sqlcipher-extension إلى ملف app/build.gradle تحت وحدة SDK الرئيسية. لذلك ، سيبدو هكذا:
dependencies {
implementation ' com.appspector:android-sdk:1.+ '
implementation ' com.appspector:sqlcipher-extension:1.+ '
} بعد ذلك ، قم بإنشاء DatabAseConnectionFactory وقم بتمريره كوسيطة لطريقة addSQLMonitor .
دعونا نتخيل أن مشروعك يحتوي على قاعدة بيانات SQLCIPHER مع اسم "my_encrypted_db" وغيرها من sqlite:
AppSpector
. build ( this )
. withDefaultMonitors ()
. addSQLMonitor ( new SQLiteMonitor . DatabaseConnectionFactory () {
@ NonNull
@ Override
public DatabaseConnection createDatabaseConnection ( @ NonNull Database database ) {
if ( "my_encrypted_db" . equals ( database . name )) {
return new SQLCipherDatabaseConnection ( database , "password" );
}
return new SQLiteDatabaseConnection ( database );
}
})
. run ( "YOUR_API_KEY" );في بعض الأحيان ، قد ترغب في ضبط أو تخطي بعض أجزاء تجميع AppSpector.
لهذا الهدف ، يوفر Monitor HTTP واجهة HTTPFilter التي يمكن أن تمر إلى طريقة addHttpMonitor(HTTPFilter) .
دعنا نقول أننا نريد تخطي رمز مصادقنا من رؤوس الطلبات. فيما يلي عينة من هذا المرشح:
public class TokenFilter implements HTTPFilter {
@ Nullable
@ Override
public HttpRequest filter ( HttpRequest request ) {
if ( request . getHeaders (). containsKey ( "YOUR-AUTH-HEADER" )) {
request . getHeaders (). remove ( "YOUR-AUTH-HEADER" );
}
return request ;
}
@ Nullable
@ Override
public HttpResponse filter ( HttpResponse response ) {
return response ;
}
} يتيح جهاز مراقبة SerquePreferences تحديد الملفات التي تريد ملاحظتها باستخدام SharedPreferencesSourceFactory .
SharedPreferencesSourceFactory.all() . بشكل افتراضي ، يستخدم الشاشة هذه القيمة.SharedPreferencesSourceFactory.excludeFiles("preferences_name") ، حيث "تفضيلات_name" هو اسم ملف تم تجاهله. يمكنك تمرير العديد من أسماء الملفات كما تريد.SharedPreferencesSourceFactory.only("preferences_name") ، حيث "تفضيلات _name" هو اسم ملف للمراقبة. تتلقى هذه الطريقة أيضًا العديد من الأرجواس كما تريد. في الإضافة ، يسمح الشاشة بتوفير SharedPreferencesMonitor.Filter لإزالة أو تعديل بعض القيم قبل إرسال البيانات على العميل.
دعنا نقول أنك تريد إزالة key_1 وتعديل تفضيلات key_2 في preferences_name الملف. لذا ، سيبدو الفلتر الخاص بك هكذا:
public class SimpleSharedPreferencesFilter implements SharedPreferencesMonitor . Filter {
@ NonNull
@ Override
public Map < String , PreferenceValue > filter ( @ NonNull String fileName , @ NonNull Map < String , PreferenceValue > values ) {
if ( fileName . equals ( "preferences_name" )) {
values . remove ( "key_1" );
if ( values . containsKey ( "key_2" )) {
values . put ( "key_2" , PreferenceValue . stringValue ( "modified value" ));
}
}
return values ;
}
} لتطبيق هذه التخصيصات ، تحتاج إلى استخدام إحدى هذه الطرق: addSharedPreferenceMonitor(SharedPreferencesMonitor.Filter) ، addSharedPreferenceMonitor(SharedPreferencesSourceFactory) ، addSharedPreferenceMonitor(SharedPreferencesSourceFactory, SharedPreferencesMonitor.Filter) .
لتصفية سجلات ، تحتاج إلى تطبيق LogMonitor.Filter ونقلها إلى طريقة addLogMonitor(LogMonitor.Filter) .
دعونا نفكر في مثال حيث نريد تغيير مستوى السجل للتحذير من جميع الرسائل مع رمز الكلمات:
public class LogFilter implements LogMonitor . Filter {
@ Nullable
@ Override
public LogEvent filter ( LogEvent event ) {
if ( event . message . contains ( "token" )) {
event . level = LogLevel . WARN ;
}
return request ;
}
}دعونا نقدم الفلتلات التي تم إنشاؤها للشاشات:
AppSpector
. build ( this )
. withDefaultMonitors ()
. addHttpMonitor ( new TokenFilter ())
. addSharedPreferenceMonitor ( new SimpleSharedPreferencesFilter ())
. addLogMonitor ( new LogFilter ())
. run ( "YOUR_API_KEY" );في بعض الأحيان قد تحتاج إلى الحصول على عنوان URL يشير إلى الجلسة الحالية من الكود. لنفترض أنك تريد تعطل الرابط في مراسل التصادم الخاص بك ، أو اكتبه إلى سجلات أو عرض في واجهة المستخدم الخاصة بك. للحصول على عنوان URL هذا ، يجب عليك إضافة رد الاتصال على الجلسة:
AppSpector . shared (). setSessionUrlListener ( new SessionUrlListener () {
@ Override
public void onReceived ( @ NonNull String sessionUrl ) {
// Save url for future use...
}
});بشكل افتراضي ، يكون AppSpector SDK نشطًا حتى يتم قتل التطبيق بواسطة Android OS ، حتى لو لم يتم ترك أنشطة. قد يؤدي ذلك إلى جمع بيانات غير ضروري وجلسات طويلة للتطبيقات غير النشطة. نحن نوفر API لتعطيل جمع البيانات لحالة عندما يكون التطبيق لا يتم تشغيله.
AppSpector
. build ( this )
. collectDataInBackground ( false ) // Set this flag to disable data collection if no activities left
. withDefaultMonitors ()
. run ( "YOUR_API_KEY" ); إذا كنت لا ترغب في استخدام البرنامج المساعد AppSpector Gradle ، فيمكنك استخدام طريقة بديلة لاعتراض طلبات واستجابات HTTP. يمكنك إضافة AppSpectorOkHttp3Interceptor يدويًا إلى OKHTTPCLIENT (أو AppSpectorOkHttp2Interceptor للإصدار القديم من OKHTTPCLIENT). أيضًا ، لا تنس إزالة البرنامج المساعد AppSpector من ملف app/build.gradle إذا تمت إضافة المكون الإضافي.
new OkHttpClient . Builder ()
. addInterceptor ( new AuthenticationInterceptor ()) // for example, it adds auth token to you request
. addInterceptor ( new AppSpectorOkHttp3Interceptor ()) // it will track your requests and responses
. build () في اللحظة الحالية ، يوفر SDK API للإعداد اليدوي في قاعدة الكود الخاصة بك. لاستخدامه في المشروع ، أولاً ، تحتاج إلى إضافة تبعية Gradle urlconnection-extension :
dependencies {
implementation ' com.appspector:android-sdk:1.+ '
implementation ' com.appspector:urlconnection-extension:1.+ '
} بعد ذلك ، استبدل مكالمات url.openConnection() بـ UrlInstrument.openConnection(url) . لنفترض أن لدينا الطريقة للحصول على صفحة Google ونريد تتبع هذا الطلب:
import java . net . HttpURLConnection ;
import java . net . URL ;
public void getGooglePage () {
HttpURLConnection connection = null ;
try {
connection = ( HttpURLConnection ) new URL ( "https://google.com" ). openConnection ();
if ( connection . getResponseCode () == 200 ) {
//Read data from connection.inputStream
}
} catch ( IOException ex ) {
Log . d ( "UrlConnectionSample" , "Request was failed" , ex );
} finally {
if ( connection != null ) {
connection . disconnect ();
}
}
}بعد دمج SDK ، سيكون الأمر مثل هذا:
import com . appspector . sdk . urlconnection . instrumentation . UrlInstrument ;
import java . net . HttpURLConnection ;
import java . net . URL ;
public void getGooglePage () {
HttpURLConnection connection = null ;
try {
connection = ( HttpURLConnection ) UrlInstrument . openConnection ( new URL ( "https://google.com" ));
if ( connection . getResponseCode () == 200 ) {
//Read data from connection.inputStream
}
} catch ( IOException ex ) {
Log . d ( "UrlConnectionSample" , "Request was failed" , ex );
} finally {
if ( connection != null ) {
connection . disconnect ();
}
}
} وهذا كل شيء! ملاحظة: استدعاء طريقة disconnect أمر مهم بالنسبة لنا. إنها علامة تم الانتهاء من الطلب.
إذا تم دمج الأخشاب في مشروعك ، يمكنك بسهولة استخدامه مع AppSpector:
Timber . plant ( new Timber . DebugTree () {
@ Override
void log ( int priority , String tag , @ NotNull String message , Throwable t ) {
Logger . log ( priority , tag , message , t )
}
})يوفر AppSpector العديد من الشاشات التي تتتبع أنشطة مختلفة داخل تطبيقك:
يوفر متصفحًا لقواعد بيانات SQLite الموجودة في تطبيقك. يسمح بتتبع جميع الاستعلامات ، ويظهر مخطط DB والبيانات في DB. يمكنك إصدار استعلام مخصص SQL على أي ديسيبل ومعرفة النتائج في المتصفح على الفور.

يعرض جميع حركة مرور HTTP في تطبيقك. يمكنك فحص أي طلب ، انظر رؤوس الطلب/الاستجابة والجسم. نحن نقدم Highliting XML و JSON للطلب/الاستجابات بخيارات التنسيق والطي ، لذا من السهل البحث عن الاستجابات الضخمة.

يعرض جميع السجلات التي تم إنشاؤها بواسطة تطبيقك.

يسمح لك AppSpector Logger بجمع رسالة السجل فقط في خدمة AppSpector. من المفيد عند تسجيل تسجيل بعض البيانات الداخلية التي يمكن تسريبها عبر logcat. يحتوي AppSpector Logger على نفس واجهة برمجة التطبيقات مع فئة android.util.Log .
Logger . d ( "MyTAG" , "It won't be printed to the Logcat" );معظم التطبيقات مدركة للموقع. يتطلب اختباره تغيير المواقع بنفسك. في هذه الحالة ، فإن السخرية من الموقع هو مدخر في الوقت الفعلي. ما عليك سوى الإشارة إلى الموقع على الخريطة وسيقوم تطبيقك بتغيير الجيوداتا على الفور.

يعرض الرسوم البيانية في الوقت الفعلي لاستخدام وحدة المعالجة المركزية / الذاكرة / الشبكة / القرص / البطارية.

ببساطة يلتقط لقطة الشاشة من الجهاز.

يوفر المتصفح والمحرر لـ ServentPreferences.

يوفر الوصول إلى المجلد الداخلي للتطبيق. لذلك ، باستخدام هذا الشاشة ، يمكنك تنزيل الملفات أو إزالة أو تحميل الملفات وإنشاء مجلدات وتجول فقط من خلال مجلدات التطبيق.

تتيح لك الشاشة إرسال أي بيانات تريد رؤيتها. يوفر SDK واجهة برمجة تطبيقات بسيطة لإرسال الأحداث الخاصة بك. هنا مثال:
CustomEventsSender . send ( new MyCustomEvent ()) في المثال ، تقوم فئة MyCustomEvent بتنفيذ واجهة CustomEventPayload كما هو الحال هنا:
public class MyCustomEvent implements CustomEventPayload {
@ NonNull
@ Override
public String getName () {
return "Custom Event" ;
}
@ NonNull
@ Override
public String getCategory () {
return "Application" ;
}
@ NonNull
@ Override
public Map < String , Object > getPayload () {
final Map < String , Object > payload = new HashMap <>();
payload . put ( "sampleDate" , new Date ());
payload . put ( "sampleBool" , false );
payload . put ( "sampleInt" , 42 );
payload . put ( "sampleString" , "Test" );
return payload ;
}
}يوفر الشاشة فرصة لتشغيل الكود الخاص بك عن بُعد من لوحة معلومات AppSpector. يجب أن يتم لف الرمز المشغل في CommandCallback الخاص بـ AppSpector وتسجيله في SDK. يتيح لك الأمر نقل المعلمات إلى الكود الخاص بك وإعلان نوع النتيجة.
دعنا نقول أنك بحاجة إلى إظهار الخبز المحمص مع النص المحدد وإرجاع قيمة int.
فيما يلي إعلان أمرك الذي يتطلب وسيطة للرسالة ولديها نتيجة عدد صحيح.
@ Command ( value = "Show message" , category = "Application" )
public class ShowToastCommand extends BaseCommand < Integer > {
@ Argument ( isRequired = true )
public String message ;
}وهنا تسجيل قيادتك وتنفيذ CommandCallback.
AppSpector . shared (). commands (). register ( ShowToastCommand . class , new CommandCallback < Integer , ShowToastCommand >() {
@ Override
public void exec ( @ NonNull final ShowToastCommand command , @ NonNull final Responder < Integer > responder ) {
new Handler ( Looper . getMainLooper ()). post ( new Runnable () {
@ Override
public void run () {
Toast . makeText ( getContext (), command . message , Toast . LENGTH_SHORT ). show ();
responder . ok ( 42 );
}
});
}
}); سيظهر هذا الأمر ضمن فئة Application وسيكون له اسم Show message على لوحة القيادة. يمكنك استخدام الفئات الخاصة بك لتجميع الأوامر على لوحة القيادة.
لا يمكن تسجيل الأوامر إلا بعد تشغيل SDK.
اسمحوا لنا أن نعرف ما رأيك أو ماذا تريد أن تتحسن: [email protected].
انضم إلى Slack لدينا لمناقشة عملية الإعداد والميزات