Hands-on Lab Test: Handling Broadcast Intent’s with custom permission.
Let’s begin with secured Broadcast intent handling. We are going to use the theories we have discussed in the prelab section to secure the intents from malicious applications. To begin go to your Android Studio, please follow the following steps:
First, create a new Android Studio project, click on "File-->New-->New Project"
Choose "Empty Activity" and click "Next"
Name it "InterAppSender" and click on Finish button
Right Click on "com.arabin.interappsender--> New-->Java Class"
Name the class as "CustomData"
Follow the Step Four and Name the class as "AppCustomListerner"
Follow the Step Four and Name the class as "ShowResultOfReceiver"
Copy and paste all the following code in the specified Java and XML file
//Copy and paste the following codes into MainActivity.java file.
//MainActivity.java
package com.arabin.interappsender;
import androidx.appcompat.app.AppCompatActivity;
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 androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private EditText name, password;
private Context context;
public MainActivity(){
this.context = MainActivity.this;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = findViewById(R.id.name);
password = findViewById(R.id.password);
MainActivity.this.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String name = bundle.getString("userName");
String password = bundle.getString("password");
Intent show = new Intent(MainActivity.this,ShowResultOfReceiver.class);
show.putExtra("name",name);
show.putExtra("password",password);
startActivity(show);
}
},new IntentFilter("com.arabin.CUSTOM_ACTION"),
com.arabin.interappsender.Manifest.permission.CUSTOM_PERMISSION,null);
}
public void sendData(View view) {
int permission = Build.VERSION.SDK_INT>=23 ? ActivityCompat.checkSelfPermission(context,
com.arabin.interappsender.Manifest.permission.CUSTOM_PERMISSION):
ContextCompat.checkSelfPermission(context,com.arabin.interappsender.Manifest.permission.CUSTOM_PERMISSION);
if (permission != PackageManager.PERMISSION_DENIED){
CustomDialog dialog = new CustomDialog(context);
String title = "Permission";
String message = "Need to Allow this permission to send Data.";
String positiveButton = "Accept";
String negativeButton = "Deny";
dialog.showDialog(title,message,positiveButton,negativeButton);
dialog.setCustomDialogListerner(new AppCustomListerner() {
@Override
public void didPressedPositiveButton() {
Bundle bundle = new Bundle();
bundle.putString("userName",name.getText().toString());
bundle.putString("password",password.getText().toString());
Intent intent = new Intent("com.arabin.CUSTOM_ACTION");
intent.putExtras(bundle);
sendBroadcast(intent,com.arabin.interappsender.Manifest.permission.CUSTOM_PERMISSION);
}
});
}
}
}
//Copy and paste the following code in that XML file under the res=>layout folder
//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.arabin.interappsender.MainActivity">
<TextView
android:id="@+id/name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="95dp"
android:text="Username"
android:textSize="20dp"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/name"
android:layout_below="@+id/name_text"
android:layout_centerHorizontal="true"
android:ems="10"
android:background="#BED2CE"
android:layout_marginTop="5dp"
android:gravity="center"/>
<TextView
android:id="@+id/pass_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/name_text"
android:layout_below="@+id/name"
android:layout_marginTop="19dp"
android:text="Password"
android:textSize="20dp"/>
<EditText
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/pass_text"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:ems="10"
android:inputType="textPassword"
android:background="#BED2CE"
android:gravity="center"/>
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/name_text"
android:layout_below="@+id/password"
android:layout_marginTop="10dp"
android:text="Send"
android:onClick="sendData"/>
</RelativeLayout>
//Copy and paste the following code inside the activity_show_result_of_receiver.xml file under the res=>layout folder
//activity_show_result_of_receiver.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.arabin.interappsender.ShowResultOfReceiver">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="86dp"
android:layout_marginTop="68dp"
android:text="UserName"
android:background="#BED2CE"/>
<TextView
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/name"
android:layout_below="@+id/name"
android:layout_marginTop="30dp"
android:text="Password"
android:background="#BED2CE"/>
<TextView
android:id="@+id/userName"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/name"
android:layout_marginStart="38dp"
android:layout_toEndOf="@+id/name"
android:background="#669999"
android:gravity="center"/>
<TextView
android:id="@+id/pass"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/userName"
android:layout_alignTop="@+id/password"
android:background="#669999"
android:gravity="center"/>
</RelativeLayout>
We have to add our customized permission in the manifest.xml file to use it.
//So copy and paste the following code into your manifest.xml file
//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.arabin.interappsender">
<permission
android:name="com.arabin.interappsender.permission.CUSTOM_PERMISSION"
android:description="@string/description"
android:label="@string/label"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:protectionLevel="dangerous" />
<uses-permission android:name="com.arabin.interappsender.permission.CUSTOM_PERMISSION"/>
<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/Theme.InterAppSender">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ShowResultOfReceiver"/>
</application>
</manifest>
Now we are going to create a custom alert dialog to get user's acceptance of the custom permission on the “CustomDialog” file.
//Copy and paste the following code into the “CustomDialog.java” class
//CustomDialog.java
package com.arabin.interappsender;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import androidx.appcompat.app.AlertDialog;
public class CustomDialog {
private Context context;
private AppCustomListerner listerner;
public CustomDialog(Context context){
this.context = context;
}
public void setCustomDialogListerner(AppCustomListerner listerner){
this.listerner = listerner;
}
private void didPressPositiveButton(){
if (listerner != null){
listerner.didPressedPositiveButton();
}
}
public void showDialog(String title, String msg, String positiveButton, String negativeButton){
AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new AlertDialog.Builder(context, android.R.style.Theme_Material_Dialog_Alert);
} else {
builder = new AlertDialog.Builder(context);
}
builder.setTitle(title)
.setMessage(msg)
.setPositiveButton(positiveButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
didPressPositiveButton();
}
})
.setNegativeButton(negativeButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
}).setIcon(R.drawable.if_hazard_1055046)
.show();
}
}
Note: R.drawable.if_hazard_1055046 is a “.png” image file that has been stored in the "drawable" folder. You can download it at the end of this lab.
//Copy and paste the following code into the interface "AppCustomListerner.java"
//AppCustomListerner.java
package com.arabin.interappsender;
public interface AppCustomListerner {
void didPressedPositiveButton();
}
Also, Copy and paste the following code into "strings.xml"
//strings.xml
<resources>
<string name="app_name">InterAppSender</string>
<string name="label">Personal Permission</string>
<string name="description">Personal Permission to send an intent to other application or inter communications.</string>
</resources>
First, create a new Android Studio project and choose "Empty Activity". Click "Next"
Name it “ReceiverApp” with the company domain of "com.example.cipher.receiverapp" and click on Next
Right Click on "com.arabian.receiverapp--> New-->Java Class" and name it "MyReceiver"
In this MainActivity.java we are registering a receiver dynamically to pass data into ShowResultsOfReceriver activity. In sendData() method we are checking the availability of the permissions in the manifest.xml file through custom dialog. If permission is available and accepted by the user only then data will be sent through “sendBroadCast(intent, permission)”.
Now create another application name it ReceiverApp. This application is going to receive the intent sent from interAppSender if it has permission. Create the application the same way we did before. After that copy and paste the following code into manifest.xml file
//manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.arabin.receiverapp">
<uses-permission android:name="InterAppSenderPackageName.permission.CUSTOM_PERMISSION"/>
<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/Theme.ReceiverApp">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyReceiver"
android:exported="true">
android:permission="InterAppSenderPackageName.permission.CUSTOM_PERMISSION">
<intent-filter>
<action android:name="com.arabin.CUSTOM_ACTION"/>
</intent-filter>
</receiver>
</application>
</manifest>
Here we are declaring receiver in the manifest.xml file and also giving the access of custom permission we have created in interAppSender application. We are also giving the authority to the receiver to receive intent sent from the broadcast sending method, containing the same action name. Now go to activity_main.xml file and paste the following code
//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context="com.arabin.receiverapp.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is a broadcast interceptor\n ReceiverApp-Secured Version, Interapp permission"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now create a java class named MyReceiver extend it with Broadcastreceiver. Copy and paste the following code in the //MyReceiver.java file
package com.arabin.receiverapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String userName = bundle.getString("userName");
String password = bundle.getString("password");
final Toast tag = Toast.makeText(context, "Intercepting from Receiver app(secured version)\nUsername "+userName+"\n"+"Password "+password+"\n" ,Toast.LENGTH_SHORT);
tag.show();
new CountDownTimer(10000, 1000)
{
public void onTick(long millisUntilFinished) {tag.show();}
public void onFinish() {tag.show();}
}.start();
}
}
First, create a new Android Studio project and choose "Empty Activity". Click "Next"
Name it “UnwantedReceiverApp” with the company domain of "com.arabian.unwantedreceiverapp" and click on Next
Right Click on "com.arabian.unwantedreceiverapp--> New-->Java Class" and name it "MyReceiver"
Now create another Receiver application name it UnwantedReceiverApp copy and paste the following code to its
//manifest.xml file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.arabin.unwantedreceiverapp">
<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/Theme.UnwantedReceiverApp">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.arabin.CUSTOM_ACTION"/>
</intent-filter>
</receiver>
</application>
</manifest>
Here you can see we have registered a receiver with the same action name as interAppSenderApp and ReceiverApp. Again create a MyReceiver in this app and extend it with BroadcastReceiver paste the following code in it.
//MyReceiver.java
package com.arabin.unwantedreceiverapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String userName = bundle.getString("userName");
String password = bundle.getString("password");
final Toast tag = Toast.makeText(context, "Unwanted Interception from " +
"InterAppSender app(secured version)\nUsername "+userName+"\n"+"Password "+password+"\n" ,Toast.LENGTH_SHORT);
tag.show();
new CountDownTimer(10000, 1000)
{
public void onTick(long millisUntilFinished) {tag.show();}
public void onFinish() {tag.show();}
}.start();
}
}
Now we are ready to go install this application on an emulator or on a device one by one.
Start the InterAppSender give a demo text in the Username and password field. See image below
Save every project and run it on the AVD that shall show this interface
Enter a username and password to test
A pop-up shall be showing up
The Interfaces shall show the interception from InterAppSender
Interfaces for the ReceiverApp
The Interfaces shall show "Unwanted Interception" from InterAppSender if you change copy and paste the following code into Androidmanifest file under UnwantedReceiverApp.
But if we give access to the UnwantedReceiverApp then this application will also receive the same data, copy and paste the following code into the Androidmanifest file under UnwantedReceiverApp.
//Androidmanifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="YourPackageName">
<uses-permission android:name="YourPackageName.permission.CUSTOM_PERMISSION"/>
<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/Theme.UnwantedReceiverApp">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyReceiver"
android:permission="YourPackageName.permission.CUSTOM_PERMISSION">
<intent-filter>
<action android:name="com.arabin.CUSTOM_ACTION"/>
</intent-filter>
</receiver>
</application>
</manifest>
This is all about customized permission and its use in case of Broadcast sending option with permission.
Reference: https://developer.android.com/index.html.