यहां पूरा समाधान है (लगभग: मैंने यूआई लेआउट और बटन हैंडलिंग को छोड़ दिया है) - बहुत से प्रयोग और विभिन्न पोस्ट से जुड़े मुद्दों से संबंधित हैं जो रास्ते में आए थे।
कई चीजें हैं जो आपको करने की आवश्यकता है:
- अपने एप्लिकेशन उपवर्ग में बिना किसी अपवाद के हैंडल करें।
- एक अपवाद को पकड़ने के बाद, उपयोगकर्ता को लॉग भेजने के लिए कहने के लिए एक नई गतिविधि शुरू करें।
- लॉगकैट की फाइलों से लॉग जानकारी निकालें और अपनी खुद की फाइल पर लिखें।
- एक ईमेल ऐप शुरू करें, जो आपकी फ़ाइल को अटैचमेंट के रूप में प्रदान करे।
- प्रकट: अपने अपवाद हैंडलर द्वारा पहचानी जाने वाली अपनी गतिविधि को फ़िल्टर करें।
- वैकल्पिक रूप से, सेटअप प्रोटीज को Log.d () और Log.v () से अलग करने के लिए।
अब, यहाँ विवरण हैं:
(1 और 2) हैंडल अनक्रेडिसेप्शन, प्रारंभ लॉग गतिविधि भेजें:
public class MyApplication extends Application
{
public void onCreate ()
{
// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
public void handleUncaughtException (Thread thread, Throwable e)
{
e.printStackTrace(); // not all Android versions will print the stack trace automatically
Intent intent = new Intent ();
intent.setAction ("com.mydomain.SEND_LOG"); // see step 5.
intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); // required when starting from Application
startActivity (intent);
System.exit(1); // kill off the crashed app
}
}
(3) एक्स्ट्रेक्ट लॉग (मैंने इसे एक मेरा SendLog गतिविधि डाला):
private String extractLogToFile()
{
PackageManager manager = this.getPackageManager();
PackageInfo info = null;
try {
info = manager.getPackageInfo (this.getPackageName(), 0);
} catch (NameNotFoundException e2) {
}
String model = Build.MODEL;
if (!model.startsWith(Build.MANUFACTURER))
model = Build.MANUFACTURER + " " + model;
// Make file name - file must be saved to external storage or it wont be readable by
// the email app.
String path = Environment.getExternalStorageDirectory() + "/" + "MyApp/";
String fullName = path + <some name>;
// Extract to file.
File file = new File (fullName);
InputStreamReader reader = null;
FileWriter writer = null;
try
{
// For Android 4.0 and earlier, you will get all app's log output, so filter it to
// mostly limit it to your app's output. In later versions, the filtering isn't needed.
String cmd = (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) ?
"logcat -d -v time MyApp:v dalvikvm:v System.err:v *:s" :
"logcat -d -v time";
// get input stream
Process process = Runtime.getRuntime().exec(cmd);
reader = new InputStreamReader (process.getInputStream());
// write output stream
writer = new FileWriter (file);
writer.write ("Android version: " + Build.VERSION.SDK_INT + "\n");
writer.write ("Device: " + model + "\n");
writer.write ("App version: " + (info == null ? "(null)" : info.versionCode) + "\n");
char[] buffer = new char[10000];
do
{
int n = reader.read (buffer, 0, buffer.length);
if (n == -1)
break;
writer.write (buffer, 0, n);
} while (true);
reader.close();
writer.close();
}
catch (IOException e)
{
if (writer != null)
try {
writer.close();
} catch (IOException e1) {
}
if (reader != null)
try {
reader.close();
} catch (IOException e1) {
}
// You might want to write a failure message to the log here.
return null;
}
return fullName;
}
(4) एक ईमेल ऐप शुरू करें (मेरी SendLog गतिविधि में भी):
private void sendLogFile ()
{
String fullName = extractLogToFile();
if (fullName == null)
return;
Intent intent = new Intent (Intent.ACTION_SEND);
intent.setType ("plain/text");
intent.putExtra (Intent.EXTRA_EMAIL, new String[] {"log@mydomain.com"});
intent.putExtra (Intent.EXTRA_SUBJECT, "MyApp log file");
intent.putExtra (Intent.EXTRA_STREAM, Uri.parse ("file://" + fullName));
intent.putExtra (Intent.EXTRA_TEXT, "Log file attached."); // do this so some email clients don't complain about empty body.
startActivity (intent);
}
(3 और 4) यहाँ SendLog कैसा दिखता है (आपको यूआई जोड़ना होगा, हालाँकि):
public class SendLog extends Activity implements OnClickListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature (Window.FEATURE_NO_TITLE); // make a dialog without a titlebar
setFinishOnTouchOutside (false); // prevent users from dismissing the dialog by tapping outside
setContentView (R.layout.send_log);
}
@Override
public void onClick (View v)
{
// respond to button clicks in your UI
}
private void sendLogFile ()
{
// method as shown above
}
private String extractLogToFile()
{
// method as shown above
}
}
(5) प्रकट:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
<!-- needed for Android 4.0.x and eariler -->
<uses-permission android:name="android.permission.READ_LOGS" />
<application ... >
<activity
android:name="com.mydomain.SendLog"
android:theme="@android:style/Theme.Dialog"
android:textAppearance="@android:style/TextAppearance.Large"
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="com.mydomain.SEND_LOG" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
(6) सेटअप रक्षक:
Project.properties में, कॉन्फ़िग लाइन बदलें। आपको "ऑप्टिमाइज़" निर्दिष्ट करना होगा या प्रोगार्ड Log.v () और Log.d () कॉल को नहीं हटाएगा।
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
Proguard-project.txt में, निम्नलिखित जोड़ें। यह बताता है कि Log.v और Log.d मानने के लिए Proguard का कोई दुष्प्रभाव नहीं है (भले ही वे लॉग लिखने के बाद से करते हैं) और इस प्रकार अनुकूलन के दौरान हटाया जा सकता है:
-assumenosideeffects class android.util.Log {
public static int v(...);
public static int d(...);
}
बस! यदि आपके पास इसमें सुधार के लिए कोई सुझाव है, तो कृपया मुझे बताएं और मैं इसे अपडेट कर सकता हूं।