The open source nature of Android system has given it an absolute advantage in the current smartphone market, and it has also produced a variety of models and systems. This makes us Android developers need to adapt to different models and systems.

The body of the

The requirement described in this article is to invoke a local mail client to send a message with an attachment.

The first routine calls the mail

 

Intent intent = new Intent(Intent.ACTION_SEND); intent.setData(Uri.parse("mailto:")); intent.putExtra(Intent.EXTRA_EMAIL, ""); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); StartActivity (intent.createchooser (Intent, "Share "));Copy the code

The loading effect is as follows:

ACTION_SEND.png

In the first case, we identified the mail (Mailto), but the actual execution turned out to be file sharing. Although there was a mail client, it added user steps, which was unacceptable to the product manager, so we tried the second method.

Try SENDTO for the second (mostly promoted online)

 

Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setData(Uri.parse("mailto:")); intent.putExtra(Intent.EXTRA_EMAIL, ""); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); StartActivity (intent.createchooser (Intent, "Share "));Copy the code

The SENDTO code is loaded as follows:

ACTION_SENDTO.png

SENDTO did call the mailbox client, but the screenshot above says “No application can do this”. Why does it work? Because it works on some models, but huawei tablets don’t work. Can we assume that Huawei has changed the logo of Android mailbox? Interested students can go to see the source of huawei system. And since that’s not going to work, we’re going to explore what else we can do.

The third way is SEND_MULTIPLE sending multiple attachments

SENDTO sends a single attachment, while SEND_MULTIPLE carries multiple attachments. Let’s try this code execution

 

Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); intent.setData(Uri.parse("mailto:")); intent.putExtra(Intent.EXTRA_EMAIL, ""); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_STREAM, list); // uri.fromfile (file) startActivity(intent.createchooser (Intent, "share "));Copy the code

The screenshot of multi-attachment execution is as follows:

ACTION_SEND_MULTIPLE.png

We see that the sending of multiple attachments is similar to the first case, with all the mail clients and Bluetooth tuned up, but we don’t need to call so many applications, so let’s try something else.

The fourth way is to call the application directly

Believe that there must be a direct way to call a tool software, we directly this way can achieve the effect we want? Let’s try it together

 

Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL, ""); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); intent.setClassName("com.android.email","com.android.email.activity.MessageCompose"); StartActivity (intent.createchooser (Intent, "Share "));Copy the code

Screenshot of direct call execution effect:

Final render.png

In this case, can we find several phones with different models and systems and obtain the corresponding package name and Activity to achieve the desired effect? The answer is yes. And after the trial of Xiaomi, Redmi, Samsung, Huawei, Honor, Nubia, found that can meet the demand. I haven’t tried it on meizu system because I don’t have a meizu machine in my hand. If you are qualified, you can try it. By the way, let me know. I would be most grateful.

The final code

Send the final code, because a class can be solved, no more Github.

 

package com.hewc.sendmail; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.StrictMode; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import java.io.File; public class MainActivity extends AppCompatActivity { private Context context; private String filePath = "/storage/emulated/0/20.txt"; private static final String[] NARMAL_PHONE = {"com.android.email", "com.android.email.activity.MessageCompose"}; private static final String[] MIUI_PHONE = {"com.android.email", "com.kingsoft.mail.compose.ComposeActivity"}; private static final String[] SAMSUNG_PHONE = {"com.samsung.android.email.provider", "com.samsung.android.email.composer.activity.MessageCompose"}; @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = this; setContentView(R.layout.activity_main); / / android 7.0 system. Solve the problem of photo StrictMode VmPolicy. Builder Builder = new StrictMode. VmPolicy. Builder (); StrictMode.setVmPolicy(builder.build()); builder.detectFileUriExposure(); TextView tv = findViewById(R.id.tv); tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { File file = new File(filePath); try { Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL, ""); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); if (getDeviceBrand().toUpperCase().contains("HONOR") || getDeviceBrand().toUpperCase().contains("HUAWEI") || getDeviceBrand().toUpperCase().contains("NUBIA")) { intent.setClassName(NARMAL_PHONE[0], NARMAL_PHONE[1]); } else if (getDeviceBrand().toUpperCase().contains("XIAOMI") || getDeviceBrand().toUpperCase().contains("XIAOMI")) { intent.setClassName(MIUI_PHONE[0], MIUI_PHONE[1]); } else if (getDeviceBrand().toUpperCase().contains("SAMSUNG")) { intent.setClassName(SAMSUNG_PHONE[0], SAMSUNG_PHONE[1]); } startActivity(intent.createchooser (Intent, "share ")); } catch (Exception e) { e.printStackTrace(); Intent intent = new Intent(Intent.ACTION_SEND); intent.setData(Uri.parse("mailto:")); intent.putExtra(Intent.EXTRA_EMAIL, ""); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); StartActivity (intent.createchooser (Intent, "Share ")); }}}); } public static String getDeviceBrand() {log.e ("-- getDeviceBrand --:", android.os.Build.BRAND); return android.os.Build.BRAND; }}Copy the code

Method for acquiring the third party application Activity name: adb shell dumpsys Activity | findstr searches “mFocusedActivity” (under Windows)

 

extension

Adb shell Dumpsys activity————— Check out ActvityManagerService for adb shell Dumpsys activity Activities ———- Check Activity component information adb shell Dumpsys Activity services———– Check Service component information ADB shell Dumpsys Activity providers———- Show ContentProvider component information ADB shell Dumpsys activity broadcasts——– Show BraodcastReceiver adb Shell Dumpsys activity intents————– Adb shell Dumpsys activity processes———

Use the ADB shell command to view the activity currently interacting with the user

When doing android reverse, you sometimes need to know which Activity is in the current interface. In this case, you can use the ADB shell command to view the name of the Activity that is currently interacting with the user. First give the original address:

Stackoverflow.com/questions/1…

There are several methods to obtain:

Method one:

adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'
Copy the code

Query results are as follows:

TaskRecord indicates the queried record. Com.sina. Weibo is the package name, and.visitorMainTabActivity is the corresponding Activity name.

Method 2:

adb shell dumpsys activity | grep -i run
Copy the code

Query results are as follows:

Method 3:

adb shell dumpsys activity | grep "mFoc"
Copy the code

Query results are as follows:



MFocusedActivity is the Activity currently interacting with the user.

$shell = adb shell; $shell = adb shell;

This will not prompt you that “grep” is not an internal or external command, nor is it a runnable query