Here's the full solution (almost: I omitted the interface layout and button controls) - obtained from a large number of experiments and various messages from others related to problems that arose along the way.
You need to do a few things:
- Handle uncaughtException in a subclass of Application.
- Once an exception is detected, run a new action to ask the user to send a login.
- Extract the log information from the logcat files and write to your own file.
- Launch the email application by providing the file as an attachment.
- Manifest: Filter your activity to recognize your exception handler.
- If desired, install Proguard to cut Log.d () and Log.v ().
Now, here are the details:
(1 and 2) Handle uncaughtException, start working with the send log:
public class MyApplication extends Application { public void onCreate () {
(3) Extract the log (I set this with my SendLog processing):
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;
(4) Launch the email application (also in my SendLog operation):
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.");
(3 and 4) Here is what SendLog looks like (you need to add a user interface):
public class SendLog extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature (Window.FEATURE_NO_TITLE);
(5) Manifesto:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... > <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) Setup Proguard:
In project.properties, change the configuration line. You must specify "optimize", or Proguard will not delete Log.v () and Log.d () calls.
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
In proguard-project.txt add the following. This tells Proguard that Log.v and Log.d have no side effects (even though they are logged) and therefore can be removed during optimization:
-assumenosideeffects class android.util.Log { public static int v(...); public static int d(...); }
What is it! If you have any suggestions for improving this, let me know and I can update it.