안드로이드(Android)

안드로이드 이론 빡공 17

KyeongMin 2020. 6. 29. 17:34
728x90
반응형

**Manifest.xml**

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.threedpit.myreceiver">
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <!--이게 위험 권한이라 activity에 나오게 해야한다.
    그것을 한번에 하는법이 있다.
    -->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <receiver
            android:name=".SmsReceiver"
            android:enabled="true"
            android:exported="true">

            <!--intent-filter는 인텐트가 왔을때
             그중에 내가 원하는 것만 필터로 걸러내는것-->
            <intent-filter>
                <!--액션의 정보가 sms 메시지가 들어가 있는
                인텐트 객체의 액션 정보가 같다.
                -->
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>

        </receiver>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

위와 같이 작성을해주시고

**SmsReceiver.java**

package com.threedpit.myreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.util.Log;

public class SmsReceiver extends BroadcastReceiver {
    private  static final String TAG = "SmsReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
            Log.d(TAG,"onReceive 호출됨");

            Bundle bundle = intent.getExtras();
            //이 번들에는 extraData인 부가데이터가 들어있다.
            //이 번들객체를 파싱하는 메소드
            SmsMessage[] messages =  parseSmsMessage(bundle);
            // SmsMessage이 클래스는 이미 이api 안드로이드에
            //정의 되어있다.  이게 표준 프로토콜을 이용해서 서로
            //메세지를 주고 받게 되어있는데 이게 미리 객체로 만들어 놓은것


        //sms 메세지는 그냥 할수 없기 때문에 권한설정이 필요하다.
        if(messages !=null && messages.length>0){//1건이라도 있으면
            String sender = messages[0].getOriginatingAddress();//전화번호
            String contents = messages[0].getMessageBody();

            Log.d(TAG,"sender : "+ sender +"contents : "+ contents);
        }
    }
    private SmsMessage[] parseSmsMessage(Bundle bundle) {
        //pdus 는 표준프로토콜에 맞춰넘어온것
        Object[] objs = (Object[]) bundle.get("pdus");
        SmsMessage[] messages = new SmsMessage[objs.length];


        int smsCount = objs.length;
        for (int i = 0; i < smsCount; i++) {
            //안드로이드 버전마다다름 if는 23이상이면 위에꺼로 아니면 아래로 해라 의미
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                String format = bundle.getString("format");
                messages[i] = SmsMessage.createFromPdu((byte[]) objs[i], format);
            } else {
                messages[i] = SmsMessage.createFromPdu((byte[]) objs[i]);
            }
        }
        return messages;
    }
}

위험 권한 설정을 위한 라이브러리 가져오기

**build.gradle**

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.threedpit.myreceiver"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}
//이것을 추가---------------------------------------------------
allprojects{
    repositories {
        maven {url 'http://jitpack.io'}
    }
}
//------------------------------------------------------------

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//이것을 추가---------------------------------------------------
    implementation 'com.github.pedroSG94:AutoPermissions:1.0.3'
//------------------------------------------------------------

}

**MainActivity.java**

package com.threedpit.myreceiver;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Toast;

import com.pedro.library.AutoPermissions;
import com.pedro.library.AutoPermissionsListener;

public class MainActivity extends AppCompatActivity implements AutoPermissionsListener {


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

        //필요한 위험 권한 을 다 띄워줌
        AutoPermissions.Companion.loadAllPermissions(this,101);

    }
    // 위험권한에 대한것이 나올때 사용자가 거부를 했는지 승인을 했는지 나옴
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        AutoPermissions.Companion.parsePermissions(this,requestCode,permissions,this);
    }

    @Override
    public void onDenied(int requestCode, String[] permissions) {
        showToast("권한 거부된 것"+ permissions.length);
    }

    @Override
    public void onGranted(int requestCode, String[] permissions) {
        showToast("권한 승인된 것" + permissions.length);
    }

     public void showToast(String data ){
         Toast.makeText(this,data,Toast.LENGTH_LONG).show();
     }
}

**SmsReceiver.java**

package com.threedpit.myreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.util.Log;

public class SmsReceiver extends BroadcastReceiver {
    private  static final String TAG = "SmsReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
            Log.d(TAG,"onReceive 호출됨");

            Bundle bundle = intent.getExtras();
            //이 번들에는 extraData인 부가데이터가 들어있다.
            //이 번들객체를 파싱하는 메소드
            SmsMessage[] messages =  parseSmsMessage(bundle);
            // SmsMessage이 클래스는 이미 이api 안드로이드에
            //정의 되어있다.  이게 표준 프로토콜을 이용해서 서로
            //메세지를 주고 받게 되어있는데 이게 미리 객체로 만들어 놓은것


        //sms 메세지는 그냥 할수 없기 때문에 권한설정이 필요하다.
        if(messages !=null && messages.length>0){//1건이라도 있으면
            String sender = messages[0].getOriginatingAddress();//전화번호
            String contents = messages[0].getMessageBody();

            Log.d(TAG,"sender : "+ sender +"contents : "+ contents);
         
         
            //추가한것---------------------------------------
            //데이터 다른 액티비티로 보내기
            sendToActivity(context,sender,contents);
            //------------------------------------------------
            
            
        }
    }
    
    
    //추가한것---------------------------------------
    public void sendToActivity (Context context, String sender, String contents){
        Intent intent = new Intent(context,SmsActivity.class);

        //화면이 없는것에서 화면을 띄우는것이기 때문에
        //Flag 해줘야한다. 아래의 single top은
        //기존의sms액티비티 떠있으면 두번째 보낼때는 새로 만들지 않고 재사용
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.putExtra("sender",sender);
        intent.putExtra("contents",contents);

        context.startActivity(intent);
    }
//------------------------------------------------------
    
    
    private SmsMessage[] parseSmsMessage(Bundle bundle) {
        //pdus 는 표준프로토콜에 맞춰넘어온것
        Object[] objs = (Object[]) bundle.get("pdus");
        SmsMessage[] messages = new SmsMessage[objs.length];


        int smsCount = objs.length;
        for (int i = 0; i < smsCount; i++) {
            //안드로이드 버전마다다름 if는 23이상이면 위에꺼로 아니면 아래로 해라 의미
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                String format = bundle.getString("format");
                messages[i] = SmsMessage.createFromPdu((byte[]) objs[i], format);
            } else {
                messages[i] = SmsMessage.createFromPdu((byte[]) objs[i]);
            }
        }
        return messages;
    }
}

데이터를 넘기는것을 추가해줍니다. 그리고 받는 화면인

**SmsActivity.java**

package com.threedpit.myreceiver;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class SmsActivity extends AppCompatActivity {

    TextView textView1;
    TextView textView2;
    TextView textView3;

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

        textView2 = findViewById(R.id.textView2);
        textView3 = findViewById(R.id.textView3);

        Intent intent = getIntent();
        processIntent(intent);

    }
    //현재 onCreate는 실행된거라
    //intent는 onNewIntent로 받아지기때문에 아래와 같이 해준다.

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
       // 액티비티는 미리 만들어져있는 상태에서
       // intent만 전달되기때문에 이렇게 해준다.
        processIntent(intent);
    }

    public void processIntent(Intent intent){
        if(intent != null){
         String sender = intent.getStringExtra("sender");
         String contents = intent.getStringExtra("contents");

            textView2.setText(sender);
            textView3.setText(contents);
        }
        else{
            finish();
        }
    }
}

**activity_sms.xml**

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".SmsActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="수신한 문제 메세지" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="발신 번호" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="문자내용" />
</LinearLayout>

 

 

부가적인 위험권한과 매니패스트 그래들

 

이미지 출처 : [2020 Do it! 안드로이드 앱 프로그래밍(개정7판)](

728x90
반응형