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

Добрый день, позавчера стал изучать программирование для андроид и столкнулся с не понятной для меня вещью, и хочу сразу разобраться, что тут не так.
Учусь программировать на AndroidStudio.

Создаю тестовую Activity в которой просто находится кнопка Button . План такой, при её нажатии должна вызваться функция create_menu , из другого Класса, не относящегося к данной Activity (находящиеся в отдельном файле).
Так вот, в другом классе, пытаются получить идентификаторы кнопок, и при данной попытке, происходит краш. Null pointer. А в дебаг сообщених, выводится
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.olololo.first/com.olololo.first.Main_First_Activity}: java.lang.NullPointerException
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
////////////////////////////////////////// начало файла Activity
    public static Main_menu menu;  // статическая константа для сформированного меню
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main__first_);
 
        /* создание меню */
        if(create_menu() == false)  return;
        
    }
 
 
    boolean create_menu()
    {
      /* выделяем память для меню */
      menu = new Main_menu();
 
      /* инициализация меню */
      if(menu.init() == false) return false;  // в метод инит код попадает, но далее при вызове findViweById происходит исключение
 
        return true;
    }
///////////////////////////////////////////////////// Конец файла Activity
 
///////////////////////////////////////////////////// Начало файла Main_Menu.java
package Ololo_first;
 
 
public class Main_menu extends AppCompatActivity  implements View.OnClickListener {
 
  public Button start_button;
 
  public boolean init()
  {
    start_button = (Button) findViewById(R.id.button_id); // <------------------------------------------------------- тут происходит краш!!!!! (хотя если это действие делать в активити, то краша нет)
    return false;
  }
}
Manifest
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.olololo.first">
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".Main_Activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            
        </activity>
    </application>
 
</manifest>
Почему получается Ошибка? и как обращаться к своим классам? (я разбиваю программу на свои классы, для упрощения разработки)
Ответ: addgoo, идея такая - Вы хоть и унаследовались от активити но не делали OnCreate и что-то внутри вашего по определению кривого объекта не инициализировано вот и не находит
Вопрос: Вызов 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 поток не меняется.
Если в методах нет работы с другим потоком, то синхронизация не нужна.
Вопрос: Причина вызова onStop()

Здравствуйте!
У меня короткий вопрос. Метод onStop() может вызваться при возвращении в предыдущую активити или при запуске следующей. Подскажите код, который поможет различить эти 2 ситуации, т.е. определить причину вызова onStop().
Ответ: Добрый день!
Сообщение от Paket236
Метод onStop() может вызваться при возвращении в предыдущую активити или при запуске следующей.
И не только. Например, при выключении экрана или сворачивании приложения.
Сообщение от Paket236
Подскажите код, который поможет различить эти 2 ситуации, т.е. определить причину вызова onStop().
Если речь только о двух ситуациях, попробуйте использовать onBackPressed, но сомневаюсь, что подойдёт.
Также можно попробовать startActivityForResult. И вообще, вы же пишете код, значит, должны знать, запускаете новую активность или нет.
Вопрос: Построение графиков различных функций на Android

Ребята..помогите пожалуйста..
Взял себе тему курсовой построение графиков различных функций на android
В прошлой курсовой сделал хороший справочник по физике..думал и с этой темой справлюсь..но курсовую скоро сдавать а я сижу на месте..нашёл в интернете библиотеки для графиков AChartEngine,aFreeChart,Androidplot,GraphView ...в мануалах и примерах этих библиотек нет именно информации как строить графики по функциям..там только по значениям...МОЖЕТ КТО ЗНАЕТ КАК МНЕ ПОСТРОИТЬ ГРАФИК ПО ФУНКЦИИ..МОЖЕТ КАКОЙ-ТО ОБЩИЙ МЕТОД ЕСТЬ..ИЛИ ЧТО-НИБУДЬ ЕЩЁ..ХОТЬ КАКУЮ НАВОДКУ ДАЙТЕ ПОЖАЛУЙСТА..ВЫРУЧИТЕ!!!
Ответ: 1. тебе надо написать парсер строки с функцией во что-то, что сможет по подставленному значению х посчитать y, ну что-то подобное если не ошибаюсь курсе на 2м было у меня, в любом случае задача тривиальная
2. затем на основе интрвала какого-то посчитать массив пар [х,у]
3. используя библиотеку отрисовать эти х и у
4. profit. пьем кофе, гладим котят
Вопрос: Парсер математических функций на java

Всех приветствую. Я хочу написать программу под android на java для работы с математическими функциями,но самое сложное,это написать парсер,который будет пытаться разобрать строку с функцией. При этом,стоит учитывать,что функции могут быть сложными,т.е выражение может иметь несколько скобок. Например,хотелось бы,чтобы парсер мог разобрать примерно такую строку:
y=x^(log(2*atan(x^2)/4*asin(1/2+0.5)))*tan(log(x^2))
При этом хотелось бы,чтобы даже если в строке не написано y=,парсер всё равно разбирал эту строку и возвращал результат вычисления выражения. Очень не хотелось бы писать парсер с нуля,поэтому у меня вопрос к форумчанам,может уже написан готовый парсер математических функций на java или другом языке? Заранее всех благодарю за помощь
Ответ:
Сообщение от КАВ
не только видя подстроку sqrt,но и видя символ √
В чем проблема заменить после парсинга с editText символа √ на sqrt.

Добавлено через 2 минуты
Пример реализации собственной функции:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Function avg = new Function("avg", 4) {
 
    @Override
    public double apply(double... args) {
        double sum = 0;
        for (double arg : args) {
            sum += arg;
        }
        return sum / args.length;
    }
};
double result = new ExpressionBuilder("avg(1,2,3,4)")
        .function(avg)
        .build()
        .evaluate();
 
double expected = 2.5d;
assertEquals(expected, result, 0d);
Вопрос: функция currentTimeMilis

функция currentTimeMilis() возвращает текущее время в миллисекундах какой страны? И она вычисляет время относительно Гринвича(начало отсчета времени)?
Ответ: Ну то есть если я хочу передать в функцию set() AlarmManagera значение времени как параметр его запуска(но это время соответствует, например 18.05.2016 10 часов утра), то как мне вычислить правильно какое количество миллисекунд я должен передать при помощи currentTimeMilis()? Или как можно передать проще в set() это время которое я говорю, чтобы именно тогда запустился alarm?
Вопрос: Артефакт при осуществлении первой попытки обратного вызова для метода onAccessibilityStateChanged

Я использую в своем приложении функциональность, связанную с дополнительными возможностями, представляемыми через использование служб Accessibility Services для операционной системы Андроид.

Созданная для моего приложения служба Accessibility Service первоначально находится в отключенном состоянии.

При запуске своего приложения я проверяю включена ли для моего приложения моя служба Accessibility Service с заданным именем.

Если соответствующая служба не включена, я вызываю Активити с системными настройками Андроида, где пользователь может вручную включить службу Accessibility Service для моего приложения.

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

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

Для этого я использую подход, связанный с использованием обратного вызова метода, который отрабатывает AccessibilityStateChangeListener для созданного мной экземпляра AccessibilityManager.

Ниже будет приведен фрагмент кода из файла MainActivity.java моего приложения, который отвечает за регистрацию обратного вызова метода onAccessibilityStateChanged, проверяющего состояние того, включена ли моя служба Accessibility Service.

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

При последующем нажатии кнопки "Выкл.", а затем "Вкл." для службы Accessibility Service моего приложения вызов метода onAccessibilityStateChanged() начинает корректно отображать состояние включенности моей службы.

1. Скажите, по какой причине метод getEnabledAccessibilityServiceList() при первоначальном отработке события обратного вызова onAccessibilityStateChanged() возвращает некорректные сведения о состоянии включенности моей службы?

Таким образом, чтобы обойти этот артефакт я предполагаю осуществить вызов события обратного вызова метода onAccessibilityStateChanged() ВРУЧНУЮ.

Только я не понимаю, как это можно сделать.

2. Подскажите, пожалуйста, каким образом можно ВРУЧНУЮ (т.е. программным образом) осуществить вызов метода onAccessibilityStateChanged() в самом конце метода onCreate() класса MainActivity моего приложения?

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
package com.comp.serviceaccessibility;
 
import java.util.List;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
 
public class MainActivity extends Activity {
 
      final static String LOG_TAG = "myLogs";
      
      public static String AccessibilityServiceId = "com.comp.serviceaccessibility/.AppAccessibilityService";     
      public static Boolean AcessibilityServiceIsEnabled;     
      public static AccessibilityManager accessibilityManager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        // Add Accessibility Service change listener        
        accessibilityManager = (AccessibilityManager)getSystemService(Context.ACCESSIBILITY_SERVICE);                
        accessibilityManager.addAccessibilityStateChangeListener(new AccessibilityManager.AccessibilityStateChangeListener() 
        {
            @Override
            public void onAccessibilityStateChanged(boolean b) 
            {
                Log.d(LOG_TAG, "onAccessibilityStateChanged");
                AcessibilityServiceIsEnabled = false;
                
                List<AccessibilityServiceInfo> runningServices = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
                                
                for (AccessibilityServiceInfo service : runningServices) 
                {
                    if (AccessibilityServiceId.equals(service.getId())) 
                    {
                        AcessibilityServiceIsEnabled = true;
                    }
                }
                
                Toast.makeText(MainActivity.this, "AcessibilityServiceIsEnabled: "+ AcessibilityServiceIsEnabled.toString(), Toast.LENGTH_SHORT).show();
            }
        });            
        
        // ??? What code should I insert here to call onAccessibilityStateChanged() method MANUALLY?
    }
        
    public void onStartAccessibilitySettingsActivity(View v) 
    {
        Log.d(LOG_TAG, "Turn On Service In Settings");
        
        // Start Accessibility Settings Activity
        Intent intentAccessibilitySettings = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);      
        PackageManager packageManager = getPackageManager(); 
        ComponentName componentName = intentAccessibilitySettings.resolveActivity(packageManager);
        if (componentName != null) {
            try {
                startActivity(intentAccessibilitySettings);    
            } catch (ActivityNotFoundException ex) {
                Log.d(LOG_TAG, "Accessibility Settings Activity is not found");       
            }
        } 
      }    
}
Ответ:

Не по теме:

Сообщение от Паблито
да там на самом деле проще просто прочитать внимательно
прочитать /попробовать /офигеть /напиться /еще раз прочитать /еще раз попробовать /еще раз офигеть и в конце концов просто опытным путем выяснить нечто необъяснимое в комбинации этих казалось бы понятных флажков удовлетворяющее вашим требованиям)

Вопрос: Не корректно отрабатывает метод onReceive()

Имеется BroadcastReceiver, который должен отработать, если будет утеряно подключение к WiFi. Как должно быть:

Приложение работает - WiFi выключили - отрабатывает onReceive() - выполнение процессов прекращается и пользователь об этом уведомляется.

Вместе с реагированием на отключение WiFi метод onReceive() отрабатывает и в таком сценарии: Приложение запустили с выключенным WiFi - включили WiFi - метод onReceive() тоже отрабатывает. Т.е, получается, что WiFi включен, а пользователь видит сообщение об обратном. Как это пофиксить?

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class WifiReceiver extends BroadcastReceiver {
 
 @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
           if (!(ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI)) {
                context.stopService(new Intent(context, NotificationService.class));
                Intent ss = new Intent(context, MainActivity.class);
                ss.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                ss.putExtra("noWifi", "noWifi");
                context.startActivity(ss);
            }
        }
    }
XML
1
2
3
4
5
<receiver android:name=".WifiReceiver" >
            <intent-filter android:priority="100">
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
            </intent-filter>
        </receiver>
Ответ: WIFI_STATE_CHANGED запустит ресивер в обоих случаях. и когда вкл и когда выкл.
вот в стаке есть пример, может вам поможет
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    NetworkInfo mobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
 
    boolean isConnected = wifi != null && wifi.isConnectedOrConnecting() ||
            mobile != null && mobile.isConnectedOrConnecting();
    if (isConnected) {
        Log.d("Network Available ", "YES");
    } else {
        Log.d("Network Available ", "NO");
    }
}}
XML
1
2
3
4
<receiver android:name=".NetworkChangeReceiver" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
Вопрос: Вызов системной JNI-функции из своего приложения

Имеется Highscreen ICE 2, у которого есть второй дисплей на задней панели(OLED).
Хочу получить доступ к рисованию на этом экране.
В результате декомпиляции стоковой прошивки выяснил, что для рисования система использует службу OledService, в которой есть только прототипы нужных функций на java, а сами функции объявлены через JNI на си в system\lib\libandroid_servers.so.
Названия функций:
  • refreshScreen_native
  • setMode_native
  • open_native
  • close_native
Как можно вызвать эти функции из своего приложения?
Ответ: XTracer, вставляйте код в новое сообщение, я перенесу. на будущее имейте ввиду
Вопрос: Как вызывать функцию каждую секунду?

Всем добрый вечер. Помогите, пожалуйста решить следующую задачу.
Есть функция, которая переводит время в устный формат (да в общем не суть), сейчас ее вызов происходит по нажатию кнопки
Java
1
mBadClock.setText(getBadTime());
То есть время, обновляется только по нажатию кнопки. Как сделать обновление раз в секунду? Иначе говоря, как вызывать функцию заново, с интервалом в одну секунду? При этом, желательно, что бы TextView, который принимает значение времени от этой функции, был вроде как обособленной единицей и существовал сам по себе, тихонечко обновлялся и не мешал вызывать другие функции.
Спасибо!
Ответ: Всем спасибо, все понял