安卓移动-作业7

1 实验目的 (Experiment Purpose)

  1. Be familiar with the broadcast mechanism of Android operating system.
  2. Be familiar with the static and dynamic registration methods of broadcast receivers.
  3. Be familiar with the Notification notification function of Android.
  4. Understand the difference between synchronous and asynchronous message processing.
  5. Master the management method of notification.

熟悉Android操作系统的广播机制。
熟悉广播接收器的静态注册和动态注册方式。
熟悉 Android 的 Notification 通知功能。
理解同步和异步消息处理的区别。
掌握通知的管理方式。

2 实验环境 (Experiment Environment)

software: Android Studio 2021.2.1 Patch 2
Operating system:Window 10

3 实验内容 (Experiment content)

3.1 Experimental data

Set the string in Android/app/res/layout/value/strings.xml.
在 Android/app/res/layout/value/strings.xml中制定字符串。

<resources>
    <string name="app_name">experiment4</string>
    <string name="send_define">发送自定义广播</string>
    <string name="send_local">发送本地广播</string>
    <string name="send_email">发送邮件</string>
    <string name="send_sms">发送短信</string>
</resources>

Set the layoutin Android/app/res/layout/value/layout.
在 Android/app/res/layout/value/layout中制定布局。

3.2 Experimental process

需求
  1. Write programs to receive system broadcast messages, monitor
    startup, network status changes, and power supply and power changes.
  2. Write programs to send and receive local broadcast messages.
  3. Write a program to send mail.
  4. The app sends a notification after receiving a new email.
  5. Use PendingIntent to open the activity corresponding to the
    notification.
  6. 6. Write a program to realize the SMS sending and receiving
    function. Compile, debug and view program running results.

编写程序接收系统广播消息,监听开机启动、网络状态变化以及电源电量变化。
编写程序发送本地广播消息,同时接收本地广播消息。
编写程序发送邮件。
应用接收到新的邮件后发送通知。
使用PendingIntent打开通知对应的活动。
编写程序实现短信收发功能。
编译、调试和查看程序运行结果。

步骤

Set the listener of each button in BradcastActivity to receive broadcast, send broadcast, jump to send email and jump to send SMS.
在BradcastActivity中设定每个按钮的监听器,分别实现接受广播,发送广播,跳转发送邮件,跳转发送短信功能。

package com.example.experiment4;

import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.example.experiment4.receiver.LocalReceiver;
import com.example.experiment4.receiver.NetworkChangeReceiver;
import com.example.experiment4.receiver.UserDefinedBroadcastReceiver;

public class BroadcastActivity extends AppCompatActivity {
    NetworkChangeReceiver netChangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcast);

        // 接收网络状态变化广播
        IntentFilter netConnIntentFilter = new IntentFilter();
        netConnIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        netChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(netChangeReceiver, netConnIntentFilter);

        // 接收电量变化广播
        Intent batteryIntent = getApplicationContext().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        int currLevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
        int total = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
        int percent = currLevel * 100 / total;
        Log.i("BatteryChangeReceiver", "battery: " + percent + "%");

        // 接收本地广播
        LocalReceiver localReceiver = new LocalReceiver();
        final LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
        IntentFilter localIntentFilter = new IntentFilter("pers.cnzdy.mobilerookie.LOCAL_BROADCAST");
        localBroadcastManager.registerReceiver(localReceiver, localIntentFilter);

        // 发送本地广播
        Button local_button  = findViewById(R.id.local_button);
        local_button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Intent intentLocal = new Intent("pers.cnzdy.mobilerookie.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intentLocal);

            }
        });


        //接收自定义广播
        IntentFilter userDefinedFilter = new IntentFilter("pers.cnzdy.mobilerookie.USER_DEFINE");
        registerReceiver(new UserDefinedBroadcastReceiver(), userDefinedFilter);

        // 发送自定义广播
        Button button = findViewById(R.id.user_button);
        button.setOnClickListener(v->
            {
                Intent intent = new Intent("pers.cnzdy.mobilerookie.USER_DEFINE");
                sendBroadcast(intent);
            });


        //跳转到发送邮件
        Button sendButton  = findViewById(R.id.send_email);
        sendButton.setOnClickListener(v->{
            Intent intent = new Intent(BroadcastActivity.this,EmailActivity.class);
            startActivity(intent);
        });

        //新邮件广播
        IntentFilter emailIntentFilter = new IntentFilter();
        registerReceiver(new EmailActivity.EmailReceiver(), emailIntentFilter);

        //发送短信
        Button smsButton  = findViewById(R.id.send_sms);
        smsButton.setOnClickListener(v->{
            Intent intent = new Intent(BroadcastActivity.this,SMSActivity.class);
            startActivity(intent);
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (netChangeReceiver != null)
            unregisterReceiver(netChangeReceiver);

//        if (messageReceiver != null)
//            unregisterReceiver(messageReceiver);
    }

}

Realize the function of sending email in EmailActivity.
在EmailActivity中实现发送邮件功能。

package com.example.experiment4;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class EmailActivity extends AppCompatActivity{
    private Button sendBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_email);

        sendBtn = (Button) findViewById(R.id.send_btn);
        sendBtn.setOnClickListener((view)->sendEmail());
    }
    private void sendEmail(){
        Intent data=new Intent(Intent.ACTION_SENDTO);
        data.setData(Uri.parse("mailto:cn_zdy@126.com"));
        data.putExtra(Intent.EXTRA_SUBJECT, "提交答案");
        data.putExtra(Intent.EXTRA_TEXT, "下面给出题目的回答:");
        startActivity(data);
    }

    static class EmailReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            Toast.makeText(context, "接收到新邮件", Toast.LENGTH_SHORT).show();
        }
    }

在SMSActivity中实现发送短信功能

package com.example.experiment4;

import android.Manifest;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class SMSActivity extends AppCompatActivity
{
    private static final String TAG = "SMSActivity";
    private static final int SEND_SMS_PERMISSION = 100;

    private TextView textViewSender;
    private TextView textViewContent;
    private IntentFilter receiveFilter;
    private IntentFilter sendFilter;
    private MessageReceiver messageReceiver;
    private EditText editTextTo;
    private EditText editTestMsg;

    private SendStatusReceiver sendStatusReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sms);

        textViewSender = findViewById(R.id.sender);
        textViewContent = findViewById(R.id.content);

        receiveFilter = new IntentFilter();
        receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        messageReceiver = new MessageReceiver();
        registerReceiver(messageReceiver, receiveFilter);

        sendFilter = new IntentFilter();
        sendFilter.addAction("SENT_SMS_ACTION");
        sendStatusReceiver = new SendStatusReceiver();
        registerReceiver(sendStatusReceiver, sendFilter);
    }

    // 在AndroidManifest中也要设置接收和发送短信权限
//    <uses-permission android:name="android.permission.SEND_SMS" />
//    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    private void requestPermission()
    {
        //判断Android版本是否大于23
        // TODO:需要修改CALL_PHONE
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            int checkCallPhonePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
            if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED)
            {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_SMS}, SEND_SMS_PERMISSION);
                return;
            }
            else
            {
                //已有权限
                sendSMS();
            }
        }
        else
        {
            //API 版本在23以下
        }
    }

    /**
     * 注册权限申请回调
     *
     * @param requestCode  申请码
     * @param permissions  申请的权限
     * @param grantResults 结果
     */
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] grantResults)
    {
        switch (requestCode)
        {
            case SEND_SMS_PERMISSION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
                {
                    sendSMS();
                }
                else
                {
                    // 拒绝授权
                    Toast.makeText(SMSActivity.this,
                            "CALL_PHONE Denied", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    public void onClick(View source)
    {
        requestPermission();
    }

    private void sendSMS()
    {
        editTextTo = findViewById(R.id.to);
        editTestMsg = findViewById(R.id.msg_input);

        String content = editTestMsg.getText().toString().trim();
        // 模拟器号码:+1-555-521-5554
        String phone = editTextTo.getText().toString().trim();

        if (!TextUtils.isEmpty(content) && !TextUtils.isEmpty(phone))
        {
            Intent sentIntent = new Intent("SENT_SMS_ACTION");
            PendingIntent pi = PendingIntent.getBroadcast(
                    SMSActivity.this, 0, sentIntent, 0);

            SmsManager smsManager = SmsManager.getDefault();
            smsManager.sendTextMessage(phone, null, content, pi,
                    null);
        }
        else
        {
            Toast.makeText(this, "手机号或内容不能为空",
                    Toast.LENGTH_SHORT).show();
        }
    }

    class SendStatusReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            if (getResultCode() == RESULT_OK)
            {
                Toast.makeText(context, "发送成功",
                        Toast.LENGTH_LONG).show();
            }
            else
            {
                Toast.makeText(context, "发送失败",
                        Toast.LENGTH_LONG).show();
            }
        }
    }

    // 运行Andriod Device Monitor,用Emulator Control给模拟器发送短信
    // Andriod Device Monitor的路径为:
    // C:\Users\Administrator\AppData\Local\Android\Sdk\tools\lib\monitor-x86_64
    class MessageReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            Bundle bundle = intent.getExtras();
            Object[] pdus = (Object[]) bundle.get("pdus");

            SmsMessage[] messages = new SmsMessage[pdus.length];
            for (int i = 0; i < messages.length; i++)
            {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            }

            String address = messages[0].getOriginatingAddress();
            String fullMessage = "";
            for (SmsMessage message : messages)
            {
                fullMessage += message.getMessageBody();
            }

            textViewSender.setText(textViewSender.getText() + "  " + address);
            textViewContent.setText(textViewContent.getText() + "  " + fullMessage);
        }
    }
}

3.3 Experimental results

The results display and code implementation are shown as follows:
结果展示和代码实现如下图:
功能选择页面:

The following shows the sending of custom broadcast and local broadcast. It can be seen that the prompts of “custom broadcast” and “local broadcast” appear below
以下展示发送自定义广播和发送本地广播
可以看出,下方出现了“自定义广播”和“本地广播”的提示

The following shows the functions of sending email and SMS.
以下展示发送邮件和发送短信功能。

4 实验小结 (Summary)

My thoughts and experiences

Android 操作系统如何广播消息?
  • 动态注册广播
    写一个广播接收器,继承自BroadcastReceiver类
    实例化接收器和意图过滤器,添加action
    调用registerReceiver注册广播接收器
  • 静态注册广播
    写一个广播接收器,继承自BroadcastReceiver类
    在AndroidMainfest.xml文件中注册,添加<<receiver>和<intent-filter>
  • 发送标准广播
    定义intent,sendBroadcast(intent)
  • 发送有序广播
    (略)
应用如何发送自定义的广播消息?
  • 准备一个接收器用于接受发送的广播
  • 在 AndroidManifest.xml 中注册广播的值
  • 活动代码中:定义intent,定义componentName,调用setComponent方法,sendBroadcast(intent)。
应用如何向用户发送通知?

通过通知栏(Notification)。

  • 小图标:必须提供,通过 setSmallIcon() 进行设置。
  • 应用名称:由系统提供。
  • 时间戳:由系统提供,但您可以使用 setWhen() 替换它或者使用
    setShowWhen(false) 隐藏它。
  • 大图标:可选内容(通常仅用于联系人照片,请勿将其用于应用图标),通过
    setLargeIcon() 进行设置。
  • 标题:可选内容,通过 setContentTitle() 进行设置。
  • 文本:可选内容,通过 setContentText() 进行设置。
应用如何实现通知的管理?

通过在调用NotificationManager.notify(ID,
notification)时所使用的ID来更新它。
为了更新之前发布的通知,需要更新或者创建一个NotificationCompat.Builder对象,从之前的通知中创建一个Notification对象,然后发布它使用之前使用的ID。如果之前的通知仍然可见,系统将直接更新通知的内容,如果之前的通知不可见了,一条新的通知将被创建。

代码

gitee代码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值