【问题标题】:Sending implicit intent to a broadcast receiver向广播接收器发送隐式意图
【发布时间】:2019-07-24 20:50:53
【问题描述】:

我正在尝试创建 2 个应用程序。第一个应用程序通过使用 sendBroadcast 的隐式意图发送 imei。下面是第一个应用程序的代码。

package com.example.activity_1;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    TextView tv_imei;

    Button bt_getimei;
    String imei;

    public static ArrayList<String> numbers;
    private SubscriptionManager subscriptionManager;
    static final Integer PHONESTATS = 0x1;
    private final String TAG = MainActivity.class.getSimpleName();

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

        tv_imei = (TextView) findViewById(R.id.tv_imei);

        bt_getimei = (Button) findViewById(R.id.bt_getimei);


        numbers = new ArrayList<String>();
        subscriptionManager = SubscriptionManager.from(MainActivity.this);

        bt_getimei.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                askForPermission(Manifest.permission.READ_PHONE_STATE, PHONESTATS);

                tv_imei.setText(imei);

                Intent sendImei = new Intent();
                sendImei.addFlags(sendImei.FLAG_INCLUDE_STOPPED_PACKAGES);
                sendImei.setAction("com.example.activity_1");
                sendImei.putExtra(Intent.EXTRA_TEXT, imei);
                sendImei.setType("text/plain");
                sendBroadcast(sendImei);

            }
        });

    }
private void askForPermission(String permission, Integer requestCode) {
    if (ContextCompat.checkSelfPermission(MainActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {

        // Should show an explanation
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {

            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);

        } else {

            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
        }
    } else {
        imei = getImeiNumber();


        Toast.makeText(this, permission + " is already granted.", Toast.LENGTH_SHORT).show();
    }
}


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1: {

            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                imei = getImeiNumber();


            } else {

                Toast.makeText(MainActivity.this, "You have Denied the Permission", Toast.LENGTH_SHORT).show();
            }
            return;
        }
    }
}


private String getImeiNumber() {
    final TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        //getDeviceId() is Deprecated so for android O we can use getImei() method
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return telephonyManager.getImei();
        }
        return telephonyManager.getImei();
    } else {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return telephonyManager.getImei();
        }
        return telephonyManager.getImei();
    }

}

}

我创建了另一个应用程序,其中包含一个用于接收 imei 的广播接收器。下面是application2的代码

    package com.example.activity_2;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import static android.content.Intent.EXTRA_TEXT;


public class MainActivity extends AppCompatActivity {


    TextView tv_imei;


    public class Receiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            StringBuilder imei= new StringBuilder();
            if (intent.getAction()==("com.example.activity_1")) {
                System.out.println("*****GOT THE INTENT********");
                StringBuilder append = imei.append("IMEI: " + intent.getExtras() + "\n");
                String log = imei.toString();
                Log.d("Received", log);
            }


        }
    }

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

        tv_imei = (TextView) findViewById(R.id.tv_imei);


        // Get intent, action and MIME type
        IntentFilter IMEI = new IntentFilter();
        IMEI.addAction("com.example.activity_1");
        IMEI.setPriority(100);
        BroadcastReceiver br = new Receiver();
        registerReceiver(br,IMEI);



    }
}

我不知道为什么第二个应用程序没有收到任何东西,因为我对 java 和一般编程一点也不熟悉。

提前谢谢你

【问题讨论】:

  • 您是否在应用的清单文件中指定了广播接收器?
  • 我正在研究 API 28,根据 android 文档,我必须在我的代码中而不是在清单文件中注册 mt 接收器。感谢您的评论
  • 其实需要在manifest文件中声明。该文档仅讨论隐式广播,而您正在使用显式广播。
  • 感谢您的更新。您能否向我解释一下隐式和显式意图之间在代码方面以及广播接收器方面的区别

标签: android broadcastreceiver android-implicit-intent


【解决方案1】:

简单来说,(详情请参考link

隐式意图是动作的目标。因此,使用该操作声明的所有广播接收器都将被调用。鉴于,

显式意图是针对特定组件的意图。所以只有那个特定的组件会收到意图。在您的情况下,它是 Receiver,您需要对代码进行一些更改才能使其正常工作。

在清单文件中声明以下内容。

 <receiver android:name=".MainActivity$Receiver">
    <intent-filter>
        <action android:name="com.example.activity_1"></action>
    </intent-filter>
</receiver>

在您的点击监听器中发送广播时。 您还需要定义该特定组件 (Receiver) 以明确意图。否则,意图将是隐含的,并且鉴于您正在使用 API 28,它将无法正常工作。

// pass Receiver class parameter to your Intent object to make the intent explicit.
Intent sendImei = new Intent(view.getContext(), Receiver.class); // change is required here
sendImei.addFlags(sendImei.FLAG_INCLUDE_STOPPED_PACKAGES);
sendImei.setAction("com.example.activity_1");
sendImei.putExtra(Intent.EXTRA_TEXT, imei);
sendImei.setType("text/plain");
sendBroadcast(sendImei);               

【讨论】:

  • 好吧,这是有道理的。不幸的是,我的任务要求使用隐含的意图来完成所有这些过程。这是否可以通过隐式意图实现上述场景。感谢您的帮助,感谢您抽出宝贵时间对此主题发表评论。
  • 你的任务是什么?如果您必须使用隐式意图,那么由于 API 28 后台执行限制,您需要使用“JobScheduler”或“WorkManager”。
  • 我被要求创建一个获取imei手机的应用程序,然后使用隐式意图将其发送到另一个应用程序。同时我必须创建第三个应用程序,它将拦截此通信并检索imei 基本上没有人弄清楚。
  • 实际上在 API 28 中,系统强烈不鼓励在后台与其他应用共享数据。另一种方法是动态注册接收器link。您将能够使用隐式意图,但这需要您的应用在内存中。
  • 您还在寻找解决方案吗?我找到了一种解决方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
相关资源
最近更新 更多