Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: проверка кода под android

Скажите есть вариант проверки кода для netbeans или eclipse.
Ответ: для эклипс.

Поддержка плагина прекращена. Рекомендуют переходить на android studio.
Вопрос: Как вызват код, выполняющийся до старта первой Activity?

Добрый день!
Столкнулся с задачей, не знаю как её решить лучше. Хочу что бы некоторый код выполнялся при старте приложения, до появления первой Activity. Знаю что можно создать класс, унаследованный от Application. Это будет сингтон, живущий на всё протяжении жизни приложения и не зависящий ни от какой Activity. У меня есть такой класс MyApplication. Правильно ли вызывать мой код в методе onCreate()? написал заглушку Log.d, кажется работает так как надо.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package ru.arvalon.mytraining;
 
import android.app.Application;
import android.util.Log;
 
public class MyApplication extends Application {
 
    private static  MyApplication singleton;
 
    public static MyApplication getInstance(){
        return singleton;
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
        singleton=this;
        Log.d("norm","Singleton is started!");
        //TODO Место для будущего кода создания БД.
    }
    
    private String somevariable;
    public String getSomevariable() {
        return somevariable;
    }
    public void setSomevariable(String somevariable) {
        this.somevariable = somevariable;
    }
}
Правильно ли так делать, писать то что мне надо в классе наследнике Application в методе onCreate()?
Ответ: arvalon, да, нормально
Вопрос: Проверка скорости сетевого подключения

Мне необходимо осуществлять в своём приложении проверку скорости сетевого подключения.

Мною было принято решение разделять скорость подключения на быструю (высокую) и медленную (низкую).

Медленная скорость подключения предполагает собой скорость сетевого подключения меньше 100 kbps.

Все остальные скорости сетевого подключения больше этого значения считаются условно высокими (быстрыми) скоростями подключения.

Под заданный критерий для медленных скоростей подходят все скорости сетевых подключений, осуществляемых в 2G-сетях.

Я использую код, приведенный ниже для осуществления проверки скорости текущего используемого сетевого подключения на Android-устройстве.

В связи с тонкостями данной реализации у меня возникло несколько вопросов.

1. В каких случаях может возникать возможность того, что будет возвращаться значение TelephonyManager.NETWORK_TYPE_UNKNOWN?

2. Что это может означать и как обрабатывать эту ситуацию?

3. Что представляют собой такие типы возвращаемых значений для соединения как

- ConnectivityManager.TYPE_MOBILE_DUN,
- ConnectivityManager.TYPE_MOBILE_HIPRI,
- ConnectivityManager.TYPE_MOBILE_MMS,
- ConnectivityManager.TYPE_MOBILE_SUPL?

4. В каких случаях могут возвращаться эти значения на устройствах?

5. В реализованном алгоритме проверки скорости сетевого подключения для этих значений мною возвращается значение низкой (медленной) скорости подключения без дальнейшей проверки используют ли эти сетевые подключения сеть 2G или нет.

Насколько это правильно?

6. Насколько часто вообще устройства могут находится в режиме использования этих типов сетевых подключений?

7. В каких случаях может возникать ситуация, что метод isConnected() может возвращать true, а метод hasInternetAccess() будет возвращать false?

8. Какие рекомендации выдавать пользователю в таком случае для исправления сложившейся ситуации?

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.connectivitymanager;
 
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
 
/**
 * Check device's network connectivity and speed 
 */
 
public class Connectivity {
 
    /**
     * Get the network info
     * @param context
     * @return
     */
    public static NetworkInfo getNetworkInfo(Context context){
        
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }
    
    /**
     * Check if there is any connectivity
     * @param context
     * @return
     */
    public static boolean isConnected(Context context){
        
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected());
    }
    
    /**
     * Check if there is internet access
     * @param context
     * @return
     */ 
    public static boolean hasInternetAccess(Context c){
        TelephonyManager tm = (TelephonyManager) c.getSystemService(Context.TELEPHONY_SERVICE);
        if(isConnected(c) && tm.getDataState() == TelephonyManager.DATA_CONNECTED)
           return true;
        else
            return false;
    }
 
    /**
     * Check if there is fast connectivity
     * @param context
     * @return
     */
    public static boolean isConnectedFast(Context context){
        
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype()));
    }
    
    /**
     * Check if the connection is fast
     * @param type
     * @param subType
     * @return
     */
    public static boolean isConnectionFast(int type, int subType){
        
        if (type == ConnectivityManager.TYPE_WIFI 
          ||type == ConnectivityManager.TYPE_ETHERNET 
          ||type == ConnectivityManager.TYPE_WIMAX){
            return true;
        }else if(type == ConnectivityManager.TYPE_MOBILE){
            switch(subType){
            case TelephonyManager.NETWORK_TYPE_1xRTT:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_CDMA:
                return false; // ~ 14-64 kbps
            case TelephonyManager.NETWORK_TYPE_EDGE:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_GPRS:
                return false; // ~ 100 kbps
            case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                return false; // ~25 kbps
            case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                return false;
            default:
                return true;
            }
        }else{
            return false;
        }
    }   
}
Ответ: Гугл помог найти описанное решение.

А вот его правильность мне бы хотелось подтвердить, чтобы предупредить возможные непредвиденные ситуации в работе алгоритма.

Допустим, что я приняла верные решения.

Хотя мне хотелось бы услышать от кого-нибудь какую-либо критику или подтверждение используемых подходов.

Но вот один вопрос остаётся у меня не разрешённым.

Я обнаружила, что по какой-то причине метод hasInternetAccess() возвращает false, когда на устройстве есть нормальный доступ к сети интернет, и я могу нормально через браузер заходить на любые сайты.

В чём может быть загвоздка в реализации этого простого метода?


Почему (tm.getDataState() == TelephonyManager.DATA_CONNECTED) возвращает false, когда на устройстве ЕСТЬ интернет?
Вопрос: Помогите скомпилировать, не соответствие типов

Язык PAWN
Не компилируется строка menu_additem(subBanMenu, name, itemMenu, 0), в функции функция subBanMenu, пишет не соответствие типов, как исправить?
Код

#include <amxmodx>
public plugin_init() {
   register_plugin("bans_menu", "1.0", "EbGiK")
   register_clcmd("amx_banmenuu", "Show_Menu")
}


public Show_Menu(id){

   new bans_menu = menu_create("\rГлавное меню", "processing_menu")
   menu_additem(bans_menu, "\rБ\yан \rМ\yеню", "1", 0)
   
 
   menu_setprop(bans_menu, MPROP_EXITNAME, "\rВ\yыход")                           //заменить Exit на Выход
   
   
    menu_display(id, bans_menu, 0)                                             // Отображение меню игроку

}


public subBanMenu(id,&name,&itemMenu){
   new subBanMenu = menu_create("Выберите игрока", "processing_subBanMenu")
   menu_additem(subBanMenu, name, itemMenu, 0)
   
   menu_setprop(subBanMenu, MPROP_EXITNAME, "\rВ\yыход")                           //заменить Exit на Выход
    menu_display(id, subBanMenu, 0)                                             // Отображение меню игроку

}




public processing_menu(id, bans_menu, item){
   new players[32],pCount,name[128]
   new sData[6], sName[128], iAccess, iCallback
   new itemMenu[3]
   menu_item_getinfo(bans_menu, item, iAccess, sData, charsmax(sData), sName, charsmax(sName), iCallback)
   new ikey = str_to_num(sData)
   switch(ikey){
      case 1:{
         get_players(players, pCount,"h")
         for(new i;i<pCount;i++){
            get_user_name(players[i],name,charsmax(name))
            num_to_str(i+1,itemMenu,charsmax(itemMenu))
            subBanMenu(id,name,itemMenu)                                                //под меню
         }
         return PLUGIN_HANDLED
      }      
      case 9:{
         menu_destroy(bans_menu)
            return PLUGIN_HANDLED
      }      
   }
   

}


Это сообщение отредактировал(а) GQU - 11.10.2015, 10:18
Ответ:
Язык PAWN
Не компилируется строка menu_additem(subBanMenu, name, itemMenu, 0), в функции функция subBanMenu, пишет не соответствие типов, как исправить?
Код

#include <amxmodx>
public plugin_init() {
   register_plugin("bans_menu", "1.0", "EbGiK")
   register_clcmd("amx_banmenuu", "Show_Menu")
}


public Show_Menu(id){

   new bans_menu = menu_create("\rГлавное меню", "processing_menu")
   menu_additem(bans_menu, "\rБ\yан \rМ\yеню", "1", 0)
   
 
   menu_setprop(bans_menu, MPROP_EXITNAME, "\rВ\yыход")                           //заменить Exit на Выход
   
   
    menu_display(id, bans_menu, 0)                                             // Отображение меню игроку

}


public subBanMenu(id,&name,&itemMenu){
   new subBanMenu = menu_create("Выберите игрока", "processing_subBanMenu")
   menu_additem(subBanMenu, name, itemMenu, 0)
   
   menu_setprop(subBanMenu, MPROP_EXITNAME, "\rВ\yыход")                           //заменить Exit на Выход
    menu_display(id, subBanMenu, 0)                                             // Отображение меню игроку

}




public processing_menu(id, bans_menu, item){
   new players[32],pCount,name[128]
   new sData[6], sName[128], iAccess, iCallback
   new itemMenu[3]
   menu_item_getinfo(bans_menu, item, iAccess, sData, charsmax(sData), sName, charsmax(sName), iCallback)
   new ikey = str_to_num(sData)
   switch(ikey){
      case 1:{
         get_players(players, pCount,"h")
         for(new i;i<pCount;i++){
            get_user_name(players[i],name,charsmax(name))
            num_to_str(i+1,itemMenu,charsmax(itemMenu))
            subBanMenu(id,name,itemMenu)                                                //под меню
         }
         return PLUGIN_HANDLED
      }      
      case 9:{
         menu_destroy(bans_menu)
            return PLUGIN_HANDLED
      }      
   }
   

}


Это сообщение отредактировал(а) GQU - 11.10.2015, 10:18
Вопрос: Проверка покупки

Всем привет, не получается сделать проверку на покупку.
Вот такой код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 mHelper.enableDebugLogging(true);
 
        mHelper.startSetup(new
                                   IabHelper.OnIabSetupFinishedListener() {
                                       public void onIabSetupFinished(IabResult result)
                                       {
                                           if (!result.isSuccess()) {
                                               Log.e("TAG", "In-app Billing setup failed: " +
                                                       result);
                                           } else {
                                               Log.e("TAG", "In-app Billing is set up OK");
                                               mHelper.queryInventoryAsync(mGotInventoryListener);
                                           }
                                       }
Приходит null,
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            //  Log.e("PAY", "Query inventory finished =." +inventory.getPurchase(ReferenceUrl.OBJECT));
 
 
            // Have we been disposed of in the meantime? If so, quit.
 
            if (result.isFailure()) {
                Log.e("PAY", "Failed to query inventory: " + result);
                return;
            }
            Purchase purchase = inventory.getPurchase(ReferenceUrl.OBJECT_BUY);
            Log.e("PAY", "Query inventory finished =." +inventory.getPurchase(ReferenceUrl.OBJECT));
            Purchase com = inventory.getPurchase(ReferenceUrl.COMICS_BUY);
            mSettings = getSharedPreferences("BUY", Context.MODE_PRIVATE); 
            SharedPreferences.Editor ed = mSettings.edit();
 
 
            if (purchase != null) {
                //purchased
                Log.e("LOG","log = " + purchase.toString());
                ed.putBoolean("objectBuy", true);
            }
 
 
        }
    };
Покупку совершаю вот так

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
   mHelper.launchPurchaseFlow(MainActivity.this, ReferenceUrl.OBJECT, 10001,
                            mPurchaseFinishedListener, "Купи!");
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
            = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result,
                                          Purchase purchase)
        {
           // Log.e("TAG","msg = "+ purchase.getSku());
            if (result.isFailure()) {
      
                // Handle error
                return;
            }
            else if (purchase.getSku().equals(ReferenceUrl.OBJECT)) {
                consumeItem();
             }
             
     
        }
    };
  public void consumeItem() {
        mHelper.queryInventoryAsync(mReceivedInventoryListener);
    }
 
    IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
            = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(IabResult result,
                                             Inventory inventory) {
 
            if (result.isFailure()) {
                // Handle failure
                Log.e("TAG","sw1 = "+ switcherBuy);
            } else {
             
                        mHelper.consumeAsync(inventory.getPurchase(ReferenceUrl.OBJECT),
                                mConsumeFinishedListener);
                
 
            }
        }
    };
    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
            new IabHelper.OnConsumeFinishedListener() {
                public void onConsumeFinished(Purchase purchase,
                                              IabResult result) {
 
                    if (result.isSuccess()) {
                        SharedPreferences.Editor ed = mSettings.edit();
                        mSettings = getSharedPreferences("BUY", Context.MODE_PRIVATE);
                 
                                ed.putBoolean("objectBuy", true);
                        ed.commit();
 
                      
                    } else {
                       Log.e("TAG","sw2 = "+ switcherBuy);
                        // handle error
                    }
                }
            };
Оплата проходит, локально все записываю, но первая проверка на покупку не срабатывает, это потому что в бета тесте??? или я чет не так делаю? Подскажите!
Ответ: TonyBicbaev, не знаю почему но у меня метод getPurchases описан так
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    /**
     * Returns the current SKUs owned by the user of the type and package name specified along with
     * purchase information and a signature of the data to be validated.
     * This will return all SKUs that have been purchased in V3 and managed items purchased using
     * V1 and V2 that have not been consumed.
     * @param apiVersion billing API version that the app is using
     * @param packageName package name of the calling app
     * @param type the type of the in-app items being requested
     *        ("inapp" for one-time purchases and "subs" for subscription).
     * @param continuationToken to be set as null for the first call, if the number of owned
     *        skus are too many, a continuationToken is returned in the response bundle.
     *        This method can be called again with the continuation token to get the next set of
     *        owned skus.
     * @return Bundle containing the following key-value pairs
     *         "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
     *              failure as listed above.
     *         "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
     *         "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
     *         "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
     *                                      of the purchase information
     *         "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
     *                                      next set of in-app purchases. Only set if the
     *                                      user has more owned skus than the current list.
     */
    Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken);
а вызов выглядит например так
Java
1
products = mService.getPurchases(3, packageName, "inapp", continuationToken);
Вопрос: Google maps метод поиска фрагмента карт на разметке для разных версий андроид

Столкнулся с такой проблемой.
в андройде 6 работает один метод поиска фрагмента карт на разметке а в 5 и ранее - другой.

//api 21+
mapFragment = (MapFragment) getChildFragmentManager().findFragmentById(R.id.container_map);
//api20-
//mapFragment = (MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.container_map);

Соответственно метод не в свое версии андройда ничго не находит и выдает null со всеми вытекающими...
как быть? каким методом искать фрагмент карт?
Ответ: Mikalai, а это норма или я что то не так понял? просто где ни смотрел примеры работы с картами - что то не припоминаю подобной проверки.
Вопрос: Проверка на достижение локации на карте

Хотелось бы динамически получать координаты и выводить их в виде тоста.
Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_navigation);
        setUpMapIfNeeded();
        new GpsTask().execute();
    }
    public class GpsTask extends AsyncTask<String, Void, String> {
 
        @Override
        protected String doInBackground(String... params) {
            while(true){
                GPSTracker gps = new GPSTracker(getBaseContext());
                LatLng location = new LatLng(gps.getLatitude(), gps.getLongitude());
                Toast.makeText(getBaseContext(), location.toString(), Toast.LENGTH_LONG).show();
            return "";}
        }
    }
Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
public class GPSTracker extends Service implements LocationListener {
 
    private final Context mContext;
    boolean isGPSEnabled = false;
    boolean isNetworkEnabled = false;
    boolean canGetLocation = false;
 
    Location location;
    double latitude;
    double longitude;
 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;
    protected LocationManager locationManager;
 
    public GPSTracker(Context context) {
        this.mContext = context;
        getLocation();
    }
 
    public Location getLocation() {
 
        try {
            locationManager = (LocationManager) mContext
                    .getSystemService(LOCATION_SERVICE);
 
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);
 
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
 
            if (!isGPSEnabled && !isNetworkEnabled) {
            } else {
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return location;
    }
 
    public void stopUsingGPS(){
        if(locationManager != null){
            locationManager.removeUpdates(GPSTracker.this);
        }
    }
 
    public double getLatitude(){
        if(location != null){
            latitude = location.getLatitude();
        }
        return latitude;
    }
 
    public double getLongitude(){
        if(location != null){
            longitude = location.getLongitude();
        }
        return longitude;
    }
 
    public boolean canGetLocation() {
        return this.canGetLocation;
    }
 
    @Override
    public void onLocationChanged(Location location) {
    }
 
    @Override
    public void onProviderDisabled(String provider) {
    }
 
    @Override
    public void onProviderEnabled(String provider) {
    }
 
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
 
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
 
}
Приложение крэшится. Посмотреть где крэшится не могу. В чём может быть дело?
Ответ: sergey_viper, мне кажется, что у Вас в корне неверная архитектура. У Вас же есть onLocationChanged метод в сервисе. Из него надо пробрасывать через какой-нибудь observer-observble данные
Вопрос: Создание класса и вызов его методов

Код:
Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class DIYliq extends AppCompatActivity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
//...
int GlobalA;
//...
@Override
public void onClick(View v) {
    switch(v.getId()) {
        case R.id.EditText:
        int A = Integer.parseInt(EditText.getText().toString());        
        int N = //Some calculations with int A...
        if (N>0){GlobalA=1}else{GlobalA=0}
        break;
            }
@Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
 
        switch(seekBar.getId()) {
        case R.id.SeekBar:
        EditText.setText(String.valueOf(SeekBar.getProgress()));
        break;
            }
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
        switch(seekBar.getId()) {
        case R.id.SeekBase:
        int A = Integer.parseInt(EditText.getText().toString());        
        int N = //Some calculations with int A...
        if (N>0){GlobalA=1}else{GlobalA=0}
        break;
            }
В коде есть идентичные строки, в которых выполняются расчёты:


Насколько я понимаю, необходимо создать класс, в котором будут прописаны математические действия, а из методов onClick и onStopTrackingTouch уже вызывать метод вышеупомянутого класса.

Так как во всём коде будет много подобных повторений с разными расчётами, нужно создать класс, в котором будут несколько методов (для каждого из повторений). Верно?

То есть, как-то так (схематически):

Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
class Calculations {
    void method_one(SeekBar seekBar, EditText editText){ //body of method 
    }
    void method_two(SeekBar seekBar, EditText editText){ //body of method 
    }
}
Вопрос, собственно, в том, как правильно написать сам класс (и куда его впихнуть в коде, он должен быть внутри класса public class DIYliq, или за его пределами?) и как потом использовать его методы в коде?
Ответ: Ничего не вышло, подскажите, пожалуйста ошибку.
Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Calculations.java:
package com.e_cigcalculations.e_cigliq;
 
public class Calculations {
        int getMaxStrength(int a, int b){
        int c = a + b;
            return c;
        }
}
 
Фрагмент из MainActivity.java:
 
//Objects
    Calculations calculations = new Calculations();
 
    //Globals
    int OutStrengthMax, OutStrengthMin, LowNic, HighNik, a, b;
 
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.Liq1et:
                a = Integer.parseInt(Liq1et.getText().toString());
                Liq2et.requestFocus();
                break;
            case R.id.Liq2et:
                b = Integer.parseInt(Liq2et.getText().toString());
                Liq2et.requestFocus();
                int sum;
                sum = Integer.parseInt(String.valueOf(calculations.getMaxStrength(a, b)));
                OutStrengthMax = sum;
                LiqOutStrengthet.setText(OutStrengthMax);
                break;
            case R.id.LiqOutStrengthet:
                int strength = Integer.parseInt(LiqOutStrengthet.getText().toString());
                SeekStrengthBar.setProgress(strength);
                LiqVolumeet.requestFocus();
                break;
        }
 
    }
При клике на Liq2et крашится.
Вопрос: Что вернёт метод простого класса

доброго времени суток.

Имеем простой класс.

Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.util.Patterns;
import java.util.regex.Pattern;
 
public class Android_info extends Activity{
 
    static String mail="lillo";
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        Pattern emailPattern = Patterns.EMAIL_ADDRESS;
        Account[] accounts = AccountManager.get(this).getAccounts();
        for (Account account : accounts) {
            if (emailPattern.matcher(account.name).matches()) {
                mail = account.name;
            }
        }
 
    }
 
    public static String return_mail(){
        return mail;                        // должен вернуться gmail аккаунта
    }
 
 
}
Подскажите пожалуйста что вернет метод return_mail ?
Ответ: на данный момент добавлено в манифест:

Код XML
1
2
3
4
5
6
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.USE_CREDENTIALS"/>
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.INTERNET"/>
то же самое... возвращает lillo

а можно все как-то вынести из метода onCreate в метод return_mail?

я так догадываюсь, что JNI технология не вызывает метод onCreate, поскольку явно вызывается только метод return_mail.
Вопрос: Вызов java метода из native

Привет, чтот не пойму зачем у меня ошибка происходит...

Значит что хочу и что происходит.
Есть активити с TextView и кнопкой.
В TextView выводится текст из C++ функции stringFromJNI, всё выводит, всё работает.
По кнопке я вызываю метод из С++ RunMyCode в котором хочу найти java метод (helloWorld) и его вызвать.
В общем нахожу класс, метод, перед вызовом кидаю лог, лог приходит а при выхове получаю ошибку

system_process E/InputDispatcher: channel '4a9d792... .test.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!

вот java

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }
 
    static {
        System.loadLibrary("native-lib");
    }
   
    public native String stringFromJNI();
    public native void RunMyCode();//этот метод вызовит из натив helloWorld
 
 
    public void helloWorld(boolean b){//ЭТОТ МЕТОД ХОЧУ ВЫЗВАТЬ
        Log.d("LOG","helloWorld: " + b);//ТУТ НЕ СРАБОТАЕТ
    }
 
    public void RunCode(View v){//нажатие на кнопку, которое вызывает native код
        Log.d("LOG","вызов native по кнопке");
        RunMyCode();//native
    }
}
Вот native

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <jni.h>
#include <string>
#include <android/log.h>
 
// Android log function wrappers
static const char* kTAG = "LOG";
#define LOGI(...) \
  ((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__))
#define LOGW(...) \
  ((void)__android_log_print(ANDROID_LOG_WARN, kTAG, __VA_ARGS__))
#define LOGE(...) \
((void)__android_log_print(ANDROID_LOG_ERROR, kTAG, __VA_ARGS__))
 
extern "C" {
    JNIEXPORT jstring JNICALL
    Java_ru_himik_nightscream_test_MainActivity_stringFromJNI(JNIEnv *env, jobject mainClass) {
        jstring hello = (jstring) "Это работает";
        return env->NewStringUTF((const char *) hello);
    }
 
    JNIEXPORT void JNICALL
    Java_ru_himik_nightscream_test_MainActivity_RunMyCode(JNIEnv *env, jobject mainClass) {
        jclass mainActivity = env->GetObjectClass(mainClass);
        jmethodID sendTimeID = env->GetMethodID(mainActivity, "helloWorld", "(Z)V");
        LOGI("sendTimeID: %d", sendTimeID);//выводит != 0, значит метод существует
        env->CallVoidMethod(mainActivity, sendTimeID, (jboolean) false);
    }
}
Пересмотрел пару десятков примеров, всё фигня, не робит и всё.
Да и в основном примеры старые, где надо было использовать Android.mk, сейчас гугл говорит надо CMake использовать в новых проектах, сам гугл только как месяц обновил примеры, но там куча не нужного и еще куча багов.
Ответ:
Сообщение от _Night_Scream_
я хочу спрятать вызов некоторых методов класса через native уровень
эти вызовы из native будут работать в том же потоке и фактически разницы не будет для приложения откуда я вызвал этот метод (helloWorld) из native или из java?
При переходе через границу JNI поток не меняется.
Если в методах нет работы с другим потоком, то синхронизация не нужна.