// Note intent, dataType, dataURI all default to "" bool CXBMCApp::StartActivity(const std::string &package, const std::string &intent, const std::string &dataType, const std::string &dataURI) { CJNIIntent newIntent = intent.empty() ? GetPackageManager().getLaunchIntentForPackage(package) : CJNIIntent(intent); if (!newIntent && CJNIBuild::SDK_INT >= 21) newIntent = GetPackageManager().getLeanbackLaunchIntentForPackage(package); if (!newIntent) return false; if (!dataURI.empty()) { CJNIURI jniURI = CJNIURI::parse(dataURI); if (!jniURI) return false; newIntent.setDataAndType(jniURI, dataType); } newIntent.setPackage(package); startActivity(newIntent); if (xbmc_jnienv()->ExceptionCheck()) { CLog::Log(LOGERROR, "CXBMCApp::StartActivity - ExceptionOccurred launching %s", package.c_str()); xbmc_jnienv()->ExceptionClear(); return false; } return true; }
void CXBMCApp::onReceive(CJNIIntent intent) { std::string action = intent.getAction(); android_printf("CXBMCApp::onReceive Got intent. Action: %s", action.c_str()); if (action == "android.intent.action.BATTERY_CHANGED") m_batteryLevel = intent.getIntExtra("level",-1); }
void CXBMCApp::onReceive(CJNIIntent intent) { std::string action = intent.getAction(); android_printf("CXBMCApp::onReceive Got intent. Action: %s", action.c_str()); if (action == "android.intent.action.BATTERY_CHANGED") m_batteryLevel = intent.getIntExtra("level",-1); else if (action == "android.intent.action.DREAMING_STOPPED" || action == "android.intent.action.SCREEN_ON") { if (HasFocus()) g_application.WakeUpScreenSaverAndDPMS(); } else if (action == "android.intent.action.HEADSET_PLUG" || action == "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") { bool newstate; if (action == "android.intent.action.HEADSET_PLUG") newstate = (intent.getIntExtra("state", 0) != 0); else newstate = (intent.getIntExtra("android.bluetooth.profile.extra.STATE", 0) == 2 /* STATE_CONNECTED */); if (newstate != m_headsetPlugged) { m_headsetPlugged = newstate; CAEFactory::DeviceChange(); } } }
void CXBMCApp::onReceive(CJNIIntent intent) { std::string action = intent.getAction(); android_printf("CXBMCApp::onReceive Got intent. Action: %s", action.c_str()); if (action == "android.intent.action.BATTERY_CHANGED") m_batteryLevel = intent.getIntExtra("level",-1); else if (action == "android.intent.action.DREAMING_STOPPED" || action == "android.intent.action.SCREEN_ON") if (HasFocus()) g_application.WakeUpScreenSaverAndDPMS(); }
void CXBMCApp::onReceive(CJNIIntent intent) { std::string action = intent.getAction(); android_printf("CXBMCApp::onReceive Got intent. Action: %s", action.c_str()); if (action == "android.intent.action.BATTERY_CHANGED") m_batteryLevel = intent.getIntExtra("level",-1); else if (action == "android.intent.action.DREAMING_STOPPED" || action == "android.intent.action.SCREEN_ON") { if (HasFocus()) g_application.WakeUpScreenSaverAndDPMS(); } else if (action == "android.intent.action.HEADSET_PLUG" || action == "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") { bool newstate; if (action == "android.intent.action.HEADSET_PLUG") newstate = (intent.getIntExtra("state", 0) != 0); else newstate = (intent.getIntExtra("android.bluetooth.profile.extra.STATE", 0) == 2 /* STATE_CONNECTED */); if (newstate != m_headsetPlugged) { m_headsetPlugged = newstate; CAEFactory::DeviceChange(); } } else if (action == "android.intent.action.MEDIA_BUTTON") { CJNIKeyEvent keyevt = (CJNIKeyEvent)intent.getParcelableExtra(CJNIIntent::EXTRA_KEY_EVENT); int keycode = keyevt.getKeyCode(); bool up = (keyevt.getAction() == CJNIKeyEvent::ACTION_UP); CLog::Log(LOGINFO, "Got MEDIA_BUTTON intent: %d, up:%s", keycode, up ? "true" : "false"); if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_RECORD) CAndroidKey::XBMC_Key(keycode, XBMCK_RECORD, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_EJECT) CAndroidKey::XBMC_Key(keycode, XBMCK_EJECT, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_FAST_FORWARD) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_FASTFORWARD, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_NEXT) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_NEXT_TRACK, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PAUSE) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PLAY_PAUSE, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PLAY) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PLAY_PAUSE, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PLAY_PAUSE) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PLAY_PAUSE, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PREVIOUS) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PREV_TRACK, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_REWIND) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_REWIND, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_STOP) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_STOP, 0, 0, up); } }
void CGUIDialogKeyboardGeneric::OnVoiceRecognition() { #ifdef TARGET_ANDROID CJNIIntent intent = CJNIIntent(CJNIRecognizerIntent::ACTION_RECOGNIZE_SPEECH); intent.putExtra(CJNIRecognizerIntent::EXTRA_LANGUAGE_MODEL, CJNIRecognizerIntent::LANGUAGE_MODEL_FREE_FORM); CJNIIntent result; if (CXBMCApp::WaitForActivityResult(intent, ACTION_RECOGNIZE_SPEECH_REQID, result) == CJNIBase::RESULT_OK) { CJNIArrayList<std::string> guesses = result.getStringArrayListExtra(CJNIRecognizerIntent::EXTRA_RESULTS); if (guesses.size()) SetEditText(guesses.get(0)); } #endif }
void CXBMCApp::run() { int status = 0; SetupEnv(); CJNIIntent startIntent = getIntent(); android_printf("XBMC Started with action: %s\n",startIntent.getAction().c_str()); std::string filenameToPlay = GetFilenameFromIntent(startIntent); if (!filenameToPlay.empty()) { int argc = 2; const char** argv = (const char**) malloc(argc*sizeof(char*)); std::string exe_name("XBMC"); argv[0] = exe_name.c_str(); argv[1] = filenameToPlay.c_str(); CAppParamParser appParamParser; appParamParser.Parse((const char **)argv, argc); free(argv); } android_printf(" => waiting for a window"); // Hack! // TODO: Change EGL startup so that we can start headless, then create the // window once android gives us a surface to play with. while(!m_window) usleep(1000); m_firstrun=false; android_printf(" => running XBMC_Run..."); try { status = XBMC_Run(true); android_printf(" => XBMC_Run finished with %d", status); } catch(...) { android_printf("ERROR: Exception caught on main loop. Exiting"); } // If we are have not been force by Android to exit, notify its finish routine. // This will cause android to run through its teardown events, it calls: // onPause(), onLostFocus(), onDestroyWindow(), onStop(), onDestroy(). ANativeActivity_finish(m_activity); m_exiting=true; }
// Note intent, dataType, dataURI all default to "" bool CXBMCApp::StartActivity(const string &package, const string &intent, const string &dataType, const string &dataURI) { CJNIIntent newIntent = GetPackageManager().getLaunchIntentForPackage(package); if (!newIntent) return false; if (!dataURI.empty()) newIntent.setData(dataURI); if (!intent.empty()) newIntent.setAction(intent); startActivity(newIntent); return true; }
std::string CXBMCApp::GetFilenameFromIntent(const CJNIIntent &intent) { std::string ret; if (!intent) return ret; CJNIURI data = intent.getData(); if (!data) return ret; std::string scheme = data.getScheme(); StringUtils::ToLower(scheme); if (scheme == "content") { std::vector<std::string> filePathColumn; filePathColumn.push_back(CJNIMediaStoreMediaColumns::DATA); CJNICursor cursor = getContentResolver().query(data, filePathColumn, std::string(), std::vector<std::string>(), std::string()); if(cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndex(filePathColumn[0]); ret = cursor.getString(columnIndex); } cursor.close(); } else if(scheme == "file") ret = data.getPath(); else ret = data.toString(); return ret; }
bool CXBMCApp::ListApplications(vector<androidPackage> *applications) { CJNIList<CJNIApplicationInfo> packageList = GetPackageManager().getInstalledApplications(CJNIPackageManager::GET_ACTIVITIES); int numPackages = packageList.size(); for (int i = 0; i < numPackages; i++) { androidPackage newPackage; newPackage.packageName = packageList.get(i).packageName; newPackage.packageLabel = GetPackageManager().getApplicationLabel(packageList.get(i)).toString(); CJNIIntent intent = GetPackageManager().getLaunchIntentForPackage(newPackage.packageName); if (!intent || !intent.hasCategory("android.intent.category.LAUNCHER")) continue; applications->push_back(newPackage); } return true; }
void CXBMCApp::run() { int status = 0; SetupEnv(); m_initialVolume = GetSystemVolume(); CJNIIntent startIntent = getIntent(); android_printf("XBMC Started with action: %s\n",startIntent.getAction().c_str()); std::string filenameToPlay = GetFilenameFromIntent(startIntent); if (!filenameToPlay.empty()) { int argc = 2; const char** argv = (const char**) malloc(argc*sizeof(char*)); std::string exe_name("XBMC"); argv[0] = exe_name.c_str(); argv[1] = filenameToPlay.c_str(); CAppParamParser appParamParser; appParamParser.Parse((const char **)argv, argc); free(argv); } m_firstrun=false; android_printf(" => running XBMC_Run..."); try { status = XBMC_Run(true); android_printf(" => XBMC_Run finished with %d", status); } catch(...) { android_printf("ERROR: Exception caught on main loop. Exiting"); } // If we are have not been force by Android to exit, notify its finish routine. // This will cause android to run through its teardown events, it calls: // onPause(), onLostFocus(), onDestroyWindow(), onStop(), onDestroy(). ANativeActivity_finish(m_activity); m_exiting=true; }
void CXBMCApp::onNewIntent(CJNIIntent intent) { std::string action = intent.getAction(); if (action == "android.intent.action.VIEW") { std::string playFile = GetFilenameFromIntent(intent); CApplicationMessenger::Get().MediaPlay(playFile); } }
void CXBMCApp::onNewIntent(CJNIIntent intent) { std::string action = intent.getAction(); if (action == "android.intent.action.VIEW") { CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PLAY, 1, 0, static_cast<void*>( new CFileItem(GetFilenameFromIntent(intent)))); } }
void CXBMCApp::onNewIntent(CJNIIntent intent) { std::string action = intent.getAction(); CLog::Log(LOGDEBUG, "CXBMCApp::onNewIntent - Got intent. Action: %s", action.c_str()); std::string targetFile = GetFilenameFromIntent(intent); if (!targetFile.empty() && (action == "android.intent.action.VIEW" || action == "android.intent.action.GET_CONTENT")) { CLog::Log(LOGDEBUG, "-- targetFile: %s", targetFile.c_str()); CURL targeturl(targetFile); std::string value; if (action == "android.intent.action.GET_CONTENT" || (targeturl.GetOption("showinfo", value) && value == "true")) { if (targeturl.IsProtocol("videodb") || (targeturl.IsProtocol("special") && targetFile.find("playlists/video") != std::string::npos) || (targeturl.IsProtocol("special") && targetFile.find("playlists/mixed") != std::string::npos) ) { std::vector<std::string> params; params.push_back(targeturl.Get()); params.push_back("return"); CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTIVATE_WINDOW, WINDOW_VIDEO_NAV, 0, nullptr, "", params); } else if (targeturl.IsProtocol("musicdb") || (targeturl.IsProtocol("special") && targetFile.find("playlists/music") != std::string::npos)) { std::vector<std::string> params; params.push_back(targeturl.Get()); params.push_back("return"); CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTIVATE_WINDOW, WINDOW_MUSIC_NAV, 0, nullptr, "", params); } } else { CFileItem* item = new CFileItem(targetFile, false); if (item->IsVideoDb()) { *(item->GetVideoInfoTag()) = XFILE::CVideoDatabaseFile::GetVideoTag(CURL(item->GetPath())); item->SetPath(item->GetVideoInfoTag()->m_strFileNameAndPath); } CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(item)); } } else if (action == ACTION_XBMC_RESUME) { if (m_playback_state != PLAYBACK_STATE_STOPPED) { if (m_playback_state & PLAYBACK_STATE_VIDEO) RequestVisibleBehind(true); if (!(m_playback_state & PLAYBACK_STATE_PLAYING)) CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_PAUSE))); } } }
CJNIIntent CJNIContext::sendBroadcast(const CJNIIntent &intent) { return call_method<jhobject>(m_context, "sendBroadcast", "(Landroid/content/Intent;)V", intent.get_raw()); }
bool CAndroidNetworkManager::ReceiveNetworkEvent(INetworkEventsCallback *callback, const NetworkEventDataPtr data) { // All actions are event-driven. Android broadcasts connection events in the // form of subscribed events from XBMCApp. See CXBMCApp::onReceive const CJNIIntent intent(*boost::static_pointer_cast<const CJNIIntent>(data)); std::string action = intent.getAction(); CLog::Log(LOGDEBUG, "NetworkManager: Received event: %s",action.c_str()); if (action == CJNIWifiManager::NETWORK_STATE_CHANGED_ACTION) { GetEthernetConnection(); GetWifiAccessPoints(); GetCurrentWifiConnection(); if(m_currentWifi.get() && m_currentWifi->GetState() == NETWORK_CONNECTION_STATE_CONNECTED) { // Call the callback before setting the event so that the connection list // Is updated before leaving the wifi dialog callback->OnConnectionListChange(GetConnections()); m_wifiConnectionEvent.Set(); } else callback->OnConnectionListChange(GetConnections()); } else if(action == CJNIConnectivityManager::CONNECTIVITY_ACTION) { const CJNINetworkInfo newNetworkInfo = intent.getParcelableExtra(CJNIWifiManager::EXTRA_NETWORK_INFO); if (newNetworkInfo) { int type = newNetworkInfo.getType(); std::string typeName = newNetworkInfo.getTypeName(); std::string stateName = newNetworkInfo.getState().name(); if (type == CJNIConnectivityManager::TYPE_ETHERNET) { // This one is simple, just pass the new status along to the connection GetEthernetConnection(); if (m_ethernetConnection.get()) { if(m_ethernetConnection->GetState() == NETWORK_CONNECTION_STATE_CONNECTED) { callback->OnConnectionListChange(GetConnections()); m_ethernetConnectionEvent.Set(); } else callback->OnConnectionListChange(GetConnections()); } } else { GetWifiAccessPoints(); GetCurrentWifiConnection(); callback->OnConnectionListChange(GetConnections()); } } } else if (action == CJNIWifiManager::SCAN_RESULTS_AVAILABLE_ACTION) { GetWifiAccessPoints(); callback->OnConnectionListChange(GetConnections()); } else if (action == CJNIWifiManager::SUPPLICANT_STATE_CHANGED_ACTION) { int error = intent.getIntExtra(CJNIWifiManager::EXTRA_SUPPLICANT_ERROR, 0); if (error == 1) { CLog::Log(LOGDEBUG, "NetworkManager: authentication failed"); GetCurrentWifiConnection(); callback->OnConnectionListChange(GetConnections()); m_currentWifi->OnAuthFailed(); m_wifiConnectionEvent.Set(); } } else if (action == CJNIWifiManager::RSSI_CHANGED_ACTION) { if (!m_currentWifi.get()) GetCurrentWifiConnection(); if (m_currentWifi.get()) { int newRSSI = intent.getIntExtra(CJNIWifiManager::EXTRA_NEW_RSSI, 0); m_currentWifi->SetStrength(newRSSI); callback->OnConnectionChange(m_currentWifi); } } return true; }
void CXBMCApp::onReceive(CJNIIntent intent) { std::string action = intent.getAction(); CLog::Log(LOGDEBUG, "CXBMCApp::onReceive - Got intent. Action: %s", action.c_str()); if (action == "android.intent.action.BATTERY_CHANGED") m_batteryLevel = intent.getIntExtra("level",-1); else if (action == "android.intent.action.DREAMING_STOPPED" || action == "android.intent.action.SCREEN_ON") { if (HasFocus()) g_application.WakeUpScreenSaverAndDPMS(); } else if (action == "android.intent.action.HEADSET_PLUG" || action == "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") { bool newstate = m_headsetPlugged; if (action == "android.intent.action.HEADSET_PLUG") newstate = (intent.getIntExtra("state", 0) != 0); else if (action == "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED") newstate = (intent.getIntExtra("android.bluetooth.profile.extra.STATE", 0) == 2 /* STATE_CONNECTED */); if (newstate != m_headsetPlugged) { m_headsetPlugged = newstate; CServiceBroker::GetActiveAE()->DeviceChange(); } } else if (action == "android.media.action.HDMI_AUDIO_PLUG") { bool newstate; newstate = (intent.getIntExtra("android.media.extra.AUDIO_PLUG_STATE", 0) != 0); if (newstate != m_hdmiPlugged) { CLog::Log(LOGDEBUG, "-- HDMI state: %s", newstate ? "on" : "off"); m_hdmiPlugged = newstate; if (m_hdmiPlugged != m_hdmiReportedState) { if (g_application.IsInitialized()) { CWinSystemBase* winSystem = CServiceBroker::GetWinSystem(); if (winSystem && dynamic_cast<CWinSystemAndroid*>(winSystem)) dynamic_cast<CWinSystemAndroid*>(winSystem)->SetHDMIState(m_hdmiPlugged); m_hdmiReportedState = m_hdmiPlugged; } } } } else if (action == "android.intent.action.SCREEN_OFF") { if (m_playback_state & PLAYBACK_STATE_VIDEO) CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_STOP))); } else if (action == "android.intent.action.MEDIA_BUTTON") { if (m_playback_state == PLAYBACK_STATE_STOPPED) { CLog::Log(LOGINFO, "Ignore MEDIA_BUTTON intent: no media playing"); return; } CJNIKeyEvent keyevt = (CJNIKeyEvent)intent.getParcelableExtra(CJNIIntent::EXTRA_KEY_EVENT); int keycode = keyevt.getKeyCode(); bool up = (keyevt.getAction() == CJNIKeyEvent::ACTION_UP); CLog::Log(LOGINFO, "Got MEDIA_BUTTON intent: %d, up:%s", keycode, up ? "true" : "false"); if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_RECORD) CAndroidKey::XBMC_Key(keycode, XBMCK_RECORD, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_EJECT) CAndroidKey::XBMC_Key(keycode, XBMCK_EJECT, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_FAST_FORWARD) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_FASTFORWARD, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_NEXT) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_NEXT_TRACK, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PAUSE) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PLAY_PAUSE, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PLAY) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PLAY_PAUSE, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PLAY_PAUSE) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PLAY_PAUSE, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_PREVIOUS) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_PREV_TRACK, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_REWIND) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_REWIND, 0, 0, up); else if (keycode == CJNIKeyEvent::KEYCODE_MEDIA_STOP) CAndroidKey::XBMC_Key(keycode, XBMCK_MEDIA_STOP, 0, 0, up); } else if (action == "android.net.conn.CONNECTIVITY_CHANGE") { if (g_application.IsInitialized()) { CNetworkBase& net = CServiceBroker::GetNetwork(); CNetworkAndroid* netdroid = static_cast<CNetworkAndroid*>(&net); netdroid->RetrieveInterfaces(); } } }
void CJNIXBMCMediaSession::updateIntent(const CJNIIntent& intent) { call_method<void>(m_object, "updateIntent", "(Landroid/content/Intent;)V", intent.get_raw()); }
void CJNIContext::startActivity(const CJNIIntent &intent) { call_method<void>(jhobject(m_context), "startActivity", "(Landroid/content/Intent;)V", intent.get_raw()); }
void CJNIContext::sendBroadcast(const CJNIIntent &intent) { call_method<void>(m_context, "sendBroadcast", "(Landroid/content/Intent;)V", intent.get_raw()); }