Android运用手机多媒体

本文详细介绍了如何在Android平台上实现短信的接收和发送功能,包括如何注册广播接收器获取短信内容以及如何使用SmsManager发送短信。此外,还讲解了如何调用手机摄像头拍照以及从相册选择图片,涉及权限配置和回调处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 接收和发送短信

1.1 接收短信

思路:当手机收到一条短信,会发出一条广播,通过注册广播接收器得知,然后获取短信,显示。

1.1.1 Manifest.xml 注册:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

1.1.2 在布局文件我们简单用两个textView分别显示短信的发送者还有短信内容。在Activity文件中当然是获取实例然后setText()设置控件的内容。
Activity中我们定义一个内部类MessageReceiver继承BroadcastReceiver,在onReceive()里写获取短信内容的逻辑。
首先是获取一个Bundle,然后通过”pdus”键获得SMS pdus的数组,其中每一个pdu表示一条短信消息。接着使用SmsMessage的createFromPdu()方法把pdu字节数组转换为SmsMessage对象,调用其getOriginatingAddress()可获取发送号码,getMessageBody()可获取短信内容,把短信内容拼接起来就是一条完整信息啦。
最后显示在控件上就可以了。

    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];
            //String format = intent.getStringExtra("format");
            for(int i=0; i<messages.length; i++) {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            }
            String address = messages[0].getOriginatingAddress();
            String fullMsg = "";
            for(SmsMessage message: messages) {
                fullMsg += message.getMessageBody();
            }
            tvFrom.setVisibility(View.VISIBLE);
            tvMsg.setVisibility(View.VISIBLE);
            sender.setText(address);
            msg.setText(fullMsg);
        }
    }

1.1.3 当然还要注册这个接收器,使用动态注册

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

        //……

        //接收短信
        recvFilter = new IntentFilter();
        recvFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        receiver = new MessageReceiver();
        registerReceiver(receiver, recvFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }
1.2 发送短信

1.2.1 Manifest.xml 注册

<uses-permission android:name="android.permission.SEND_SMS"/>

1.2.2 我们在布局文件简单设置两个EditText用于接收号码输入和短信内容输入,一个Button用于触发发送短信的逻辑。
在onClick()方法中,使用SmsManager的getDefault()方法获取一个smsManager实例,然后使用smsManager的sendTextMessage()方法就能发送短信了。
sendTextMessage()参数:
destinationAddress 发送短信的地址(也就是号码)
scAddress 短信服务中心,如果为null,就是用当前默认的短信服务中心
text 短信内容
sentIntent 如果不为null,当短信发送成功或者失败时,这个PendingIntent会被广播出去成功的结果代码是Activity.RESULT_OK,或者下面这些错误之一 :RESULT_ERROR_GENERIC_FAILURERESULT_ERROR_RADIO_OFFRESULT_ERROR_NULL_PDU
对于 RESULT_ERROR_GENERIC_FAILURE, 这个sentIntent可能包括额外的”errorCode”,包含一些具体有用的信息帮助检查 。基于SMS控制的全部程序检查,如果 sentIntent 为null,则发信程序会被所有位置程序检查一遍,这样会导致发送时间延长。
deliveryIntent 如果不为null,当这个短信发送到接收者那里,这个PendtingIntent会被广播,状态报告生成的pdu(指对等层次之间传递的数据单位)会拓展到数据(”pdu”)

btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SmsManager smsManager = SmsManager.getDefault();

            smsManager.sendTextMessage(
            toer.getText().toString(), null,
            toContent.getText().toString(), null, null);
            }
        });

1.2.3 基于以上,我们已经可以发送短信了。检查发送是否成功要借助第四个参数sentIntent

btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SmsManager smsManager = SmsManager.getDefault();
                Intent sentIntent = new Intent("SENT_SMS_ACTION");
                PendingIntent pi = PendingIntent.getBroadcast(
                        MainActivity.this, 0, sentIntent, 0);
                smsManager.sendTextMessage(toer.getText().toString(), null,
                        toContent.getText().toString(), pi, null);
            }
        });
        sendFilter = new IntentFilter();
        sendFilter.addAction("SENT_SMS_ACTION");
        sendReceiver = new SendStateReceiver();
        registerReceiver(sendReceiver, sendFilter);

内部类SendStsteReceiver

    class SendStateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(getResultCode() == RESULT_OK) {
                Toast.makeText(MainActivity.this, "Send succeeded", Toast.LENGTH_LONG).show();
            }else {
                Toast.makeText(MainActivity.this, "Send failed", Toast.LENGTH_LONG).show();
            }
        }
    }

2 读取手机图片、调用摄像头拍照

2.1 调用手机摄像头

2.1.1 Manifest.xml 注册写入存储卡权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2.1.2 我们在布局文件简单设置一个ImageView用于展示图片,一个Button用于调用摄像头,调用摄像头后还会进入裁剪程序,然后展示图片。

        btnTakePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //new 一个新的文件对象,传入SD卡根目录,还有文件名称
                File outputImg = new File(Environment.getExternalStorageDirectory(), "output_img.jpg");
                try {
                    if (outputImg.exists()) {
                        outputImg.delete();
                    }
                    //根据抽象路径创建一个新的空文件
                    outputImg.createNewFile();
                }catch (IOException e) {
                    e.printStackTrace();
                }
                //转换成Uri对象,代表图片的唯一地址
                imgUri = Uri.fromFile(outputImg);
                //调用相机程序
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);//指定输出地址
                //这里使用的是带返回值的启动Activity的操作,这里传入的是自己定义的标识符,根据返回值进行不同的操作
                startActivityForResult(intent, TAKE_PHOTO);
            }
        });

根据返回值进行不同的操作

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) { //就是我们调用时传进去的
            case TAKE_PHOTO:
                if(resultCode == RESULT_OK) { //拍照成功,调用裁剪程序
                    Intent intent = new Intent("com.android.camera.action.CROP");
                    intent.setDataAndType(imgUri, "image/*"); //设置数据和类型
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri); //设置输出路径
                    startActivityForResult(intent, CROP_PHOTO);
                }
                break;
            case CROP_PHOTO:
                if(resultCode == RESULT_OK) { //裁剪成功,展示图片
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(
                                getContentResolver().openInputStream(imgUri));
                        picture.setImageBitmap(bitmap);
                    }catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
    }
2.2 调用相册选择手机图片

2.2.1 同样一个Button触发选择图片

btnChoose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("android.intent.action.GET_CONTENT");
                intent.setType("image/*");
                startActivityForResult(intent, CHOOSE_PHOTO);
            }
        });

根据返回值进行不同操作

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case TAKE_PHOTO:
                if(resultCode == RESULT_OK) {
                    Intent intent = new Intent("com.android.camera.action.CROP");
                    intent.setDataAndType(imgUri, "image/*");
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);
                    startActivityForResult(intent, CROP_PHOTO);
                }
                break;
            case CROP_PHOTO:
                if(resultCode == RESULT_OK) {
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(
                                getContentResolver().openInputStream(imgUri));
                        picture.setImageBitmap(bitmap);
                    }catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case CHOOSE_PHOTO:
                if(resultCode == RESULT_OK) { 
                //因为sdk19以后返回的数据不同,所以要根据手机系统版本进行不同的操作
                    //判断手机系统版本
                    if(Build.VERSION.SDK_INT >= 19) {
                        handleImageOnKiKai(data);
                    }else {
                        handleImageBeforeKiKai(data);
                    }
                }
                break;
            default:
                break;
        }
    }

不同SDK不同的操作:

    //>=19的操作
    @TargetApi(19)
    private void handleImageOnKiKai(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();
        if(DocumentsContract.isDocumentUri(this, uri)) {
            //如果是Document类型的Uri,则通过document id 处理
            String docId = DocumentsContract.getDocumentId(uri);
            if("com.android.providers.media.documents".equals(uri.getAuthority())) {
                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            }else if("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
            }else if("content".equalsIgnoreCase(uri.getScheme())) {
                //不是document类型的Uri,普通方法处理
                imagePath = getImagePath(uri, null);
            }
            displayImage(imagePath);
        }
    }

    //<19的操作
    private void handleImageBeforeKiKai(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        displayImage(imagePath);
    }

    private String getImagePath(Uri uri, String selection) {
        String path = null;
        //通过Uri 和selection获取真正的图片路径
        Cursor cursor = getContentResolver().query(
                uri, null, selection, null, null);
        if(cursor != null) {
            if(cursor.moveToFirst()) {
                path = cursor.getString(
                        cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

    private void displayImage(String path) {
        if(path != null) {
            Bitmap bitmap = BitmapFactory.decodeFile(path);
            picture.setImageBitmap(bitmap);
        }else {
            Toast.makeText(this, "Load Failed", Toast.LENGTH_LONG).show();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值