嗨,我想编写一个程序,接收传入的SMS并将其列出。

但是我有一个问题。

收到短信后,它就不会出现在活动列表中,而当我打开活动时,程序将停止。

java - android编程中的传入短信列表-LMLPHP

我有两个类:ReceiveMessage和SmsInbox。

ReceiveMessage:

 public class ReceiveMessage extends BroadcastReceiver {

final SmsManager mysms = SmsManager.getDefault();
@Override
public void onReceive(Context context, Intent intent) {

    Bundle mybundel = intent.getExtras();
    try {

        if(mybundel !=null){
            final Object[] messageContent=(Object[])mybundel.get("pdus");
            String smsMessageStr = "";
            for (int i=0;i<messageContent.length;i++){

                SmsMessage mynewsms = SmsMessage.createFromPdu((byte[])    messageContent[i]);
                NewMessageNotification nome = new  NewMessageNotification();
                nome.notify(context,mynewsms.getDisplayOriginatingAddress(),mynewsms.getDisplayMessageBody(),i);
                i++;

                String smsBody = mynewsms.getMessageBody().toString();
                String address = mynewsms.getOriginatingAddress();

                smsMessageStr += "SMS From: " + address + "\n";
                smsMessageStr += smsBody + "\n";
            }
            Toast.makeText(context, smsMessageStr, Toast.LENGTH_SHORT).show();

            //this will update the UI with message
            SmsInbox inst = SmsInbox.instance();
            inst.updateList(smsMessageStr);
        }
    }
    catch (Exception ex){

    }
}


SmsInbox:

     public class SmsInbox extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener, AdapterView.OnItemClickListener {

private static SmsInbox inst;
ArrayList<String> smsMessagesList = new ArrayList<String>();
ListView smsListView;
ArrayAdapter arrayAdapter;

public static SmsInbox instance() {
    return inst;
}

@Override
public void onStart() {
    super.onStart();
    inst = this;
}

DrawerLayout drawer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sms_inbox);
    smsListView = (ListView) findViewById(R.id.SmsList);
    arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, smsMessagesList);
    smsListView.setAdapter(arrayAdapter);
    smsListView.setOnItemClickListener(this);

    ContentResolver cr = getContentResolver();
    Cursor cursor = cr.query(Uri.parse("content://sms/inbox"), null, null,
            null, null);

    int indexBody = cursor.getColumnIndex("body");
    int indexAddr = cursor.getColumnIndex("address");

    if (indexBody < 0 || !cursor.moveToFirst()) return;
    arrayAdapter.clear();
    do {
        String str = "SMS From: " + cursor.getString(indexAddr) +
                "\n" + cursor.getString(indexBody) + "\n";
        arrayAdapter.add(str);
    } while (cursor.moveToNext());


    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);


    drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();
    toggle.setDrawerIndicatorEnabled(false);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);


}

public void updateList(final String smsMessage) {
    arrayAdapter.insert(smsMessage, 0);
    arrayAdapter.notifyDataSetChanged();
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
    try {
        String[] smsMessages = smsMessagesList.get(pos).split("\n");
        String address = smsMessages[0];
        String smsMessage = "";
        for (int i = 1; i < smsMessages.length; ++i) {
            smsMessage += smsMessages[i];
        }

        String smsMessageStr = address + "\n";
        smsMessageStr += smsMessage;
        Toast.makeText(this, smsMessageStr, Toast.LENGTH_SHORT).show();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.END)) {
        drawer.closeDrawer(GravityCompat.END);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.menuRight) {
        if (drawer.isDrawerOpen(Gravity.RIGHT)) {
            drawer.closeDrawer(Gravity.RIGHT);
        } else {
            drawer.openDrawer(Gravity.RIGHT);
        }
        return true;
    }

    return super.onOptionsItemSelected(item);
}


@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.

    int id = item.getItemId();

    if (id == R.id.Home_page) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    } else if (id == R.id.not_pay) {

        if (SmsInbox.this.drawer != null && SmsInbox.this.drawer.isDrawerOpen(GravityCompat.END)) {
            SmsInbox.this.drawer.closeDrawer(GravityCompat.END);
        } else {
            Intent intent = new Intent(this, MainActivity.class);
            SmsInbox.this.startActivity(intent);
            overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

        }

    } else if (id == R.id.date_pay) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    } else if (id == R.id.bill_sms) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    } else if (id == R.id.help_menu) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    } else if (id == R.id.for_us) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    } else if (id == R.id.exit_app) {
        finish();
        overridePendingTransition(0, 0);
    }


    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.END);
    return true;
}


@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}


SmsInbox布局:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:id="@+id/MainLayout"
   >

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:text="SMS Inbox"
    android:id="@+id/textView"
    android:layout_gravity="center_horizontal" />

    <ListView android:id="@+id/SMSList"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_margin="5dp" />

   </LinearLayout>


打开活动时进行调试:

java - android编程中的传入短信列表-LMLPHP

其他调试:

java - android编程中的传入短信列表-LMLPHP


我收到短信没有问题。我无法列出他们。


表现:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mahdishekari.mycollectbill">
//permission baraye ersal sms dar mainActivity2.
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="au.com.example.READ_CONTENT" />
<uses-permission android:name="au.com.example.WRITE_CONTENT" />
<uses-permission android:name="android.permission.VIBRATE" />

<application
    android:name=".MyFontApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".BarcodScanner"
        android:label="@string/title_activity_barcod_scanner"
        android:parentActivityName=".MainActivity"
        android:theme="@style/AppTheme.NoActionBar">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.mahdishekari.mycollectbill.MainActivity" />
    </activity>
    <activity
        android:name=".SmsReceiver"
        android:label="@string/title_activity_sms_receiver"
        android:theme="@style/AppTheme.NoActionBar" />
    <activity
        android:name=".SmsInbox"
        android:label="SmsInbox"
        android:theme="@style/AppTheme.NoActionBar" />
    <receiver android:name=".ReceiveMessage" android:exported="true" >
        <intent-filter android:priority="999" >
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>

</application>




谢谢。

最佳答案

您应该添加

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


到Android清单。
如您在日志中所见,这是一个权限拒绝例外。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ces.cesday">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_SMS"/> //add this line only
    <application
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"

        android:theme="@style/AppTheme">



在SmsInbox中更改为此

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sms_inbox);
    smsListView = (ListView) findViewById(R.id.SmsList);
    arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, smsMessagesList);
    smsListView.setAdapter(arrayAdapter);
    smsListView.setOnItemClickListener(this);
if(ContextCompat.checkSelfPermission(getBaseContext(), "android.permission.READ_SMS") == PackageManager.PERMISSION_GRANTED) {

    ContentResolver cr = getContentResolver();
    Cursor cursor = cr.query(Uri.parse("content://sms/inbox"), null, null,
            null, null);

    int indexBody = cursor.getColumnIndex("body");
    int indexAddr = cursor.getColumnIndex("address");

    if (indexBody < 0 || !cursor.moveToFirst()) return;
    arrayAdapter.clear();
    do {
        String str = "SMS From: " + cursor.getString(indexAddr) +
                "\n" + cursor.getString(indexBody) + "\n";
        arrayAdapter.add(str);
    } while (cursor.moveToNext());
}

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);


    drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();
    toggle.setDrawerIndicatorEnabled(false);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);


}

10-07 22:22