make simple code but app has stopping work in kotlin - java

l am try to learn kotlin language , and the first app to me is take data fro json array . but the problem is when start to debug app l got FATAL EXCEPTION: main and app has stopping working . In my Android App, I desgin the following json data construction
my code is :
package com.example.ali.test
import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val url = "https://mysafeinfo.com/api/data?list=presidents&format=json"
Download().execute(url)
}
// full class for json api
inner class Download : AsyncTask<String,String,String>(){
override fun onPreExecute() {
}
// for build connection
override fun doInBackground(vararg p0: String?): String{
try {
val url = URL(p0[0])
val urlConnect = url.openConnection() as HttpURLConnection
urlConnect.connectTimeout = 700
val inputStream = urlConnect.inputStream
val dataJsonAsStr = covertStreamToString(urlConnect.inputStream)
publishProgress(dataJsonAsStr)
} catch (e: Exception){
}
return ""
}
// for get items from json api
override fun onProgressUpdate(vararg values: String?) {
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
}
}
fun handleJson (jsonString: String?){
val jsonArray = JSONArray(jsonString)
val list = ArrayList<FlightShdu>()
var x = 0
while (x < jsonArray.length()){
val jsonObject = jsonArray.getJSONObject(x)
list.add(FlightShdu(
jsonObject.getInt("id"),
jsonObject.getString("nm")
))
x++
}
val adapter = ListAdapte(this#MainActivity,list)
flightShdu_list.adapter = adapter
}
// for connection api
fun covertStreamToString (inputStream: InputStream): String {
val bufferReader = BufferedReader(InputStreamReader(inputStream))
var line:String
var allString:String=""
try {
do{
line=bufferReader.readLine()
if (line!=null)
allString+=line
}while (line!=null)
bufferReader.close()
}catch (ex:java.lang.Exception){}
return allString;
}
}
error in console :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ali.test, PID: 24738
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 
Caused by: org.json.JSONException: End of input at character 0 of
at org.json.JSONTokener.syntaxError(JSONTokener.java:449)
at org.json.JSONTokener.nextValue(JSONTokener.java:97)
at org.json.JSONArray.<init>(JSONArray.java:92)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.example.ali.test.MainActivity.handleJson(MainActivity.kt:68)
at com.example.ali.test.MainActivity$Download.onPostExecute(MainActivity.kt:59)
at com.example.ali.test.MainActivity$Download.onPostExecute(MainActivity.kt:27)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 
any one have any idea please ?

Your doInBackground() always returns an empty string, "". This empty string will be passed as the parameter to onPostExecute, which in turns uses this empty string as a parameter to handleJson. When you try to create a JSON array from this empty string it throws an exception at index 0, as it doesn't have any more data and it's not a valid json.
You need to return the result of the network call from doInBackground() instead of an empty string.

**
Use your code like this example below:
**
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val s = tvDisplay.text.toString()
btnOk.setOnClickListener {
Download().execute(s)
}
}
inner class Download : AsyncTask<String, Void, Void>() {
override fun doInBackground(vararg ss: String?): Void? {
validate(ss[0]!!)
return null
}
}
private fun validate(s:String) {
if(s.isNotEmpty()){
runOnUiThread {
Toast.makeText(this, "Working :)", Toast.LENGTH_SHORT).show()
}
}
else{
runOnUiThread {
Toast.makeText(this, "Not Working :(", Toast.LENGTH_SHORT).show()
}
}
}
}

Related

E/GraphResponse: Unsupported get request. Android Studio facebook login

I have problem with Facebook login app. I was fallowing this tutorial . I took every step and on the end i converted MainAcktivity into kotlin file. Application after login in or logout is stopping.
and I'm receiving follow error in Logcat:
2021-05-22 19:23:12.963 9521-9545/com.example.XXX_login E/GraphResponse: {HttpStatus: 400, errorCode: 100, subErrorCode: 33, errorType: GraphMethodException, errorMessage: Unsupported get request. Object with ID '111111111111111' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api}
2021-05-22 19:23:46.065 9521-9521/com.example.XXX_login E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.XXX_login, PID: 9521
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter oldAccessToken
at com.example.XXX_login.MainActivity$accessTokenTracker$1.onCurrentAccessTokenChanged(Unknown Source:2)
at com.facebook.AccessTokenTracker$CurrentAccessTokenBroadcastReceiver.onReceive(AccessTokenTracker.java:110)
at androidx.localbroadcastmanager.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:313)
at androidx.localbroadcastmanager.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:121)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Here is my MainActivity.kt file:
package com.example.XXX_login
import com.facebook.FacebookSdk
import com.facebook.appevents.AppEventsLogger
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.facebook.*
import com.facebook.login.LoginManager
import com.facebook.login.LoginResult
import com.facebook.login.widget.LoginButton
import org.json.JSONException
import com.squareup.picasso.Picasso as Picasso1
//import java.util.*
class MainActivity : AppCompatActivity() {
private var callbackManager: CallbackManager? = null
private lateinit var loginButton: LoginButton
private var imageView: ImageView? = null
private var textView: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loginButton = findViewById(R.id.login_button)
textView = findViewById(R.id.tv_name)
imageView = findViewById(R.id.tv_profilePic)
callbackManager = CallbackManager.Factory.create()
//permisions do logowania
loginButton.setPermissions(
listOf(
"user_gender",
"email",
"user_location",
"user_birthday"
)
)
loginButton.registerCallback(callbackManager, object : FacebookCallback<LoginResult?> {
override fun onSuccess(loginResult: LoginResult?) {
Log.d("Demo", "Zalogowano!")
}
override fun onCancel() {
Log.d("Demo", "Wylogowano")
}
override fun onError(error: FacebookException) {
Log.d("Demo", "Bład logowania:")
}
})
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
callbackManager!!.onActivityResult(requestCode, resultCode, data)
super.onActivityResult(requestCode, resultCode, data)
val graphRequest =
GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { `object`, response ->
//tworzenie pliku JSON z pobieranymi przez Graph danymi
Log.d("Demo", `object`.toString())
try {
val name = `object`.getString("name")
val pic = `object`.getJSONObject("picture").getJSONObject("data").getString("url")
textView!!.text = name
Picasso1.get().load(pic).into(imageView)
} catch (e: JSONException) {
e.printStackTrace()
}
}
val bundle = Bundle()
//informacjie pozyskiwane z facebooka= defaultowe i na podstawie wcześniej wydanych permissions
bundle.putString(
"fields",
"gender, name, first_name, last_name, email, birthday, location, picture"
)
graphRequest.parameters = bundle
graphRequest.executeAsync()
}
//tracker do sprawdzania czy użytkownik jest zalogowany, jestli token sie zmieni to wywowała sie ta metoda
//wylogowywanie sie
var accessTokenTracker: AccessTokenTracker = object : AccessTokenTracker() {
override fun onCurrentAccessTokenChanged(
oldAccessToken: AccessToken,
currentAccessToken: AccessToken
) {
if (currentAccessToken == null) {
LoginManager.getInstance().logOut()
textView!!.text = ""
imageView!!.setImageResource(0)
}
}
}
override fun onDestroy() {
super.onDestroy()
accessTokenTracker.stopTracking()
}
}
I had have read in the internet for answer for this problem but i've could't find something that could work.
This is because in Kotlin you have to specify the variable as nullable if it will be null in any case.
The error is in this function
var accessTokenTracker: AccessTokenTracker = object : AccessTokenTracker() {
override fun onCurrentAccessTokenChanged(
oldAccessToken: AccessToken,
currentAccessToken: AccessToken
) {
if (currentAccessToken == null) {
LoginManager.getInstance().logOut()
textView!!.text = ""
imageView!!.setImageResource(0)
}
}
}
here in the onCurrentAccessTokenChanged() function you are expecting the currentAccessToken to be null, but you have not made currentAccessToken as nullable hence it will fail and crash. Since only nullable elements can get null value assigned after initialisation in Kotlin. Therefore here you can make the variables as nullable and the problem will be solved.
You can make any variable as nullable like this
currentAccessToken : Type? , where the Type can be Int, String or any supported or custom type.
var accessTokenTracker: AccessTokenTracker = object : AccessTokenTracker() {
override fun onCurrentAccessTokenChanged(
oldAccessToken: AccessToken?,
currentAccessToken: AccessToken?
) {
if (currentAccessToken == null) {
LoginManager.getInstance().logOut()
textView!!.text = ""
imageView!!.setImageResource(0)
}
}
}
This will solve your problem.
It is always recommended that you make the variables as Nullable if you think that the variable might accommodate null at any time in the future in any case to avoid such crashes.

Android (Kotlin) Two-Way Databinding with non-string primitive type

I'm trying to do 2-way databinding in Android (Emulating a Pixel 3a running API level 29, with a min API target of 21). I want to use the #={} syntax on an EditText's android:text property.
The documentation seems to say we can use a static converter class to convert to/from primitive (or presumably complex) data types, using an annotation to describe which methods reverse which others. I'm currently working with ints, but will also be working with doubles at least.
The conversion method from an Int to a string works fine. It's called when my fragment's layout is being inflated (though oddly, it's called twice immediately), however the conversion from a string back to an int is never hit with the debugger.
DatabindingConverters.kt
package com.razelon.svcman.database
import android.widget.EditText
import androidx.databinding.InverseMethod
object DatabindingConverters {
#JvmStatic
#InverseMethod("intToString")
fun stringToInt(v: EditText, old: Int, new: String): Int {
return new.toInt()
}
#JvmStatic
fun intToString(v: EditText, old: Int, new: Int): String {
return new.toString()
}
}
Excerpts from fragment_new_order.xml:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.razelon.svcman.orders.FragmentNewOrderViewModel" />
<import type="com.razelon.svcman.database.DatabindingConverters" />
</data>
<ScrollView
android:id="#+id/order_scroller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="48dp">
<EditText
android:id="#+id/edtWorkOrder"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="16dp"
android:ems="6"
android:hint="#string/hint_work_order"
android:importantForAutofill="no"
android:inputType="number"
// The line in question, for XML
android:text="#={DatabindingConverters.intToString(edtWorkOrder, viewModel.orderNo, viewModel.orderNo)}"
app:layout_constraintBaseline_toBaselineOf="#+id/edtAcct"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/edtAcct" />
// Other views
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>
FragmentNewOrderViewModel.kt
package com.razelon.svcman.orders
import android.app.Application
import androidx.databinding.Bindable
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.razelon.svcman.database.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlin.math.max
const val MAX_WORK_CODES = 5
class FragmentNewOrderViewModel(
val database: SvcDao,
app: Application
) : AndroidViewModel(app) {
private val job = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + job)
private val _listWorkCodes = MutableLiveData<List<WorkCode>>(listOf())
private val _listParts = MutableLiveData<List<SvcPart>>(listOf())
private val _eventResetOrder = MutableLiveData<Boolean>(false)
val serviceMen = database.getAllServiceMen()
val listWorkCodes: LiveData<List<WorkCode>>
get() = _listWorkCodes
val listSvcParts: LiveData<List<SvcPart>>
get() = _listParts
val eventResetOrder: LiveData<Boolean>
get() = _eventResetOrder
val orderNo = MutableLiveData<Int>(0)
fun addWorkCode(): Boolean {
if(_listWorkCodes.value!!.size >= MAX_WORK_CODES) {
return false
}
_listWorkCodes.value = List<WorkCode>(_listWorkCodes.value!!.size + 1) {
if (it < (_listWorkCodes.value!!.size)) {
_listWorkCodes.value?.get(it)!!
} else {
WorkCode(0)
}
}
return true
}
fun updateWorkCode(code: WorkCode) {
}
fun deleteWorkCode(pos: Int) {
_listWorkCodes.value = List<WorkCode>(max(_listWorkCodes.value!!.size - 1, 0)) {
if(it >= pos) _listWorkCodes.value!![it + 1] else _listWorkCodes.value!![it]
}
}
fun addNewPart() {
_listParts.value = List<SvcPart>(_listParts.value!!.size + 1) {
if(it < _listParts.value!!.size) {
_listParts.value!![it]
} else {
SvcPart("", 0.0, 1)
}
}
}
fun deletePart(pos: Int) {
_listParts.value = List<SvcPart>(max(_listParts.value!!.size - 1, 0)) {
if(it >= pos) _listParts.value!![it + 1] else _listParts.value!![it]
}
}
fun resetOrder() {
_eventResetOrder.value = true
_listParts.value = listOf()
_listWorkCodes.value = listOf()
}
fun onOrderReset() {
_eventResetOrder.value = false
}
}
I'm at a loss for why it isn't calling the inverse converter marked by the #InverseMethod("intToString") annotation. I've used the object keyword for the class declaration, marked the methods with the needed annotations, imported the type into my layout databind, and have the parameters in the methods matched up as documented. I am brand new to Kotlin and Android development, so I'm sure it could be something I'm overlooking easily, but any insight would be appreciated as to what I'm missing here.
I figured it out, and it's entirely my fault. It's not shown in the post, but in my fragment, I never actually assigned the variable from the layout to my binding, so there was nothing for it to send the value back to.
Setting this fixed it for me, because I forgot it before:
FragmentNewOrder.kt
val app = this.activity!!.application
val ds = SvcDatabase.getInstance(app).DAO
val factory = FragmentNewOrderViewModelFactory(ds, app)
val viewModel =
ViewModelProviders.of(this, factory).get(FragmentNewOrderViewModel::class.java)
// Very important, don't forget to bind your data 🙃
binding.viewModel = viewModel

Does Kotlin supports AIDL?

I have a simple AIDL definition and I want to use in Kotlin code but when it builds shows Unresolved reference error for all variables that uses the interface. but the same AIDL has no problem in Java code. does Kotlin support it? how to solve
here my AIDL in src/main/aidl/
// ServiceInterface.aidl
package com.example.test;
interface ServiceInterface {
void test(String arg1);
}
and activity code is
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.swiftytime.clientappcommunication.R
import com.example.test.ServiceInterface
class MainActivity : AppCompatActivity() {
var mServiceAidl: ServiceInterface? = null
var mIsBound = false
private val mConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
try {
mServiceAidl = ServiceInterface.Stub.asInterface(service)
Log.e("app", "Attached")
} catch (e: RemoteException) {
}
}
override fun onServiceDisconnected(className: ComponentName) {
mServiceAidl = null
Log.e("app", "Disconnected.")
}
}
private fun doBindService() {
val intent = Intent().apply {
component = ComponentName(
"com.example.test", "com.example.test.MyService"
)
}
bindService(
intent,
mConnection, Context.BIND_AUTO_CREATE
)
mIsBound = true
Log.e("app", "Binding.")
}
private fun doUnbindService() {
if (mIsBound) {
unbindService(mConnection)
mIsBound = false
Log.e("app", "Unbinding.")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doBindService()
}
}
this is error
[ERROR] [org.gradle.api.Task] e: /Volumes/Projects/AndroidProject/ClientAppCommunication/app/src/main/java/com/example/test/MainActivity.kt: (16, 23): Unresolved reference: ServiceInterface
After many hours, I found the problem which is buildToolsVersion 29.0.0 generate wrong path for generated java files, I submitted a bug
Just changing to buildToolsVersion 28.0.3 solve the issue.
Update:
Problem Solved and now it works in buildToolsVersion 29.0.1
I'm using AIDL with Kotlin and what I have is interfaces written in Java and all model classes that are used by defined interfaces are written in Kotlin and it is working perfectly.
For example. I have I*Subscriber.aidl with method
void onSomeEventHappened(in AidlEvent event);
and also I have the .aidl file and .kt file for AidlEvent class.
AidlEvent.aidl file
// AidlEvent.aidl
parcelable AidlEvent;
AidlEvent.kt
data class AidlEvent(
val eventType: Int,
val eventMessage: String):
Parcelable {
// add parcelable methods
}
I'm not sure that you will be able to write .aidl interface in Kotlin, haven't managed to do that. It should not be an issue if you need to write few methods in Java, as you don't need to implement them in Java, you will just declare them.

how to use try-resources in kotlin?

I am trying to use kotlin instead of Java, I cannot find a good way to do with try resource:
Java Code like this:
import org.tensorflow.Graph;
import org.tensorflow.Session;
import org.tensorflow.Tensor;
import org.tensorflow.TensorFlow;
public class HelloTensorFlow {
public static void main(String[] args) throws Exception {
try (Graph g = new Graph()) {
final String value = "Hello from " + TensorFlow.version();
// Construct the computation graph with a single operation, a constant
// named "MyConst" with a value "value".
try (Tensor t = Tensor.create(value.getBytes("UTF-8"))) {
// The Java API doesn't yet include convenience functions for adding operations.
g.opBuilder("Const", "MyConst").setAttr("dtype", t.dataType()).setAttr("value", t).build();
}
// Execute the "MyConst" operation in a Session.
try (Session s = new Session(g);
// Generally, there may be multiple output tensors,
// all of them must be closed to prevent resource leaks.
Tensor output = s.runner().fetch("MyConst").run().get(0)) {
System.out.println(new String(output.bytesValue(), "UTF-8"));
}
}
}
}
I do it in kotlin, I have to do this:
fun main(args: Array<String>) {
val g = Graph();
try {
val value = "Hello from ${TensorFlow.version()}"
val t = Tensor.create(value.toByteArray(Charsets.UTF_8))
try {
g.opBuilder("Const", "MyConst").setAttr("dtype", t.dataType()).setAttr("value", t).build()
} finally {
t.close()
}
var sess = Session(g)
try {
val output = sess.runner().fetch("MyConst").run().get(0)
println(String(output.bytesValue(), Charsets.UTF_8))
} finally {
sess?.close()
}
} finally {
g.close()
}
}
I have try to use use like this:
Graph().use {
it -> ....
}
I got error like this:
Error:(16, 20) Kotlin: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
#InlineOnly public inline fun ???.use(block: (???) -> ???): ??? defined in kotlin.io
I just use wrong dependency:
compile "org.jetbrains.kotlin:kotlin-stdlib"
replace it with:
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

NativeScript Fail to connect to camera service

I'am trying to get access native Api to hardware on NativeScript "i don't use no plugins on my code" . when i fire the function startup(0) or startup(1) up to the camera facing chosed i have this errors .
Fail to connect to camera service
import { Injectable} from '#angular/core';
import * as SocketIO from "nativescript-socket.io";
import * as permissions from 'nativescript-permissions';
let CAMERA = () => (android as any).Manifest.permission.CAMERA;
#Injectable()
export class CameraService {
Camera:any; //Camera android.hardware.Camera instatiation
camera:any;
constructor() {
let RECORD_AUDIO = () => (android as any).Manifest.permission.RECORD_AUDIO;
let READ_EXTERNAL_STORAGE = () => (android as any).Manifest.permission.READ_EXTERNAL_STORAGE;
let WRITE_EXTERNAL_STORAGE = () => (android as any).Manifest.permission.WRITE_EXTERNAL_STORAGE;
this.Camera=android.hardware.Camera;
this.camera = android.hardware.Camera;
}
socket = SocketIO.connect('http://localhost:3000');
CamList = [];
//satrt up the camera
startup(cameraID){
try{
// this.releasecamera();
if(!this.hasCameraPermission){ console.log('no permission'); return;}else{console.log('permission granted');}
let cam = this.Camera.open(cameraID);
console.log(1);
cam.startPreview();
cam.takePicture(null, null, new android.hardware.Camera.PictureCallback({
onPictureTaken: async (data, camera) => {
this.releasecamera();
this.sendpicture(data);
}
}));
}catch(ex){
console.log('start up error',ex);
}
}
//send picture
sendpicture(data){
try{
let bitmap = android.graphics.BitmapFactory.decodeByteArray(data,0,data.length);
console.log('hhere');
let outputStream = new java.io.ByteArrayOutputStream();
bitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, 100, outputStream);
let img=[];
img.push({image:true,buffer:outputStream.toByteArray()});
console.log(img);
console.dir(img);
this.socket.emit('img',img);}catch(ex){
console.log('parss prob',ex);
}
}
//liste all cameras avlaible on the device
getcameras(){
// let Camera:any = android.hardware.Camera ;
let numberOfcams = this.Camera.getNumberOfCameras(); //android.hardware.Camera.getNumberOfCameras();
for(let i = 0 ; i<numberOfcams;i++){
let camera = new this.Camera.CameraInfo();
this.Camera.getCameraInfo(i,camera);
if(camera.facing == this.Camera.CameraInfo.CAMERA_FACING_FRONT)
{
//let ca = "{name:'front' , id:"+i+"}";
this.CamList.push({name:'front',id:i});
}else if(camera.facing == this.Camera.CameraInfo.CAMERA_FACING_BACK)
{
// let ca = "{name:'back' , id:"+i+"}";
this.CamList.push({name:'back',id:i});
} else{
this.CamList.push({name:'other',id:i});
}
console.dir(camera);
}
//console.dir(this.CamList);
//this.releasecamera();
return this.CamList ;
}
public hasCameraPermission(): boolean {
return permissions.hasPermission(CAMERA());
}
//release camera
releasecamera(){
if(this.Camera != null ){
this.Camera.stopPreview();
this.Camera.release();
this.Camera = null;
}
}
}
this is the Errors Log .
java.lang.RuntimeException: takePicture failed
JS: android.hardware.Camera.native_takePicture(Native Method)
JS: android.hardware.Camera.takePicture(Camera.java:1484)
JS: android.hardware.Camera.takePicture(Camera.java:1429)
JS: com.tns.Runtime.callJSMethodNative(Native Method)
JS: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
JS: com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
JS: com.tns.Runtime.callJSMethod(Runtime.java:957)
JS: com.tns.Runtime.callJSMethod(Runtime.java:941)
JS: com.tns.Runtime.callJSMethod(Runtime.java:933)
JS: com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__ClickListenerImpl.onClick(Object_frnal_ts_helpers_l58_c38__ClickListenerImpl.java:12)
JS: android.view.View.performClick(View.java:5204)
JS: android.view.View$PerformClick.run(View.java:21052)
JS: android.os.Handler.handleCallback(Handler.java:739)
JS: android.os.Handler.dispatchMessage(Handler.java:95)
JS: android.os.Looper.loop(Looper.java:145)
JS: android.app.ActivityThread.main(ActivityThread.java:5944)
JS: java.lang.reflect.Method.invoke(Native Method)
JS: java.lang.reflect.Method.invoke(Method.java:372)
JS: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1389)
JS: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1184)
I hope someone shows me what i made wrong on my code .
advanced thanks.
due to rare tutorials about how to preview camera using NativeScript
the error is that there is no textureView Implemented in the Html file
public onCreatingView = (args:any)=>{
if(androidApp){
var appContext = androidApp.context ;
this.mtextureview = new android.view.TextureView(androidApp.context);
this.mtextureview.setSurfaceTextureListener(this.msurfaceTextureLisitiner);
args.view = this.mtextureview ;
}if(iosApp){
console.log("running on ios");
}
}
//the method surfaceTextureListiner callback from the interface
public msurfaceTextureLisitiner = new android.view.TextureView.SurfaceTextureListener({
onSurfaceTextureAvailable : (texture,width,height)=>{
console.log('texture avlaible');
this.mcamera = android.hardware.Camera.open(this.cid);
var params:android.hardware.Camera.Parameters = this.mcamera.getParameters();
this.mcamera.setDisplayOrientation(90);
params.set("orientation", "portrait");
this.mcamera.setParameters(params);
this.mtextureview = texture;
try{
this.mcamera.setPreviewTexture(texture);
this.mcamera.startPreview();
}catch(e){
console.log(e);
}
},
onSurfaceTextureSizeChanged : (texture,width,height)=>{
console.log('size changed');
},
onSurfaceTextureDestroyed : (texture)=>{
console.log('surface destroyed');
this.mcamera.stopPreview();
this.mcamera.release();
return true;
},
onSurfaceTextureUpdated : (texture)=>{
console.log("texture updated");
}
});
and the html file
<StackLayout orientattion="vertical">
<Placeholder #surface height="500" *ngIf="init" (creatingView)="onCreatingView($event)" (loaded)="onLoaded(surface)" id="placeholder-view"></Placeholder>
<Button text="changeCamera" (tap)="cameraId()"></Button>
</StackLayout>
i made a little project if anyone is facing same problem can takes an idea from my repository click here to go project page

Categories

Resources